¿Alguna vez has querido crear tu propio juego desde cero? Con el proyecto de juego Arduino que te presentamos hoy, podrás hacer una réplica del clásico Flappy Bird adaptado para Arduino. En este artículo te enseñaremos paso a paso cómo llevar a cabo este divertido proyecto y cómo programar tu propia versión del adictivo juego. ¡No te lo pierdas!
En este proyecto Arduino crearemos un genial juego Arduino usando un Arduino y una pantalla táctil TFT, en realidad una réplica del popular juego Flappy Bird para teléfonos inteligentes. Puedes aprender cómo funciona viendo el siguiente vídeo o leyendo el texto escrito a continuación.
descripción general
El juego es bastante simple pero interesante y adictivo. Controlamos al pájaro mediante la pantalla táctil e intentamos esquivar las columnas en movimiento, cuya velocidad aumenta a medida que avanzamos. Además, el juego puede guardar tu puntuación más alta incluso si lo desconectas.[/column]
En>
Código fuente
Dado que el código es un poco más largo y para una mejor comprensión, publicaré el código fuente del programa en secciones con una descripción para cada sección. Y al final de este artículo publicaré el código fuente completo.
Usaremos las bibliotecas UTFT y URTouch de Henning Karlsen. Puede descargar estas bibliotecas desde su sitio web. www.RinkyDinkElectronics.com. Además, usaremos la biblioteca EEPROM para almacenar la puntuación más alta en EEPROM. La EEPROM es una memoria que puede almacenar datos incluso cuando la placa está apagada.
Después de incluir las bibliotecas, necesitamos crear los objetos UTFT y URTouch y definir las variables necesarias para el juego. En la sección de configuración, debemos iniciar la visualización y tocar, leer la puntuación más alta de la EEPROM e iniciar el juego usando la función personalizadainicialGame().
#include <UTFT.h>
#include <URTouch.h>
#include <EEPROM.h>
//==== Creating Objects
UTFT myGLCD(SSD1289,38,39,40,41); //Parameters should be adjusted to your Display/Schield model
URTouch myTouch( 6, 5, 4, 3, 2);
//==== Defining Fonts
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];
extern unsigned int bird01[0x41A]; // Bird Bitmap
int x, y; // Variables for the coordinates where the display has been pressed
// Floppy Bird
int xP = 319;
int yP = 100;
int yB = 50;
int movingRate = 3;
int fallRateInt = 0;
float fallRate = 0;
int score = 0;
int lastSpeedUpScore = 0;
int highestScore;
boolean screenPressed = false;
boolean gameStarted = false;
void setup() {
// Initiate display
myGLCD.InitLCD();
myGLCD.clrScr();
myTouch.InitTouch();
myTouch.setPrecision(PREC_MEDIUM);
highestScore = EEPROM.read(0); // Read the highest score from the EEPROM
initiateGame(); // Initiate the game
}
Code language: Arduino (arduino)
Entonces, usando la función personalizada iniciaGame(), dibujamos el estado inicial del juego y así es como lo hacemos. Primero debemos dejar la pantalla en blanco, luego dibujar el fondo azul, dibujar la sección inferior, agregar el texto y llamar a la función personalizada drawBird() para dibujar el pájaro. Después de eso necesitamos un bucle while que impida que el juego se inicie hasta que toquemos la pantalla. Entonces, cuando estemos en este estado, al presionar la esquina superior derecha podemos restablecer la puntuación más alta a cero. Si pulsamos en cualquier otro lugar de la pantalla salimos del bucle while y entramos en el bucle principal de código que iniciará el juego.
// ===== initiateGame - Custom Function
void initiateGame() {
myGLCD.clrScr();
// Blue background
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(0,0,319,239);
// Ground
myGLCD.setColor(221,216,148);
myGLCD.fillRect(0, 215, 319, 239);
myGLCD.setColor(47,175,68);
myGLCD.fillRect(0, 205, 319, 214);
// Text
myGLCD.setColor(0, 0, 0);
myGLCD.setBackColor(221, 216, 148);
myGLCD.setFont(BigFont);
myGLCD.print("Score:",5,220);
myGLCD.setFont(SmallFont);
myGLCD.print("HowToMechatronics.com", 140, 220);
myGLCD.setColor(0, 0, 0);
myGLCD.setBackColor(114, 198, 206);
myGLCD.print("Highest Score: ",5,5);
myGLCD.printNumI(highestScore, 120, 6);
myGLCD.print(">RESET<",255,5);
myGLCD.drawLine(0,23,319,23);
myGLCD.print("TAP TO START",CENTER,100);
drawBird(yB); // Draws the bird
// Wait until we tap the sreen
while (!gameStarted) {
if (myTouch.dataAvailable()) {
myTouch.read();
x=myTouch.getX();
y=myTouch.getY();
// Reset higest score
if ((x>=250) && (x<=319) &&(y>=0) && (y<=28)) {
highestScore = 0;
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(120, 0, 150, 22);
myGLCD.setColor(0, 0, 0);
myGLCD.printNumI(highestScore, 120, 5);
}
if ((x>=0) && (x<=319) &&(y>=30) && (y<=239)) {
gameStarted = true;
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(0, 0, 319, 32);
}
}
}
// Clears the text "TAP TO START" before the game start
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(85, 100, 235, 116);
}
Code language: Arduino (arduino)
En la sección del bucle principal tenemos la variable xP que se usa para dibujar las columnas, así como la variable yP. Al principio, la variable xP tiene el valor 319 como tamaño de la pantalla y la variable yP tiene el valor 100, es decir, la altura de la primera columna. En cada iteración, el valor de la variable xP se reduce por el valor de la variable MovingRate, que inicialmente tiene un valor de 3 y aumenta a medida que avanza el juego.
// The Main Loop Section
void loop() {
xP=xP-movingRate; // xP - x coordinate of the pilars; range: 319 - (-51)
drawPilars(xP, yP); // Draws the pillars
// yB - y coordinate of the bird which depends on value of the fallingRate variable
yB+=fallRateInt;
fallRate=fallRate+0.4; // Each inetration the fall rate increase so that we can the effect of acceleration/ gravity
fallRateInt= int(fallRate);
// Checks for collision
if(yB>=180 || yB<=0){ // top and bottom
gameOver();
}
if((xP<=85) && (xP>=5) && (yB<=yP-2)){ // upper pillar
gameOver();
}
if((xP<=85) && (xP>=5) && (yB>=yP+60)){ // lower pillar
gameOver();
}
// Draws the bird
drawBird(yB);
// After the pillar has passed through the screen
if (xP<=-51){
xP=319; // Resets xP to 319
yP = rand() % 100+20; // Random number for the pillars height
score++; // Increase score by one
}
//==== Controlling the bird
if (myTouch.dataAvailable()&& !screenPressed) {
fallRate=-6; // Setting the fallRate negative will make the bird jump
screenPressed = true;
}
// Doesn't allow holding the screen / you must tap it
else if ( !myTouch.dataAvailable() && screenPressed){
screenPressed = false;
}
// After each five points, increases the moving rate of the pillars
if ((score - lastSpeedUpScore) == 5) {
lastSpeedUpScore = score;
movingRate++;
}
}
Code language: Arduino (arduino)
Así es como funciona el juego: tenemos columnas de 50 píxeles de ancho que se mueven de derecha a izquierda, y cada columna siguiente tiene una altura aleatoria diferente. Para que se muevan lógicamente, después de cada iteración debemos limpiar la pantalla y volver a dibujar el gráfico con las columnas en su nueva posición. Sin embargo, esto no es posible debido a la baja frecuencia de actualización de la pantalla, lo que provocaría que los gráficos parpadearan. Para poder activar todos los píxeles la pantalla necesita un poco más de tiempo, por lo que tendremos que improvisar y solo redibujar las cosas que se mueven.
Entonces,>
// ===== drawPlillars - Custom Function
void drawPilars(int x, int y) {
if (x>=270){
myGLCD.setColor(0, 200, 20);
myGLCD.fillRect(318, 0, x, y-1);
myGLCD.setColor(0, 0, 0);
myGLCD.drawRect(319, 0, x-1, y);
myGLCD.setColor(0, 200, 20);
myGLCD.fillRect(318, y+81, x, 203);
myGLCD.setColor(0, 0, 0);
myGLCD.drawRect(319, y+80, x-1, 204);
}
else if( x<=268) {
// Draws blue rectangle right of the pillar
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(x+51, 0, x+60, y);
// Draws the pillar
myGLCD.setColor(0, 200, 20);
myGLCD.fillRect(x+49, 1, x+1, y-1);
// Draws the black frame of the pillar
myGLCD.setColor(0, 0, 0);
myGLCD.drawRect(x+50, 0, x, y);
// Draws the blue rectangle left of the pillar
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(x-1, 0, x-3, y);
// The bottom pillar
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(x+51, y+80, x+60, 204);
myGLCD.setColor(0, 200, 20);
myGLCD.fillRect(x+49, y+81, x+1, 203);
myGLCD.setColor(0, 0, 0);
myGLCD.drawRect(x+50, y+80, x, 204);
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(x-1, y+80, x-3, 204);
}
// Draws the score
myGLCD.setColor(0, 0, 0);
myGLCD.setBackColor(221, 216, 148);
myGLCD.setFont(BigFont);
myGLCD.printNumI(score, 100, 220);
}
Code language: Arduino (arduino)
De vuelta en la sección del bucle tenemos la variable yB, que indica la posición y del pájaro y depende de la velocidad de caída, la cual aumenta después de cada iteración y de esta forma conseguimos el efecto de la aceleración o la gravedad. También aquí verificamos si hay colisiones y usamos declaraciones if para restringir al pájaro de modo que si golpea la cima, el suelo o los pilares, se acabó el juego.
El>
//====== drawBird() - Custom Function
void drawBird(int y) {
// Draws the bird - bitmap
myGLCD.drawBitmap (50, y, 35, 30, bird01);
// Draws blue rectangles above and below the bird in order to clear its previus state
myGLCD.setColor(114, 198, 206);
myGLCD.fillRoundRect(50,y,85,y-6);
myGLCD.fillRoundRect(50,y+30,85,y+36);
}
Code language: Arduino (arduino)
De vuelta en el bucle, podemos ver que después de que la columna pasa por la pantalla, la variable xP se restablece a 319, a yP se le asigna un nuevo valor aleatorio de 20 a 100 para la altura de las columnas y la puntuación aumenta en uno. Con la siguiente declaración if controlamos al pájaro. Cuando tocamos la pantalla, configuramos la tasa de caída en negativa, lo que hace que el pájaro salte, y la declaración else if no permite que eso suceda si simplemente mantenemos presionada la pantalla. La última declaración if se relaciona con la dificultad del juego y aumenta la velocidad de movimiento de las columnas después de cada punto fino.
Bien, ahora sólo necesitamos ver cómo funciona la función personalizada gameOver(). Después de un retraso de un segundo, la pantalla se borra y se imprimen la partitura y algo de texto. Si la puntuación es mayor que la puntuación más alta, se escribe en la EEPROM, todas las variables se restablecen a sus valores de posición inicial y al final se llama a la función personalizada «initiateGame()» para reiniciar el juego.
//======== gameOver() - Custom Function
void gameOver() {
delay(1000); // 1 second
// Clears the screen and prints the text
myGLCD.clrScr();
myGLCD.setColor(255, 255, 255);
myGLCD.setBackColor(0, 0, 0);
myGLCD.setFont(BigFont);
myGLCD.print("GAME OVER", CENTER, 40);
myGLCD.print("Score:", 100, 80);
myGLCD.printNumI(score,200, 80);
myGLCD.print("Restarting...", CENTER, 120);
myGLCD.setFont(SevenSegNumFont);
myGLCD.printNumI(2,CENTER, 150);
delay(1000);
myGLCD.printNumI(1,CENTER, 150);
delay(1000);
// Writes the highest score in the EEPROM
if (score > highestScore) {
highestScore = score;
EEPROM.write(0,highestScore);
}
// Resets the variables to start position values
xP=319;
yB=50;
fallRate=0;
score = 0;
lastSpeedUpScore = 0;
movingRate = 3;
gameStarted = false;
// Restart game
initiateGame();
}
Code language: Arduino (arduino)
Eso es todo y espero que la explicación del código haya sido lo suficientemente clara. Si tiene alguna pregunta, no dude en hacerla en la sección de comentarios a continuación.
Aquí está el código completo del juego:
/* Arduino Game Proejct
* Program made by Dejan Nedelkovski,
* www.HowToMechatronics.com
*/
/* This program uses the UTFT and URTouch libraries
* made by Henning Karlsen.
* You can find and download them at:
* www.RinkyDinkElectronics.com
*/
#include <UTFT.h>
#include <URTouch.h>
#include <EEPROM.h>
//==== Creating Objects
UTFT myGLCD(SSD1289,38,39,40,41); //Parameters should be adjusted to your Display/Schield model
URTouch myTouch( 6, 5, 4, 3, 2);
//==== Defining Fonts
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];
extern unsigned int bird01[0x41A]; // Bird Bitmap
int x, y; // Variables for the coordinates where the display has been pressed
// Floppy Bird
int xP = 319;
int yP = 100;
int yB = 50;
int movingRate = 3;
int fallRateInt = 0;
float fallRate = 0;
int score = 0;
int lastSpeedUpScore = 0;
int highestScore;
boolean screenPressed = false;
boolean gameStarted = false;
void setup() {
// Initiate display
myGLCD.InitLCD();
myGLCD.clrScr();
myTouch.InitTouch();
myTouch.setPrecision(PREC_MEDIUM);
highestScore = EEPROM.read(0); // Read the highest score from the EEPROM
initiateGame(); // Initiate the game
}
void loop() {
xP=xP-movingRate; // xP - x coordinate of the pilars; range: 319 - (-51)
drawPilars(xP, yP); // Draws the pillars
// yB - y coordinate of the bird which depends on value of the fallingRate variable
yB+=fallRateInt;
fallRate=fallRate+0.4; // Each inetration the fall rate increase so that we can the effect of acceleration/ gravity
fallRateInt= int(fallRate);
// Checks for collision
if(yB>=180 || yB<=0){ // top and bottom
gameOver();
}
if((xP<=85) && (xP>=5) && (yB<=yP-2)){ // upper pillar
gameOver();
}
if((xP<=85) && (xP>=5) && (yB>=yP+60)){ // lower pillar
gameOver();
}
// Draws the bird
drawBird(yB);
// After the pillar has passed through the screen
if (xP<=-51){
xP=319; // Resets xP to 319
yP = rand() % 100+20; // Random number for the pillars height
score++; // Increase score by one
}
//==== Controlling the bird
if (myTouch.dataAvailable()&& !screenPressed) {
fallRate=-6; // Setting the fallRate negative will make the bird jump
screenPressed = true;
}
// Doesn't allow holding the screen / you must tap it
else if ( !myTouch.dataAvailable() && screenPressed){
screenPressed = false;
}
// After each five points, increases the moving rate of the pillars
if ((score - lastSpeedUpScore) == 5) {
lastSpeedUpScore = score;
movingRate++;
}
}
// ===== initiateGame - Custom Function
void initiateGame() {
myGLCD.clrScr();
// Blue background
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(0,0,319,239);
// Ground
myGLCD.setColor(221,216,148);
myGLCD.fillRect(0, 215, 319, 239);
myGLCD.setColor(47,175,68);
myGLCD.fillRect(0, 205, 319, 214);
// Text
myGLCD.setColor(0, 0, 0);
myGLCD.setBackColor(221, 216, 148);
myGLCD.setFont(BigFont);
myGLCD.print("Score:",5,220);
myGLCD.setFont(SmallFont);
myGLCD.print("HowToMechatronics.com", 140, 220);
myGLCD.setColor(0, 0, 0);
myGLCD.setBackColor(114, 198, 206);
myGLCD.print("Highest Score: ",5,5);
myGLCD.printNumI(highestScore, 120, 6);
myGLCD.print(">RESET<",255,5);
myGLCD.drawLine(0,23,319,23);
myGLCD.print("TAP TO START",CENTER,100);
drawBird(yB); // Draws the bird
// Wait until we tap the sreen
while (!gameStarted) {
if (myTouch.dataAvailable()) {
myTouch.read();
x=myTouch.getX();
y=myTouch.getY();
// Reset higest score
if ((x>=250) && (x<=319) &&(y>=0) && (y<=28)) {
highestScore = 0;
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(120, 0, 150, 22);
myGLCD.setColor(0, 0, 0);
myGLCD.printNumI(highestScore, 120, 5);
}
if ((x>=0) && (x<=319) &&(y>=30) && (y<=239)) {
gameStarted = true;
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(0, 0, 319, 32);
}
}
}
// Clears the text "TAP TO START" before the game start
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(85, 100, 235, 116);
}
// ===== drawPlillars - Custom Function
void drawPilars(int x, int y) {
if (x>=270){
myGLCD.setColor(0, 200, 20);
myGLCD.fillRect(318, 0, x, y-1);
myGLCD.setColor(0, 0, 0);
myGLCD.drawRect(319, 0, x-1, y);
myGLCD.setColor(0, 200, 20);
myGLCD.fillRect(318, y+81, x, 203);
myGLCD.setColor(0, 0, 0);
myGLCD.drawRect(319, y+80, x-1, 204);
}
else if( x<=268) {
// Draws blue rectangle right of the pillar
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(x+51, 0, x+60, y);
// Draws the pillar
myGLCD.setColor(0, 200, 20);
myGLCD.fillRect(x+49, 1, x+1, y-1);
// Draws the black frame of the pillar
myGLCD.setColor(0, 0, 0);
myGLCD.drawRect(x+50, 0, x, y);
// Draws the blue rectangle left of the pillar
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(x-1, 0, x-3, y);
// The bottom pillar
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(x+51, y+80, x+60, 204);
myGLCD.setColor(0, 200, 20);
myGLCD.fillRect(x+49, y+81, x+1, 203);
myGLCD.setColor(0, 0, 0);
myGLCD.drawRect(x+50, y+80, x, 204);
myGLCD.setColor(114, 198, 206);
myGLCD.fillRect(x-1, y+80, x-3, 204);
}
// Draws the score
myGLCD.setColor(0, 0, 0);
myGLCD.setBackColor(221, 216, 148);
myGLCD.setFont(BigFont);
myGLCD.printNumI(score, 100, 220);
}
//====== drawBird() - Custom Function
void drawBird(int y) {
// Draws the bird - bitmap
myGLCD.drawBitmap (50, y, 35, 30, bird01);
// Draws blue rectangles above and below the bird in order to clear its previus state
myGLCD.setColor(114, 198, 206);
myGLCD.fillRoundRect(50,y,85,y-6);
myGLCD.fillRoundRect(50,y+30,85,y+36);
}
//======== gameOver() - Custom Function
void gameOver() {
delay(3000); // 1 second
// Clears the screen and prints the text
myGLCD.clrScr();
myGLCD.setColor(255, 255, 255);
myGLCD.setBackColor(0, 0, 0);
myGLCD.setFont(BigFont);
myGLCD.print("GAME OVER", CENTER, 40);
myGLCD.print("Score:", 100, 80);
myGLCD.printNumI(score,200, 80);
myGLCD.print("Restarting...", CENTER, 120);
myGLCD.setFont(SevenSegNumFont);
myGLCD.printNumI(2,CENTER, 150);
delay(1000);
myGLCD.printNumI(1,CENTER, 150);
delay(1000);
// Writes the highest score in the EEPROM
if (score > highestScore) {
highestScore = score;
EEPROM.write(0,highestScore);
}
// Resets the variables to start position values
xP=319;
yB=50;
fallRate=0;
score = 0;
lastSpeedUpScore = 0;
movingRate = 3;
gameStarted = false;
// Restart game
initiateGame();
}
Code language: Arduino (arduino)
Aquí hay un archivo de descarga con el boceto de Arduino, la imagen del pájaro y el archivo de mapa de bits del pájaro.
Archivos Birduino
Proyecto de juego Arduino – Réplica de Flappy Bird para Arduino
En este proyecto de Arduino, vamos a crear un divertido juego de Arduino, en realidad una réplica del popular juego Flappy Bird para smartphones, utilizando un Arduino y una pantalla táctil TFT. Puedes aprender cómo funciona viendo el siguiente video o leyendo el texto escrito a continuación.
Visión general
El juego es bastante simple pero interesante y adictivo. Usando la pantalla táctil controlamos al pájaro e intentamos evitar las columnas en movimiento, cuya velocidad aumenta a medida que avanzamos. Además, el juego puede almacenar tu puntuación más alta incluso si desconectas la energía.
En el tutorial anterior (Tutorial TFT de Arduino) aprendimos en detalle cómo usar pantallas táctiles TFT con un Arduino y dejamos el ejemplo del juego para ser explicado en este tutorial. Así que ahora, al igual que en el tutorial anterior, explicaremos paso a paso el código detrás de este juego de Arduino.
Código fuente:
El código es un poco extenso y para una mejor comprensión lo publicaré en secciones con una descripción para cada sección. Al final de este artículo, publicaré el código fuente completo.
Utilizaremos las bibliotecas UTFT y URTouch creadas por Henning Karlsen. Puedes descargar estas bibliotecas desde su sitio web, www.RinkyDinkElectronics.com. También utilizaremos la biblioteca EEPROM para almacenar la puntuación más alta en la EEPROM. La EEPROM es una memoria que puede almacenar datos incluso cuando la placa está apagada.
Después de haber incluido las bibliotecas, necesitamos crear los objetos UTFT y URTouch, así como definir las variables necesarias para el juego. En la sección de configuración, necesitamos iniciar la pantalla y el tacto, leer la puntuación más alta de la EEPROM e iniciar el juego utilizando la función personalizada initiateGame().
Cada sección del código se explica detalladamente para que puedas comprender cómo funciona cada paso. Desde cómo se dibujan los pilares en movimiento hasta cómo se controla el movimiento del pájaro y qué sucede cuando el juego termina.
Este proyecto es una excelente manera de aprender cómo utilizar pantallas táctiles TFT con Arduino y cómo crear un juego interactivo. ¡Diviértete y aprende a la vez!
Si tienes alguna pregunta, no dudes en preguntar en la sección de comentarios a continuación. ¡Estoy aquí para ayudarte!
Por favor, descarga el archivo con el código de Arduino, la imagen del pájaro y el archivo de mapa de bits para el pájaro.
Categorías: Proyectos. Completa este artículo con toda la información que tengas sobre el contenido que te ha inspirado. Escribe este artículo en formato HTML para una página web, con etiquetas
¡Qué buena idea! Me encantaría intentar crear mi propio juego de Flappy Bird en Arduino. ¡Gracias por compartir este proyecto!
¡Qué chévere este proyecto! Nunca pensé en poder jugar al Flappy Bird en un Arduino. ¡Definitivamente voy a intentarlo! ¡Gracias por la inspiración!
¡Me parece genial este proyecto! Nunca imaginé que se pudiera replicar el Flappy Bird en un Arduino. Definitivamente voy a intentarlo. ¡Gracias por la idea!