Arduino Retro Gaming con una pantalla OLED

  • Edmund Richardson
  • 0
  • 2434
  • 258
Anuncio

¿Alguna vez te has preguntado cuánto trabajo se necesita para escribir tus propios juegos retro? ¿Qué tan fácil es codificar Pong para el Arduino? Únete a mí mientras te muestro cómo construir una mini consola de juegos retro con Arduino y cómo codificar Pong desde cero. Aquí está el resultado final:

Plan de construcción

Este es un circuito bastante simple. UNA potenciómetro (bote) controlará el juego, y una pantalla OLED será conducida por el Arduino. Esto se producirá en una placa de prueba, sin embargo, es posible que desee hacer de este un circuito permanente e instalarlo en un estuche. Hemos escrito sobre la recreación de Pong Cómo recrear el juego clásico de Pong usando Arduino Cómo recrear el juego clásico de Pong usando Arduino Pong fue el primer videojuego que llegó al mercado masivo. Por primera vez en la historia, el concepto de un "videojuego" se introdujo en la casa de la familia, gracias al Atari 2600 - ... antes, sin embargo, hoy te mostraré cómo escribir el código desde cero y desglosando cada parte.

Que necesitas

Esto es lo que necesitas:

  • 1 x Arduino (cualquier modelo)
  • 1 x 10k potenciómetro
  • 1 x 0.96 "Pantalla OLED I2C
  • 1 x placa de prueba
  • Variedad de cables macho> macho

Cualquier Arduino debería funcionar, así que mira nuestra guía de compra Guía de compra de Arduino: ¿Qué placa deberías obtener? Guía de compra de Arduino: ¿Qué placa debería obtener? Hay tantos tipos diferentes de placas Arduino por ahí, que te perdonarían por estar confundido. ¿Cuál deberías comprar para tu proyecto? ¡Permítanos ayudarlo con esta guía de compra de Arduino! si no está seguro de qué modelo comprar.

Estas pantallas OLED son muy geniales. Por lo general, se pueden comprar en blanco, azul, amarillo o una mezcla de los tres. Existen a todo color, sin embargo, agregan un nivel completamente diferente a la complejidad y el costo de este proyecto..

El circuito

Este es un circuito bastante simple. Si no tienes mucha experiencia con Arduino, mira estos proyectos para principiantes 15 Grandes proyectos Arduino para principiantes 15 Grandes proyectos Arduino para principiantes ¿Estás interesado en proyectos Arduino pero no sabes por dónde empezar? Estos proyectos para principiantes le enseñarán cómo comenzar. primero.

Aquí está:

Mirando el frente de la olla, conecta el pin izquierdo a +5V y el pin correcto para suelo. Conecte el pin del medio a pin analógico 0 (A0).

La pantalla OLED se conecta mediante el protocolo I2C. Conectar VCC y GND al Arduino +5V y suelo. Conectar SCL a análogo cinco (A5) Conectar SDA a analógico 4 (A4) La razón por la que esto está conectado a los pines analógicos es simple; Estos pines contienen los circuitos necesarios para el protocolo I2C. Asegúrese de que estén conectados correctamente y que no estén cruzados. Los pines exactos variarán según el modelo, pero se utilizan A4 y A5 en el Nano y Uno. Consulte la documentación de la biblioteca Wire para su modelo si no está utilizando un Arduino o Nano.

Prueba de olla

Cargue este código de prueba (asegúrese de seleccionar la placa y el puerto correctos del Herramientas > Tablero y Herramientas > Puerto menús):

void setup () // ponga su código de configuración aquí, para ejecutar una vez: Serial.begin (9600); // setup serial void loop () // pon tu código principal aquí, para ejecutarlo repetidamente: Serial.println (analogRead (A0)); // imprime el valor del pot delay (500); 

Ahora abra el monitor en serie (Parte superior derecha > Monitor en serie) y voltea la olla. Debería ver el valor que se muestra en el monitor serie. Totalmente en sentido antihorario debe ser cero, y completamente en sentido horario debe ser 1023:

Ajustarás esto más adelante, pero por ahora está bien. Si no sucede nada o el valor cambia sin que usted haga nada, desconecte y vuelva a verificar el circuito.

Prueba OLED

La pantalla OLED es un poco más compleja de configurar. Primero debe instalar dos bibliotecas para controlar la pantalla. Descargue las bibliotecas Adafruit_SSD1306 y Adafruit-GFX de Github. Copie los archivos en su carpeta de bibliotecas. Esto varía según su sistema operativo:

  • Mac OS: / Usuarios / Nombre de usuario / Documentos / Arduino / bibliotecas
  • Linux: / inicio / Nombre de usuario / Sketchbook
  • Ventanas: / Usuarios / Arduino / bibliotecas

Ahora suba un boceto de prueba. Ir Expediente > Ejemplos > Adafruit SSD1306 > ssd1306_128x64_i2c. Esto debería darle un boceto grande que contiene muchos gráficos:

Si no sucede nada después de la carga, desconecte y verifique sus conexiones. Si los ejemplos no están en los menús, es posible que deba reiniciar su IDE Arduino.

El código

Ahora es el momento del código. Explicaré cada paso, así que salte al final si solo quiere que se ejecute. Esta es una buena cantidad de código, así que si no se siente seguro, consulte estos 10 recursos gratuitos Aprenda a codificar: 10 Recursos en línea gratuitos y fantásticos para perfeccionar sus habilidades Aprenda a codificar: 10 Recursos en línea gratuitos y fantásticos para perfeccionar su Codificación de habilidades. Un tema que muchos evitan. Hay una gran cantidad de recursos y herramientas gratuitos, todos los cuales están disponibles en línea. Seguro que podrías tomar algunos cursos sobre el tema en un lugar cercano ... para aprender a codificar.

Comience por incluir las bibliotecas necesarias:

#include #include #include #include #include 

SPI y CABLE son dos bibliotecas Arduino para manejar la comunicación I2C. Adafruit_GFX y Adafruit_SSD1306 son las bibliotecas que instaló anteriormente.

A continuación, configure la pantalla:

Adafruit_SSD1306 display (4);

Luego configura todas las variables necesarias para ejecutar el juego:

int resolución [2] = 128, 64, bola [2] = 20, (resolución [1] / 2); const int PIXEL_SIZE = 8, WALL_WIDTH = 4, PADDLE_WIDTH = 4, BALL_SIZE = 4, SPEED = 3; int playerScore = 0, aiScore = 0, playerPos = 0, aiPos = 0; char ballDirectionHori = 'R', ballDirectionVerti = 'S'; boolean inProgress = true;

Estos almacenan todos los datos necesarios para ejecutar el juego. Algunos de estos almacenan la ubicación de la pelota, el tamaño de la pantalla, la ubicación del jugador, etc. Observe cómo algunos de estos son const lo que significa que son constantes y nunca cambiarán. Esto permite que el compilador Arduino acelere un poco las cosas.

La resolución de la pantalla y la ubicación de la bola se almacenan en matrices. Las matrices son colecciones de cosas similares, y para la pelota, guarde las coordenadas (X y Y) Acceder a elementos en matrices es fácil (no incluya este código en su archivo):

resolución [1];

Como las matrices comienzan en cero, esto devolverá el segundo elemento en la matriz de resolución (64) Actualizar elementos es aún más fácil (de nuevo, no incluya este código):

bola [1] = 15;

Dentro configuración nula (), configurar la pantalla:

configuración vacía () display.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.display (); 

La primera línea le dice a la biblioteca Adafruit qué dimensiones y protocolo de comunicación está usando su pantalla (en este caso, 128 X 64 y I2C) La segunda línea (display.display ()) le dice a la pantalla que muestre lo que esté almacenado en el búfer (que no es nada).

Crea dos métodos llamados drawBall y eraseBall:

void drawBall (int x, int y) display.drawCircle (x, y, BALL_SIZE, WHITE);  void eraseBall (int x, int y) display.drawCircle (x, y, BALL_SIZE, BLACK); 

Estos toman el X y y coordenadas de la pelota y dibujarla en la pantalla usando el drawCircle Método de las bibliotecas de visualización. Esto usa la constante BALL_SIZE definido anteriormente. Intente cambiar esto y vea qué sucede. Este método drawCircle acepta un color de píxel - NEGRO o BLANCO. Como se trata de una pantalla monocromática (un color), el blanco equivale a un píxel encendido y el negro apaga el píxel.

Ahora crea un método llamado moveAi:

vacío moveAi () eraseAiPaddle (aiPos); if (bola [1]> aiPos) ++ aiPos;  más si (bola [1] < aiPos)  --aiPos;  drawAiPaddle(aiPos); 

Este método maneja mover el Inteligencia artificial o AI jugador. Este es un oponente de computadora bastante simple: si la pelota está por encima de la pala, muévase hacia arriba. Si está debajo de la pala, baje. Bastante simple, pero funciona bien. Se utilizan los símbolos de incremento y decremento (++aiPos y -aiPos) para sumar o restar uno de la posición de ai. Puedes sumar o restar un número mayor para que la IA se mueva más rápido y, por lo tanto, sea más difícil de superar. Así es como lo harías:

aiPos + = 2;

Y:

aiPos - = 2;

los Más igual y Menos igual Los signos son abreviaturas para sumar o restar dos del / al valor actual de aiPos. Aquí hay otra forma de hacer eso:

aiPos = aiPos + 2;

y

aiPos = aiPos - 1;

Observe cómo este método primero borra la paleta y luego la vuelve a dibujar. Esto tiene que hacerse así. Si se dibujara la nueva posición de la pala, habría dos paletas superpuestas en la pantalla.

los drawNet El método utiliza dos bucles para dibujar la red:

void drawNet () for (int i = 0; i < (resolution[1] / WALL_WIDTH); ++i)  drawPixel(((resolution[0] / 2) - 1), i * (WALL_WIDTH) + (WALL_WIDTH * i), WALL_WIDTH);  

Esto usa el WALL_WIDTH variables para establecer su tamaño.

Crear métodos llamados dibujar píxeles y borrarPixels. Al igual que los métodos de bola, la única diferencia entre estos dos es el color de los píxeles:

void drawPixel (int posX, int posY, int dimensiones) for (int x = 0; x < dimensions; ++x)  for (int y = 0; y < dimensions; ++y)  display.drawPixel((posX + x), (posY + y), WHITE);    void erasePixel(int posX, int posY, int dimensions)  for (int x = 0; x < dimensions; ++x)  for (int y = 0; y < dimensions; ++y)  display.drawPixel((posX + x), (posY + y), BLACK);   

De nuevo, ambos métodos usan dos para bucles para dibujar un grupo de píxeles. En lugar de tener que dibujar cada píxel usando las bibliotecas drawPixel método, los bucles dibujan un grupo de píxeles basado en las dimensiones dadas.

los drawScore El método utiliza las características de texto de la biblioteca para escribir el jugador y la puntuación de AI en la pantalla. Estos se almacenan en playerScore y aiScore:

void drawScore () display.setTextSize (2); display.setTextColor (BLANCO); display.setCursor (45, 0); display.println (playerScore); display.setCursor (75, 0); display.println (aiScore); 

Este método también tiene un eraseScore contraparte, que establece los píxeles en negro o apagado.

Los cuatro métodos finales son muy similares. Dibujan y borran el jugador y las paletas de IA:

nulo erasePlayerPaddle (int fila) erasePixel (0, fila - (PADDLE_WIDTH * 2), PADDLE_WIDTH); erasePixel (0, fila - PADDLE_WIDTH, PADDLE_WIDTH); erasePixel (0, fila, PADDLE_WIDTH); erasePixel (0, fila + PADDLE_WIDTH, PADDLE_WIDTH); erasePixel (0, fila + (PADDLE_WIDTH + 2), PADDLE_WIDTH); 

Observe cómo llaman al erasePixel Método crear antes. Estos métodos dibujan y borran la paleta apropiada.

Hay un poco más de lógica en el bucle principal. Aquí está el código completo:

#include #include #include #include Adafruit_SSD1306 display (4); int resolución [2] = 128, 64, bola [2] = 20, (resolución [1] / 2); const int PIXEL_SIZE = 8, WALL_WIDTH = 4, PADDLE_WIDTH = 4, BALL_SIZE = 4, SPEED = 3; int playerScore = 0, aiScore = 0, playerPos = 0, aiPos = 0; char ballDirectionHori = 'R', ballDirectionVerti = 'S'; boolean inProgress = true; configuración vacía () display.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.display ();  void loop () if (aiScore> 9 || playerScore> 9) // comprueba el estado del juego inProgress = false;  if (en progreso) eraseScore (); eraseBall (bola [0], bola [1]); if (ballDirectionVerti == 'U') // mueve la pelota en diagonal hacia arriba ball [1] = ball [1] - SPEED;  if (ballDirectionVerti == 'D') // mueve la pelota hacia abajo diagonalmente ball [1] = ball [1] + SPEED;  if (bola [1] = resolución [1]) // hacer rebotar la bola desde la parte inferior ballDirectionVerti = 'U';  if (ballDirectionHori == 'R') ball [0] = ball [0] + SPEED; // mueve la bola si (bola [0]> = (resolución [0] - 6)) // la bola está en el borde AI de la pantalla si ((aiPos + 12)> = bola [1] && (aiPos - 12) (aiPos + 4)) // desvía la bola hacia abajo ballDirectionVerti = 'D';  más si (bola [1] < (aiPos - 4))  // deflect ball up ballDirectionVerti = 'U';  else  // deflect ball straight ballDirectionVerti = 'S';  // change ball direction ballDirectionHori = 'L';  else  // GOAL! ball[0] = 6; // move ball to other side of screen ballDirectionVerti = 'S'; // reset ball to straight travel ball[1] = resolution[1] / 2; // move ball to middle of screen ++playerScore; // increase player score    if (ballDirectionHori == 'L')  ball[0] = ball[0] - SPEED; // move ball if (ball[0] = ball[1] && (playerPos - 12)  (playerPos + 4))  // deflect ball down ballDirectionVerti = 'D';  else if (ball[1]  playerScore)  display.println("YOU LOSE!");  else if (playerScore > aiScore) display.println ("¡USTED GANA!");  display.display ();  void moveAi () // mueve la paleta AI eraseAiPaddle (aiPos); if (bola [1]> aiPos) ++ aiPos;  más si (bola [1] < aiPos)  --aiPos;  drawAiPaddle(aiPos);  void drawScore()  // draw AI and player scores display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(45, 0); display.println(playerScore); display.setCursor(75, 0); display.println(aiScore);  void eraseScore()  // erase AI and player scores display.setTextSize(2); display.setTextColor(BLACK); display.setCursor(45, 0); display.println(playerScore); display.setCursor(75, 0); display.println(aiScore);  void drawNet()  for (int i = 0; i < (resolution[1] / WALL_WIDTH); ++i)  drawPixel(((resolution[0] / 2) - 1), i * (WALL_WIDTH) + (WALL_WIDTH * i), WALL_WIDTH);   void drawPixel(int posX, int posY, int dimensions)  // draw group of pixels for (int x = 0; x < dimensions; ++x)  for (int y = 0; y < dimensions; ++y)  display.drawPixel((posX + x), (posY + y), WHITE);    void erasePixel(int posX, int posY, int dimensions)  // erase group of pixels for (int x = 0; x < dimensions; ++x)  for (int y = 0; y < dimensions; ++y)  display.drawPixel((posX + x), (posY + y), BLACK);    void erasePlayerPaddle(int row)  erasePixel(0, row - (PADDLE_WIDTH * 2), PADDLE_WIDTH); erasePixel(0, row - PADDLE_WIDTH, PADDLE_WIDTH); erasePixel(0, row, PADDLE_WIDTH); erasePixel(0, row + PADDLE_WIDTH, PADDLE_WIDTH); erasePixel(0, row + (PADDLE_WIDTH + 2), PADDLE_WIDTH);  void drawPlayerPaddle(int row)  drawPixel(0, row - (PADDLE_WIDTH * 2), PADDLE_WIDTH); drawPixel(0, row - PADDLE_WIDTH, PADDLE_WIDTH); drawPixel(0, row, PADDLE_WIDTH); drawPixel(0, row + PADDLE_WIDTH, PADDLE_WIDTH); drawPixel(0, row + (PADDLE_WIDTH + 2), PADDLE_WIDTH);  void drawAiPaddle(int row)  int column = resolution[0] - PADDLE_WIDTH; drawPixel(column, row - (PADDLE_WIDTH * 2), PADDLE_WIDTH); drawPixel(column, row - PADDLE_WIDTH, PADDLE_WIDTH); drawPixel(column, row, PADDLE_WIDTH); drawPixel(column, row + PADDLE_WIDTH, PADDLE_WIDTH); drawPixel(column, row + (PADDLE_WIDTH * 2), PADDLE_WIDTH);  void eraseAiPaddle(int row)  int column = resolution[0] - PADDLE_WIDTH; erasePixel(column, row - (PADDLE_WIDTH * 2), PADDLE_WIDTH); erasePixel(column, row - PADDLE_WIDTH, PADDLE_WIDTH); erasePixel(column, row, PADDLE_WIDTH); erasePixel(column, row + PADDLE_WIDTH, PADDLE_WIDTH); erasePixel(column, row + (PADDLE_WIDTH * 2), PADDLE_WIDTH);  void drawBall(int x, int y)  display.drawCircle(x, y, BALL_SIZE, WHITE);  void eraseBall(int x, int y)  display.drawCircle(x, y, BALL_SIZE, BLACK); 

Esto es con lo que terminas:

Una vez que esté seguro con el código, puede realizar numerosas modificaciones:

  • Agregue un menú para niveles de dificultad (cambie la IA y la velocidad de la pelota).
  • Agregue un movimiento aleatorio a la pelota o IA.
  • Agrega otro bote para dos jugadores.
  • Agregar un botón de pausa.

Ahora eche un vistazo a estos juegos retro de Pi Zero. 5 proyectos de juegos retro con Raspberry Pi Zero 5 proyectos de juegos retro con Raspberry Pi Zero. e inspiradores recién llegados, especialmente en la mente febril de los fanáticos de los juegos retro. .

¿Has codificado Pong usando este código? ¿Qué modificaciones hiciste? Déjame saber en los comentarios a continuación, me encantaría ver algunas fotos!




Nadie ha comentado sobre este artículo todavía.

Sobre tecnología moderna, simple y asequible.
Tu guía en el mundo de la tecnología moderna. Aprenda a usar las tecnologías y los dispositivos que nos rodean todos los días y aprenda a descubrir cosas interesantes en Internet.