Juegos retro arduino con una pantalla oled
Alguna vez se preguntó hasta qué punto el trabajo que se necesita para escribir sus propios juegos retro? ¿Qué tan fácil es Pong para codificar el Arduino? Únete a mí como yo os muestro cómo construir un mini-consola de juegos retro Arduino potencia, y la forma de código Pong desde cero. Aquí está el resultado final:
construir plan
Este es un circuito bastante simple. UN potenciómetro (Pot) controlará el juego, y una pantalla OLED será impulsado por el Arduino. Esto se produce en un circuito, sin embargo es posible que desee hacer de este un circuito permanente e instalarlo en un caso. Hemos escrito acerca recreando Pong antes, sin embargo hoy voy a estar mostrando que la forma de escribir el código desde cero, y romper todas las partes.Cómo recrear el uso de mesa clásico juego de ArduinoCómo recrear el uso de mesa clásico juego de ArduinoPong fue el primer videojuego nunca que llegó al mercado de masas. Por primera vez en la historia, el concepto de una "videojuego" fue llevado a la casa de la familia, gracias a la Atari 2600 -...Lee mas
Que necesitas
Esto es lo que necesita:
- 1 x Arduino (cualquier modelo)
- 1 x 10k Potenciómetro
- 1 x 0,96 "Display OLED I2C
- 1 x Breadboard
- Surtido de sexo masculino gt; cables de conexión macho
Cualquier Arduino debería funcionar, a fin de buscar en nuestra guía de compra Si no está seguro de qué modelo comprar.
Estas pantallas OLED son muy fresco. Por lo general, se pueden adquirir en blanco, azul, amarillo, o una mezcla de los tres. Ellos existen a todo color, sin embargo estos añadir otro nivel de la complejidad y el costo de este proyecto.
El circuito
Este es un circuito bastante simple. Si usted no tiene mucha experiencia con Arduino, echa un vistazo a estos proyectos de iniciación primero.10 Grandes Proyectos Arduino para principiantes10 Grandes Proyectos Arduino para principiantesCompletar un proyecto Arduino le da una sensación de satisfacción como ningún otro. La mayoría de los principiantes no están seguros de por dónde empezar sin embargo, y aun proyectos de principiantes pueden parecer bastante desalentador.Lee mas
Aquí está:
En cuanto a la parte delantera de la olla, conecte la clavija a la izquierda +5V y el pasador derecho de suelo. Conecte el pin central a pin analógico 0 (A0).
La pantalla OLED está conectado mediante el protocolo I2C. Conectar VCC y GND a la Arduino +5V y suelo. Conectar SCL a analógico de cinco (A5). Conectar SDA a analógica 4 (A4). La razón de 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 no cruzado. Los pines exactos variarán según el modelo, pero A4 y A5 se utiliza en el Nano y Uno. Compruebe la documentación de la biblioteca de cables para su modelo si no está utilizando un Arduino o Nano.
Pot Test
Subir este código de prueba (asegúrese de seleccionar el tablero y el puerto correcto de la Herramientas gt; Tablero y Herramientas gt; Puerto menús):
vacío preparar() {// poner su código de configuración aquí, para ejecutar una vez:De serie.empezar(9600)- // configuración en serie}vacío lazo() {// ponga su código principal aquí, para ejecutar repetidamente:De serie.println(analogRead(A0))- // imprimir el valor de la ollaretrasar(500)-}
Ahora abra el monitor de puerto serie (Parte superior derecha gt; serial monitor) Y girar el bote. Usted debe ver el valor que aparece en el monitor de serie. Completamente hacia la izquierda debe ser cero, y completamente a la derecha debería haber 1023:
Va a ajustar esto más adelante, pero por ahora está bien. Si no ocurre nada, o los cambios de valor sin que hagas nada, desconecte y vuelva a comprobar el circuito.
Prueba OLED
Vídeo: Pantalla OLED y Arduino
La pantalla OLED es un poco más complejo de configurar. Es necesario instalar dos bibliotecas para controlar la pantalla por primera vez. Descargar las bibliotecas Adafruit_SSD1306 y Adafruit-GFX de Github. Copiar los archivos en la carpeta de bibliotecas. Esto varía dependiendo de su sistema operativo:
- Mac OS: / Users / nombre de usuario / Documentos / Arduino / bibliotecas
- Linux: / Home / usuario / Sketchbook
- ventanas: / Users / Arduino / bibliotecas
Ahora cargar un esbozo de prueba. Ir Archivo gt; Ejemplos gt; adafruit SSD1306 gt; ssd1306_128x64_i2c. Esto debe darle una gran boceto que contiene una gran cantidad de gráficos:
Vídeo: Tecnología OLED TV vs LED
Si no ocurre nada después de la carga, desconecte y doble comprobar sus conexiones. Si los ejemplos no están en los menús, puede que tenga que reiniciar el IDE Arduino.
El código
Ahora es el momento para el código. Yo estaré explicando cada paso, de modo saltar al final si lo que desea para ponerlo en marcha. Esta es una buena cantidad de código, por lo que si no se siente seguro, echa un vistazo estos 10 recursos libres, y estos 5 grandes recursos aprender a código.Para aprender Código: 10 libre y fantástico Recursos en línea para perfeccionar sus habilidadesPara aprender Código: 10 libre y fantástico Recursos en línea para perfeccionar sus habilidadesCodificación. Un tema que se evita por muchos. Hay una gran cantidad de recursos y herramientas libres, todos los cuales están disponibles en línea. Claro que podría tomar algunos cursos sobre el tema en un cercano ...Lee mas
Para empezar, incluyendo las librerías necesarias:
#incluir #incluir #incluir #incluir
SPI y CABLE son dos bibliotecas de Arduino para el manejo de la comunicación I2C. Adafruit_GFX y Adafruit_SSD1306 son las bibliotecas instaladas previamente.
A continuación, configure la pantalla:
Adafruit_SSD1306 monitor(4)-
Luego de configuración de todas las variables necesarias para ejecutar el juego:
int resolución[2] = {128, 64}, pelota[2] = {20, (resolución[1] / 2)}-const int PIXEL_SIZE = 8, WALL_WIDTH = 4, PADDLE_WIDTH = 4, BALL_SIZE = 4, VELOCIDAD = 3-int playerScore = 0, aiScore = 0, playerpos = 0, aiPos = 0-carbonizarse ballDirectionHori = `R`, ballDirectionVerti = `S`-booleano InProgress = cierto-
Éstas almacenan todos los datos necesarios para ejecutar el juego. Algunos de estos almacenar la ubicación de la pelota, el tamaño de la pantalla, la ubicación del jugador y así sucesivamente. Observe cómo algunos de estos son const lo que significa que son constantes, y nunca va a cambiar. De este modo, el bit de Arduino a acelerar las cosas hasta compilador.
La resolución de la pantalla y la ubicación bola se almacenan en arrays. Las matrices son colecciones de cosas similares, y por el balón, almacenar las coordenadas (x y Y). El acceso a los elementos de las matrices es fácil (no incluya el código en el archivo):
resolución[1]-
Como matrices comienzan en cero, esto devolverá el segundo elemento de la matriz de resolución (64). Actualización de elementos es aún más fácil (de nuevo, no incluya el código):
pelota[1] = 15-
Dentro void setup (), configurar la pantalla:
vacío preparar() {monitor.empezar(SSD1306_SWITCHCAPVCC, 0x3C)-monitor.monitor()-}
La primera línea le dice a la biblioteca Adafruit lo dimensiones y las comunicaciones de protocolo de la pantalla está utilizando (en este caso, 128 x 64 y I2C). La segunda línea (display.display ()) Cuenta la pantalla para mostrar todo lo que se almacena en la memoria intermedia (que no es nada).
Cree dos métodos llamados drawBall y eraseBall:
vacío drawBall(int x, int y) {monitor.drawCircle(x, y, BALL_SIZE, BLANCO)-}vacío eraseBall(int x, int y) {monitor.drawCircle(x, y, BALL_SIZE, NEGRO)-}
Éstos toman la x y y las coordenadas de la pelota y dibujar en la pantalla utilizando el drawCircle Método de las bibliotecas de presentación. Este sistema utiliza la constante BALL_SIZE definido anteriormente. Prueba a cambiar esto y ver qué pasa. Este método drawCircle acepta un color de píxel - NEGRO o BLANCO. Como se trata de una pantalla monocromática (un solo color), blanco equivale a un píxel de estar en y negro convierte el píxel apagado.
Ahora crea un método llamado moveAi:
vacío moveAi() {eraseAiPaddle(aiPos)-Si (pelota[1] gt; aiPos) {++aiPos-}más Si (pelota[1] lt; aiPos) {--aiPos-}drawAiPaddle(aiPos)-}
Este método se encarga de mover el Inteligencia artificial o AI jugador. Esto es bastante simple opositor de la computadora - Si el balón está por encima de la paleta, moverse hacia arriba. Que está por debajo de la pala, se mueve hacia abajo. Bastante simple, pero funciona bien. Se utilizan los símbolos de incremento y decremento (++aiPos y -aiPos) Para sumar o restar uno del aiPosition. Se podría añadir o restar un número más grande para hacer que la IA se mueven más rápido, y por lo tanto será más difícil de superar. He aquí cómo usted haría lo siguiente:
aiPos += 2-
Y:
aiPos -= 2-
los Iguales Plus y Iguales menos signos son taquigrafía para sumar o restar dos desde / hasta el valor actual de aiPos. Aquí hay otra manera de hacerlo:
aiPos = aiPos + 2-
y
aiPos = aiPos - 1-
Observe cómo este método borra primero la paleta, y luego dibuja de nuevo. Esto tiene que ser hecho de esta manera. Si se señaló a la nueva posición de la paleta, no habría dos paletas superpuestas en la pantalla.
los drawNet método utiliza dos bucles para dibujar la red:
vacío drawNet() {para (int yo = 0- yo lt; (resolución[1] / WALL_WIDTH)- ++yo) {drawPixel(((resolución[0] / 2) - 1), yo * (WALL_WIDTH) + (WALL_WIDTH * yo), WALL_WIDTH)-}}
Este utiliza el WALL_WIDTH Variables para establecer su tamaño.
Crear métodos llamados drawPixels y erasePixels. Al igual que los métodos de bolas, la única diferencia entre estos dos es el color de los píxeles:
vacío drawPixel(int posX, int ramillete de flores, int dimensiones) {para (int x = 0- x lt; dimensiones- ++x) {para (int y = 0- y lt; dimensiones- ++y) {monitor.drawPixel((posX + x), (ramillete de flores + y), BLANCO)-}}}vacío erasePixel(int posX, int ramillete de flores, int dimensiones) {para (int x = 0- x lt; dimensiones- ++x) {para (int y = 0- y lt; dimensiones- ++y) {monitor.drawPixel((posX + x), (ramillete de flores + y), NEGRO)-}}}
De nuevo, ambos de estos métodos utilizan dos para bucles para dibujar un grupo de píxeles. En lugar de tener que dibujar cada píxel utilizando las bibliotecas drawPixel método, los bucles dibujar un grupo de píxeles en base a las dimensiones dadas.
los drawScore método utiliza las características del texto de la biblioteca para escribir el jugador y la puntuación de AI a la pantalla. Estos se almacenan en playerScore y aiScore:
vacío drawScore() {monitor.SetTextSize(2)-monitor.SetTextColor(BLANCO)-monitor.setCursor(45, 0)-monitor.println(playerScore)-monitor.setCursor(75, 0)-monitor.println(aiScore)-}
Este método también tiene una eraseScore homólogo, que establece los píxeles a negro o apagado.
Los últimos cuatro métodos son muy similares. Ellos dibujar y borrar el jugador y paletas AI:
vacío 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 ellos llaman el erasePixel método de crear antes. Estos métodos dibujar y borrar la paleta adecuada.
Hay un poco más de lógica en el bucle principal. Aquí está todo el código:
#incluir #incluir #incluir #incluir Adafruit_SSD1306 monitor(4)-int resolución[2] = {128, 64}, pelota[2] = {20, (resolución[1] / 2)}-const int PIXEL_SIZE = 8, WALL_WIDTH = 4, PADDLE_WIDTH = 4, BALL_SIZE = 4, VELOCIDAD = 3-int playerScore = 0, aiScore = 0, playerpos = 0, aiPos = 0-carbonizarse ballDirectionHori = `R`, ballDirectionVerti = `S`-booleano InProgress = cierto-vacío preparar() {monitor.empezar(SSD1306_SWITCHCAPVCC, 0x3C)-monitor.monitor()-}vacío lazo() {Si (aiScore gt; 9 || playerScore gt; 9) {// comprueba el estado del juegoen progreso = falso-}Si (en progreso) {eraseScore()-eraseBall(pelota[0], pelota[1])-Si (ballDirectionVerti == `U`) {// coloca pelota hacia arriba en diagonalpelota[1] = pelota[1] - VELOCIDAD-}Si (ballDirectionVerti == `RE`) {// coloca bola hacia abajo en diagonalpelota[1] = pelota[1] + VELOCIDAD-}Si (pelota[1] lt; = 0) { // rebotar la pelota fuera de la parte superior ballDirectionVerti = `D`-} if (balón [1] gt; = resolución [1]) {// rebotar la pelota fuera de la parte inferiorballDirectionVerti = `U`-}Si (ballDirectionHori == `R`) {pelota[0] = pelota[0] + VELOCIDAD- // balón movimientoSi (pelota[0] gt; = (resolución[0] - 6)) {// balón está en el borde de la pantalla AISi ((aiPos + 12) gt; = pelota[1] && (aiPos - 12) lt; = pelota[1]) { // balón golpea AI paleta si (bola [1] gt; (AiPos + 4)) {// desviar bola abajoballDirectionVerti = `RE`-}más Si (pelota[1] lt; (aiPos - 4)) {// desviar pelotaballDirectionVerti = `U`-}más {// desviar bola rectaballDirectionVerti = `S`-}// cambio de dirección balónballDirectionHori = `L`-}más {// META!pelota[0] = 6- // mover bola a otro lado de la pantallaballDirectionVerti = `S`- // restablecer bola para desplazamiento en línea rectapelota[1] = resolución[1] / 2- // mover bola a mediados de pantalla++playerScore- // aumento jugador puntuación}}}Si (ballDirectionHori == `L`) {pelota[0] = pelota[0] - VELOCIDAD- // balón movimientoSi (pelota[0] lt; = 6) { // balón está en el borde jugador de la pantalla si ((playerpos + 12) gt; = bola [1] && (playerpos - 12) lt; = bola [1]) {// balón golpea jugador paddle si (bola [1] gt; (Playerpos + 4)) {// desviar bola abajoballDirectionVerti = `RE`-}más Si (pelota[1] lt; (playerpos - 4)) { // desviar pelota ballDirectionVerti = `u} else {// desviar bola recta ballDirectionVerti =` S`-} // cambiar de dirección balón ballDirectionHori = `R`-} else {balón [0] = resolución [0] - 6- // pelota se mueva a otro lado de la pantalla ballDirectionVerti = `S`- // restablecer balón a balón desplazamiento en línea recta [1] = resolución [1] / 2- // pelota se mueva a mitad de la pantalla ++ aiScore- // aumentar AI score}}} drawBall (balón de [0], bola [1]) - erasePlayerPaddle (playerpos) - playerpos = analogRead (A2) - // leídos playerpos jugador potenciómetro = mapa (playerpos, 0, 1023, 8, 54) - // valor convertido del 0 - 1023 8 - 54 drawPlayerPaddle (playerpos) - moveAi () - drawNet () - drawScore (-)} else {// alguien ha ganado display.clearDisplay () - display.setTextSize (4) - display.setTextColor (BLANCO) - display.setCursor (0, 0) - // averiguar quién si (aiScore gt; playerScore) {monitor.println("¡TÚ PIERDES!")-}más Si (playerScore gt; aiScore) {monitor.println("¡TÚ GANAS!")-}}monitor.monitor()-}vacío moveAi() {// mover la paleta de AIeraseAiPaddle(aiPos)-Si (pelota[1] gt; aiPos) {++aiPos-}más Si (pelota[1] lt; aiPos) {--aiPos-}drawAiPaddle(aiPos)-}vacío drawScore() {// dibujar puntuaciones de AI y jugadormonitor.SetTextSize(2)-monitor.SetTextColor(BLANCO)-monitor.setCursor(45, 0)-monitor.println(playerScore)-monitor.setCursor(75, 0)-monitor.println(aiScore)-}vacío eraseScore() {// borrar puntuaciones de AI y jugadormonitor.SetTextSize(2)-monitor.SetTextColor(NEGRO)-monitor.setCursor(45, 0)-monitor.println(playerScore)-monitor.setCursor(75, 0)-monitor.println(aiScore)-}vacío drawNet() {para (int yo = 0- yo lt; (resolución[1] / WALL_WIDTH)- ++yo) {drawPixel(((resolución[0] / 2) - 1), yo * (WALL_WIDTH) + (WALL_WIDTH * yo), WALL_WIDTH)-}}vacío drawPixel(int posX, int ramillete de flores, int dimensiones) {// sorteo de los grupos de píxelespara (int x = 0- x lt; dimensiones- ++x) {para (int y = 0- y lt; dimensiones- ++y) {monitor.drawPixel((posX + x), (ramillete de flores + y), BLANCO)-}}}vacío erasePixel(int posX, int ramillete de flores, int dimensiones) {// grupo de borrado de píxelespara (int x = 0- x lt; dimensiones- ++x) {para (int y = 0- y lt; dimensiones- ++y) {monitor.drawPixel((posX + x