Taula de continguts:
Vídeo: Joc de serp OLED Arduino: 3 passos
2024 Autora: John Day | [email protected]. Última modificació: 2024-01-30 08:13
Hola i benvinguts, als nostres instruccions sobre com fer un joc OLED arduino, aquest projecte va sorgir quan intentàvem fer el nostre primer joc amb un arduino, doncs, vam pensar on era millor començar que el clàssic Nokia Snake (bé a almenys un clon de serp:)).
El que necessitareu
Subministraments
Arduino UNO o clon
Pantalla OLED
4 díodes
500-1k resistència
4 botons de controlador
Zumbador Piezo passiu
opcional
BreadBoard sense soldadura
Tingueu en compte que aquests enllaços són només per exemple
Pas 1: el circuit
A la imatge anterior podeu veure el nostre circuit, fem servir el pin d3 a l’arduino com a pin de sol·licitud d’interrupció perquè l’arduino doni prioritat a la lectura de les entrades del controlador que són d4 d5 d6 d7. El bàsic del circuit és que es prem un botó de direcció que augmenta 5v, activant el pin de sol·licitud d’interrupció (fil morat d3) i un pin de direcció corresponent, la funció d’interrupció crida una funció de direcció d’actualització i aquest codi mou la serp en conseqüència. El pin 9 s'utilitza com a pin de so, ja que és un PWM (~ modulació d'amplada de pols) que es connecta directament a un piezoelèctric de 5v al pin + i el - torna a 0v / terra.
(FYI a l'arduino uno i els clons només d2 i d3 poden actuar com a pins de sol·licitud d'interrupció).
Clavilles de direcció:
d4 Pujar TARONJA
d5 A baix ROSA
d6 Esquerra BLAU
d7 Dret MARRÓ
so d9 GRIS
Cada botó té una entrada de connexió de 5V i una sortida que es connecta primer a la seva entrada digital respectiva a l’arduino, aquesta mateixa sortida de cada botó es connecta al seu propi díode, utilitzem els díodes per aturar la volta de volta a la altres botons i activar-los. A l'extrem càtode (-) de tots els 4 díodes, els unim per crear una unió de sortida que es connecta a d3 i, a continuació, a través de la resistència a 0v / terra per treure els pins d'arduino de manera que no deixin els pins flotants quan no activat.
(FYI un pin flotant pot rebre tensió fantasma i provocar un comportament inusual)
S’utilitzen 2 pins analògics per conduir la pantalla, es tracta dels pins i2c de maquinari arduino.
A5 està connectat a SCL GROC
A4 està connectat a SDA GREEN
La sortida de + 5v i 0v (terra) de l'arduino s'utilitza com a font d'alimentació per a tot el circuit que es pot alimentar mitjançant un carregador de telèfon o usb.
Pas 2: el codi
// ------------------------ ANJAWARE SNAKE Jocs Amb ajuda de la gent de la xarxa --------------- -------
#incloure
#include // https://github.com/adafruit/Adafruit-GFX-Library #include // https://github.com/adafruit/Adafruit-GFX-Library // display set (width, height) Adafruit_SSD1306 display (128, 64); // defineix els pins d'entrada són els pins de l'arduino que mai canvien, de manera que #define #define INTPIN 3 // només els pins 2 i 3 poden ser interminables a UNO #define UPPIN 4 // són pins connectats tp commutador rellevant #define DWNPIN 5 #define LFTPIN 6 #define RHTPIN 7 #define SND 9 // defineix direccions #define DIRUP 1 // aquests valors és el que mira la "serp" per decidir- #define DIRDOWN 2 // la direcció de la serp # defineix DIRLEFT 3 #define DIRRIGHT 4
// estableix variables de botó
// volitile cos el necessitem per actualitzar-lo amb la interupt, de manera que pugui tenir qualsevol valor de cicle
// mai és superior a 4, de manera que només necessiteu 8 bits int per estalviar recursos volàtils uint8_t pressionat amb el botó = 0; bool butup = 0; bool butdown = 0; // ho fem servir per establir true per a "detectar" quina direcció es pressiona bool butleft = 0; bool butright = 0;
// ints de serps
byte snakePosX [30]; // matriu per fer cos de byte de serp snakePosY [30];
int serpX = 30; // posició del cap de serp
int serpY = 30; int serp Mida = 1; // recompte de mida de serp limitat a la mida de la matriu
// ints del món
uint8_t worldMinX = 0; // estableixen els límits de l'àrea de joc
uint8_t worldMaxX = 128; uint8_t worldMinY = 10; uint8_t worldMaxY = 63;
// recollir scran (aliment) i posició de scran
bool scranAte = 0; uint8_t scranPosX = 0; uint8_t scranPosY = 0;
// puntuacions variables
playcore llarg = 0; puntuació màxima llarga = 30; // estableix la puntuació màxima en 3 punts com a punt de partida
// --------------------------- Això és el que executa la interupt en augmentar la tensió ------------ -------------
void interruptpressed () {delay (150); // lleuger retard per a la protecció "rebot" afegida updatedirection (); } // ------------------ actualitza el valor de direcció des de prémer el botó ----------------- anul·la la direcció actualitzada () { // Serial.println ("updatingdirection"); butup = digitalRead (UPPIN); // comproveu quina entrada ha augmentat i configureu bool true butdown rellevant = digitalRead (DWNPIN); butleft = digitalRead (LFTPIN); butright = DigitalRead (RHTPIN); // si els estatemes visualitzen quina entrada ha augmentat i introdueix el valor rellevant a la variable "pulsat" // aquesta variable dicta la direcció del moviment si (butup == true) {buttonpressed = DIRUP; // Serial.println ("UP pressionat"); // Serial.println (premut amb botó); butup = fals; to (SND, 1500, 10); } if (butdown == true) {buttonpressed = DIRDOWN; // Serial.println ("DOWN pressionat"); // Serial.println (premut amb botó); butdown = fals; to (SND, 1500, 10); }
if (butleft == true)
{buttonpressed = DIRLEFT; // Serial.println ("ESQUERRA premuda"); // Serial.println (pulsat); butleft = fals; to (SND, 1500, 10); } if (butright == true) {buttonpressed = DIRRIGHT; // Serial.println ("Dret premut"); // Serial.println (pulsat); butright = fals; to (SND, 1500, 10); }}
// -------------------------- dibuixar les rutines de visualització ------------------ -----------------
void updateDisplay () // dibuixa partitures i esquemes
{// Serial.println ("Actualització de la pantalla");
display.fillRect (0, 0, display.width () - 1, 8, NEGRE);
display.setTextSize (0); display.setTextColor (BLANC); // dibuixar puntuacions display.setCursor (2, 1); display.print ("Puntuació:"); display.print (String (playscore, DEC)); display.setCursor (66, 1); display.print ("Alt:"); display.print (String (highscore, DEC)); // dibuixar àrea de joc // pos 1x, 1y, 2x, 2y, color display.drawLine (0, 0, 127, 0, BLANC); // vora molt superior display.drawLine (63, 0, 63, 9, BLANC); // separador de puntuació display.drawLine (0, 9, 127, 9, BLANC); // sota la vora del text display.drawLine (0, 63, 127, 63, BLANC); // vora inferior display.drawLine (0, 0, 0, 63, BLANC); // vora esquerra display.drawLine (127, 0, 127, 63, BLANC); // vora dreta
}
// ----------------------------------- Actualitza l'àrea de joc ---------- --------------------
void updateGame () // actualitza la visualització de l'àrea de joc
{display.clearDisplay ();
display.drawPixel (scranPosX, scranPosY, BLANC);
scranAte = scranFood ();
// comproveu les rutines de les serps
if (outOfArea () || selfCollision ())
{ fi del joc(); }
// mostrar serp
for (int i = 0; i0; i--) {snakePosX = snakePosX [i-1]; snakePosY = snakePosY [i-1]; } // afegiu un píxel addicional a la serp if (scranAte) {snakeSize + = 1; snakePosX [snakeSize-1] = serpX; snakePosY [snakeSize-1] = serpY; }
commutador (premut amb el botó) // era snakeDirection
{cas DIRUP: serp Y- = 1; trencar; cas DIRDOWN: serpY + = 1; trencar; cas DIRLEFT: serpX- = 1; trencar; cas DIRECCIÓ: serpX + = 1; trencar; } snakePosX [0] = serpX; snakePosY [0] = serpY; updateDisplay (); display.display (); // --------------------- col·loqueu el scran -------------------
void placeScran ()
{scranPosX = aleatori (worldMinX + 1, worldMaxX-1); scranPosY = aleatori (worldMinY + 1, worldMaxY-1); } // ------------------------ SCRAN ATE POINT UP ---------------- bool scranFood () {if (snakeX == scranPosX && snakeY == scranPosY) {playscore = playscore + 10; to (SND, 2000, 10); updateDisplay (); placeScran (); retorn 1; } else {return 0; }} // --------------------- fora de l'àrea ---------------------- bool outOfArea () {return snakeX = worldMaxX || snakeY = worldMaxY; } //---------------------- fi del joc----------------------- --- void gameOver () {uint8_t rectX1, rectY1, rectX2, rectY2; rectX1 = 38; rectY1 = 28; rectX2 = 58; rectY2 = 12; display.clearDisplay (); display.setCursor (40, 30); display.setTextSize (1); to (SND, 2000, 50); display.print ("JOC"); to (SND, 1000, 50); display.print ("OVER"); if (playscore> = puntuació més alta) // comproveu si la puntuació és superior a la puntuació més alta {puntuació = puntuació més alta; // single if statment to update high score} for (int i = 0; i <= 16; i ++) // es tracta de dibuixar rectanlges al voltant del joc sobre {display.drawRect (rectX1, rectY1, rectX2, rectY2, WHITE); Serial.println ("si bucle"); display.display (); rectX1- = 2; // canvieu 2 píxels rectY1- = 2; rectX2 + = 4; // canvia més de 2 píxels des del darrer punt rectY2 + = 4; to (SND, i * 200, 3); } display.display (); // Neteja la pantalla després de la fama per rectX1 = 0; // estableix la posició inicial de la línia rectY1 = 0; rectX2 = 0; rectY2 = 63; for (int i = 0; i <= 127; i ++) {uint8_t cnt = 0; display.drawLine (rectX1, rectY1, rectX2, rectY2, NEGRE); rectX1 ++; rectX2 ++; display.display (); } display.clearDisplay (); playscore = 0; // restablir detalls de la serp i del jugador snakeSize = 1; serpX = display.width () / 2; serpY = display.height () / 2; waitForPress (); // espera que el jugador comenci el joc} // ------------------------- espera que prems el bucle ---------- --------------- void waitForPress () {bool esperant = 0; // el bucle finalitza quan això és cert display.clearDisplay (); while (esperant == 0) {drawALineForMe (BLANC); // dibuixa una línia blanca aleatòria drawALineForMe (NEGRE); // dibuixeu una línia negra aleatòria perquè la pantalla no ompli completament la pantalla blanca.fillRect (19, 20, 90, 32, NEGRE); // fons en blanc per al text display.setTextColor (BLANC); display.setCursor (35, 25); display.setTextSize (2); // font més gran display.println ("SERP"); // x y w h r r display.drawRoundRect (33, 22, 62, 20, 4, BLANC); // border Snake display.drawRect (19, 20, 90, 32, BLANC); // quadre de vora - 3 display.setCursor (28, 42); display.setTextSize (0); // tornar al tipus de lletra normal a display.println ("premeu qualsevol tecla"); display.display (); esperant = Llegir digital (INTPIN); // comproveu si la tecla en espera espera canviarà a 1 final mentre es prem el botó = 0; // botó de restabliment premeu}} // -------------------- DIBUIXA una línia d'entrada aleatòria color uint8_t -------------- ----- void drawALineForMe (uint8_t clr) {uint8_t línia1X, línia1Y, línia2X, línia2Y = 0; // estableix coordenades aleatòries per a una línia i dibuixa-la // variable ni més ni menys línia1X = aleatori (worldMinX + 1, worldMaxX-1); línia1Y = aleatòria (worldMinY + 1, worldMaxY-1); línia2X = aleatòria (worldMinX + 1, worldMaxX-1); línia2Y = aleatòria (worldMinY + 1, worldMaxY-1); display.drawLine (line1X, line1Y, line2X, line2Y, clr); } // ------------------------------------- detecció de col·lisions -------- -----------------------
for (byte i = 4; i <snakeSize; i ++) {if (snakeX == snakePosX && snakeY == snakePosy ) {return 1; to (SND, 2000, 20); to (SND, 1000, 20); } retorn 0; }
// -------------------------------- CONFIGURACIÓ --------------- -------------------------------
void setup () {delay (100); // simplement doneu a les coses l'oportunitat de "arrencar" // Serial.begin (9600); // desmarqueu aquesta opció si voleu veure les sortides en sèrie display.begin (SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay (); // Comenceu amb una pantalla neta display.setTextColor (BLANC); // configureu la mida de rotació del color del text, etc. display.setRotation (0); display.setTextWrap (fals); display.dim (0); // configureu la brillantor de la pantalla pinMode (INTPIN, INPUT); // configureu els ports correctes a les entrades pinMode (UPPIN, INPUT); pinMode (DWNPIN, INPUT); pinMode (LFTPIN, INPUT); pinMode (RHTPIN, INPUT); // aquesta és l'ordre interupt que "atura" l'arduino per llegir les entrades // command-function- pin-function to execute-condition on pin attachInterrupt (digitalPinToInterrupt (INTPIN), interruptpressed, RISING); // Serial.println ("Configuració superada"); waitForPress (); // mostra la pantalla d'inici de la serp placeScran (); // col·loqueu el primer menjar} // --------------------- LLAÇ PRINCIPAL ----------------- ---------------------- bucle buit () {updateGame (); // aquesta funció és la que porta el codi principal}
Pas 3:
Recomanat:
Robot de serp imprès en 3D: 7 passos (amb imatges)
Robot de serp imprès en 3D: quan vaig aconseguir la meva impressora 3D vaig començar a pensar què en puc fer. Vaig imprimir moltes coses, però volia fer tota una construcció amb la impressió 3D. Llavors vaig pensar en fer un animal robot. La meva primera idea va ser fer un gos o una aranya, però un
Serp: la màquina inútil: 5 passos
Serp: la màquina inútil: saps quan eres petit i jugaves a serp al teu Nokia? En un moment determinat, la serp començaria a perseguir la seva pròpia cua, i va ser llavors quan es va saber que el joc estava a punt d’acabar. Vam decidir convertir-ho en un robot, només el joc mai
Serp en una taula de pa: 3 passos (amb imatges)
Serp a la taula de pa: " Tens jocs al telèfon? &Quot; " No exactament. " Introducció: senzill de controlar, fàcil de programar i immortalitzat pel Nokia 6110, Snake s’ha convertit en un projecte preferit entre els enginyers. S'ha implementat en qualsevol cosa, des de matrius LED, L
Joc de la serp: 4 passos
Joc de la serp: Hola nois, avui us mostraré com fer un joc bàsic de serps a Python i sorprendre els amics en aquestes vacances. Això és molt senzill, només cal que instal·leu Python 3 i Pygame. En aquest instructiu he afegit un vídeo sobre com instal·lar pygame. Després de
Joc de serp en Do: 8 passos
Joc de la serp en Do: el joc de la serp era popular en els telèfons mòbils antics que es poden descarregar molt fàcilment mitjançant el programa c. Per construir aquest projecte cal tenir una comprensió bàsica de la sintaxi c. Exemple: per a bucle, mentre que bucle, etc. Amb la creació d'aquest tipus de jocs projecta el programamin