Arduino Nano Tetris Game en una matriz casera de 16x8
Componentes y suministros
| × | 1 | ||||
| × | 4 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 128 |
Herramientas y máquinas necesarias
|
Aplicaciones y servicios en línea
|
Acerca de este proyecto
Construí este juego de tetris con una matriz LED casera de 16x8, Arduino Nano y dos registros de cambio 74hc595. También agregué un pitido cuando presionas cualquier botón.
Código
- código
código Arduino
/ * Autor:Jae Yeong Bae UBC ECE jocker.tistory.com Fecha:18 de enero de 2013 Archivo:Tetris v2 Registro de cambios:v2:muestra la puntuación en el final del juego Propósito:matar el tiempo .. + por diversión Circuitos + Pines:Matriz de LED:2 74HC575 Shift Registros en orden:Pines verde, azul, rojo:Pestillo =3 Reloj =2 Datos =4 filas de ánodos =5 a 13 (8 pines) compartidos entre ambos botones de matriz (como digital):A4 =izquierda A5 =abajo A6 =derecha A7 =arriba (rotar) Comentario:Este es mi segundo proyecto Arduino. El código puede ser confuso e ineficaz. Referencias de la biblioteca Arduino y hojas de datos. * / Unsigned char latchPin =3; unsigned char clockPin =2; unsigned char dataPin =4; unsigned char rowPin =5; long delays =0; short delay_ =500; long bdelay =0; short buttondelay =150; btdowndelay corto =30; btsidedelay corto =80; tipo de bloque de caracteres sin firmar; rotación de bloque de caracteres sin firmar; líneas int =0; bloque booleano [8] [18]; // 2 extra para la rotación pila booleana [8] [16]; boolean disp [8] [16]; boolean lib [10] [5] [7]; void setup () {lib [0] [1] [0] =1; lib [0] [2] [0] =1; lib [0] [3] [0] =1; lib [0] [0] [1] =1; lib [0] [4] [ 1] =1; lib [0] [3] [2] =1; lib [0] [0] [2] =1; lib [0] [4] [2] =1; lib [0] [2 ] [3] =1; lib [0] [0] [3] =1; lib [0] [4] [3] =1; lib [0] [1] [4] =1; lib [0] [0] [4] =1; lib [0] [4] [4] =1; lib [0] [0] [5] =1; lib [0] [4] [5] =1; lib [ 0] [1] [6] =1; lib [0] [2] [6] =1; lib [0] [3] [6] =1; lib [1] [2] [0] =1; lib [1] [1] [1] =1; lib [1] [2] [1] =1; lib [1] [2] [2] =1; lib [1] [2] [3] =1; lib [1] [2] [4] =1; lib [1] [2] [5] =1; lib [1] [1] [6] =1; lib [1] [2] [6 ] =1; lib [1] [3] [6] =1; lib [2] [1] [0] =1; lib [2] [2] [0] =1; lib [2] [3] [0] =1; lib [2] [0] [1] =1; lib [2] [4] [1] =1; lib [2] [4] [2] =1; lib [2] [ 3] [3] =1; lib [2] [2] [4] =1; lib [2] [1] [5] =1; lib [2] [0] [6] =1; lib [2 ] [1] [6] =1; lib [2] [2] [6] =1; lib [2] [3] [6] =1; lib [2] [4] [6] =1; lib [3] [0] [0] =1; lib [3] [1] [0] =1; lib [3] [2] [0] =1; lib [3] [3] [0] =1; lib [3] [4] [0] =1; lib [3] [3] [1] =1; lib [3] [2] [2] =1; lib [3] [3] [3] =1; lib [3] [4] [4] =1; lib [3] [0] [5] =1; l ib [3] [4] [5] =1; lib [3] [1] [6] =1; lib [3] [2] [6] =1; lib [3] [3] [6] =1; lib [4] [3] [0] =1; lib [4] [2] [1] =1; lib [4] [3] [1] =1; lib [4] [1] [2 ] =1; lib [4] [3] [2] =1; lib [4] [0] [3] =1; lib [4] [3] [3] =1; lib [4] [0] [4] =1; lib [4] [1] [4] =1; lib [4] [2] [4] =1; lib [4] [3] [4] =1; lib [4] [ 4] [4] =1; lib [4] [3] [5] =1; lib [4] [3] [6] =1; lib [5] [0] [0] =1; lib [5 ] [1] [0] =1; lib [5] [2] [0] =1; lib [5] [3] [0] =1; lib [5] [4] [0] =1; lib [5] [0] [1] =1; lib [5] [0] [2] =1; lib [5] [1] [2] =1; lib [5] [2] [2] =1; lib [5] [3] [2] =1; lib [5] [4] [3] =1; lib [5] [4] [4] =1; lib [5] [0] [5] =1; lib [5] [4] [5] =1; lib [5] [1] [6] =1; lib [5] [2] [6] =1; lib [5] [3] [ 6] =1; lib [6] [2] [0] =1; lib [6] [3] [0] =1; lib [6] [1] [1] =1; lib [6] [0 ] [2] =1; lib [6] [0] [3] =1; lib [6] [1] [3] =1; lib [6] [2] [3] =1; lib [6] [3] [3] =1; lib [6] [0] [4] =1; lib [6] [4] [4] =1; lib [6] [0] [5] =1; lib [ 6] [4] [5] =1; lib [6] [1] [6] =1; lib [6] [2] [6] =1; lib [6] [3] [6] =1; lib [7] [0] [0] =1; lib [7] [1] [0] =1; lib [7] [2] [0] =1; lib [7] [3] [0] =1; lib [7] [4] [0] =1; lib [7] [4] [1] =1; lib [7] [3] [2] =1; lib [7] [2] [3 ] =1; lib [7] [1] [4] =1; lib [7] [1] [5] =1; lib [7] [1] [6] =1; lib [8] [1] [0] =1; lib [8] [2] [0 ] =1; lib [8] [3] [0] =1; lib [8] [0] [1] =1; lib [8] [4] [1] =1; lib [8] [0] [2] =1; lib [8] [4] [2] =1; lib [8] [1] [3] =1; lib [8] [2] [3] =1; lib [8] [ 3] [3] =1; lib [8] [0] [4] =1; lib [8] [4] [4] =1; lib [8] [0] [5] =1; lib [8 ] [4] [5] =1; lib [8] [1] [6] =1; lib [8] [2] [6] =1; lib [8] [3] [6] =1; lib [9] [1] [0] =1; lib [9] [2] [0] =1; lib [9] [3] [0] =1; lib [9] [0] [1] =1; lib [9] [4] [1] =1; lib [9] [0] [2] =1; lib [9] [4] [2] =1; lib [9] [1] [3] =1; lib [9] [2] [3] =1; lib [9] [3] [3] =1; lib [9] [4] [3] =1; lib [9] [4] [ 4] =1; lib [9] [3] [5] =1; lib [9] [1] [6] =1; lib [9] [2] [6] =1; int semilla =(analogRead (0) +1) * (analogRead (1) +1) * (analogRead (2) +1) * (analogRead (3) +1); randomSeed (semilla); aleatorio (10,9610806); semilla =semilla * aleatoria (3336,15679912) + analogRead (aleatoria (4)); randomSeed (semilla); aleatorio (10,98046); cli (); // detener las interrupciones // establecer la interrupción del timer0 en 2kHz TCCR1A =0; // establecer todo el registro TCCR0A en 0 TCCR1B =0; // lo mismo para TCCR0B TCNT1 =0; // inicializar el valor del contador en 0 // establecer comparar registro de coincidencia para incrementos de 2khz OCR1A =259; // =(16 * 10 ^ 6) / (2000 * 64) - 1 (debe ser <256) // activar el modo CTC TCCR1A | =(1 <0; i--) {para (j =0; j <16; j ++) {bloque [i] [j] =bloque [i-1] [j]; }} para (j =0; j <16; j ++) {bloque [0] [j] =0; } updateLED (); return 1; } return 0;} int readBut () {if (bdelay> millis ()) {return 0; } if (analogRead (A4)> 500) {// izquierda bdelay =millis () + btsidedelay; volver 3; } if (analogRead (A5)> 500) {// down bdelay =millis () + btdowndelay; volver 4; } if (analogRead (A6)> 500) {// derecha bdelay =millis () + btsidedelay; volver 2; } if (analogRead (A7)> 500) {// up bdelay =millis () + buttondelay; return 1; } return 0;} void updateLED () {int i; int j; para (i =0; i <8; i ++) {para (j =0; j <16; j ++) {disp [i] [j] =bloque [i] [j] | pila [i] [j]; }}} void rotate () {// saltar al bloque cuadrado (3) if (blocktype ==3) return; int xi; int yi; int i; int j; // detecta la izquierda para (i =7; i> =0; i--) {para (j =0; j <16; j ++) {if (block [i] [j]) {xi =i; }}} // detectar para (i =15; i> =0; i--) {para (j =0; j <8; j ++) {if (block [j] [i]) {yi =i; }}} if (blocktype ==0) {if (blockrotation ==0) {if (! space_left ()) {if (space_right3 ()) {if (! moveright ()) return; xi ++; } else return; } else if (! space_right ()) {if (space_left3 ()) {if (! moveleft ()) return; if (! moveleft ()) return; xi--; xi--; } else return; } else if (! space_right2 ()) {if (space_left2 ()) {if (! moveleft ()) return; xi--; } else return; } bloque [xi] [yi] =0; bloque [xi] [yi + 2] =0; bloque [xi] [yi + 3] =0; bloque [xi-1] [yi + 1] =1; bloque [xi + 1] [yi + 1] =1; bloque [xi + 2] [yi + 1] =1; blockrotation =1; } else {bloque [xi] [yi] =0; bloque [xi + 2] [yi] =0; bloque [xi + 3] [yi] =0; bloque [xi + 1] [yi-1] =1; bloque [xi + 1] [yi + 1] =1; bloque [xi + 1] [yi + 2] =1; blockrotation =0; }} // desplazamiento a mid xi ++; yi ++; if (blocktype ==1) {if (blockrotation ==0) {block [xi-1] [yi-1] =0; bloque [xi-1] [yi] =0; bloque [xi + 1] [yi] =0; bloque [xi] [yi-1] =1; bloque [xi + 1] [yi-1] =1; bloque [xi] [yi + 1] =1; blockrotation =1; } else if (blockrotation ==1) {if (! space_left ()) {if (! moveright ()) return; xi ++; } xi--; bloque [xi] [yi-1] =0; bloque [xi + 1] [yi-1] =0; bloque [xi] [yi + 1] =0; bloque [xi-1] [yi] =1; bloque [xi + 1] [yi] =1; bloque [xi + 1] [yi + 1] =1; blockrotation =2; } más si (rotación de bloque ==2) {yi -; bloque [xi-1] [yi] =0; bloque [xi + 1] [yi] =0; bloque [xi + 1] [yi + 1] =0; bloque [xi] [yi-1] =1; bloque [xi] [yi + 1] =1; bloque [xi-1] [yi + 1] =1; blockrotation =3; } else {if (! space_right ()) {if (! moveleft ()) return; xi--; } bloque [xi] [yi-1] =0; bloque [xi] [yi + 1] =0; bloque [xi-1] [yi + 1] =0; bloque [xi-1] [yi-1] =1; bloque [xi-1] [yi] =1; bloque [xi + 1] [yi] =1; blockrotation =0; }} if (blocktype ==2) {if (blockrotation ==0) {block [xi + 1] [yi-1] =0; bloque [xi-1] [yi] =0; bloque [xi + 1] [yi] =0; bloque [xi] [yi-1] =1; bloque [xi + 1] [yi + 1] =1; bloque [xi] [yi + 1] =1; blockrotation =1; } else if (blockrotation ==1) {if (! space_left ()) {if (! moveright ()) return; xi ++; } xi--; bloque [xi] [yi-1] =0; bloque [xi + 1] [yi + 1] =0; bloque [xi] [yi + 1] =0; bloque [xi-1] [yi] =1; bloque [xi + 1] [yi] =1; bloque [xi-1] [yi + 1] =1; blockrotation =2; } más si (rotación de bloque ==2) {yi -; bloque [xi-1] [yi] =0; bloque [xi + 1] [yi] =0; bloque [xi-1] [yi + 1] =0; bloque [xi] [yi-1] =1; bloque [xi] [yi + 1] =1; bloque [xi-1] [yi-1] =1; blockrotation =3; } else {if (! space_right ()) {if (! moveleft ()) return; xi--; } bloque [xi] [yi-1] =0; bloque [xi] [yi + 1] =0; bloque [xi-1] [yi-1] =0; bloque [xi + 1] [yi-1] =1; bloque [xi-1] [yi] =1; bloque [xi + 1] [yi] =1; blockrotation =0; }} if (blocktype ==4) {if (blockrotation ==0) {block [xi + 1] [yi-1] =0; bloque [xi-1] [yi] =0; bloque [xi + 1] [yi] =1; bloque [xi + 1] [yi + 1] =1; blockrotation =1; } else {if (! space_left ()) {if (! moveright ()) return; xi ++; } xi--; bloque [xi + 1] [yi] =0; bloque [xi + 1] [yi + 1] =0; bloque [xi-1] [yi] =1; bloque [xi + 1] [yi-1] =1; blockrotation =0; }} if (blocktype ==5) {if (blockrotation ==0) {block [xi] [yi-1] =0; bloque [xi-1] [yi] =0; bloque [xi + 1] [yi] =0; bloque [xi] [yi-1] =1; bloque [xi + 1] [yi] =1; bloque [xi] [yi + 1] =1; blockrotation =1; } else if (blockrotation ==1) {if (! space_left ()) {if (! moveright ()) return; xi ++; } xi--; bloque [xi] [yi-1] =0; bloque [xi + 1] [yi] =0; bloque [xi] [yi + 1] =0; bloque [xi-1] [yi] =1; bloque [xi + 1] [yi] =1; bloque [xi] [yi + 1] =1; blockrotation =2; } más si (rotación de bloque ==2) {yi -; bloque [xi-1] [yi] =0; bloque [xi + 1] [yi] =0; bloque [xi] [yi + 1] =0; bloque [xi] [yi-1] =1; bloque [xi-1] [yi] =1; bloque [xi] [yi + 1] =1; blockrotation =3; } else {if (! space_right ()) {if (! moveleft ()) return; xi--; } bloque [xi] [yi-1] =0; bloque [xi-1] [yi] =0; bloque [xi] [yi + 1] =0; bloque [xi] [yi-1] =1; bloque [xi-1] [yi] =1; bloque [xi + 1] [yi] =1; blockrotation =0; }} if (blocktype ==6) {if (blockrotation ==0) {block [xi-1] [yi-1] =0; bloque [xi] [yi-1] =0; bloque [xi + 1] [yi-1] =1; bloque [xi] [yi + 1] =1; blockrotation =1; } else {if (! space_left ()) {if (! moveright ()) return; xi ++; } xi--; bloque [xi + 1] [yi-1] =0; bloque [xi] [yi + 1] =0; bloque [xi-1] [yi-1] =1; bloque [xi] [yi-1] =1; blockrotation =0; }} // si el bloque hecho rotar y la pila se superponen, empujar las filas hacia arriba while (! check_overlap ()) {for (i =0; i <18; i ++) {for (j =0; j <8; j ++) {block [j] [i] =bloque [j] [i + 1]; }} retrasos =milis () + retraso_; } updateLED (); } void movedown () {if (space_below ()) {// mover hacia abajo int i; para (i =15; i> =0; i--) {int j; para (j =0; j <8; j ++) {bloque [j] [i] =bloque [j] [i-1]; }} para (i =0; i <7; i ++) {bloque [i] [0] =0; }} else {// fusionar y nuevo bloque int i; int j; para (i =0; i <8; i ++) {para (j =0; j <16; j ++) {if (bloque [i] [j]) {pila [i] [j] =1; bloque [i] [j] =0; }}} newBlock (); } updateLED (); } booleano check_overlap () {int i; int j; for (i =0; i <16; i ++) {for (j =0; j <7; j ++) {if (block [j] [i]) {if (pile [j] [i]) return false; }}} for (i =16; i <18; i ++) {for (j =0; j <7; j ++) {if (block [j] [i]) {return false; }}} devuelve verdadero;} void check_gameover () {int i; int j; int cnt =0;; para (i =15; i> =0; i--) {cnt =0; para (j =0; j <8; j ++) {if (pila [j] [i]) {cnt ++; }} if (cnt ==8) {líneas ++; para (j =0; j <8; j ++) {pila [j] [i] =0; } updateLED (); retraso (50); int k; para (k =i; k> 0; k--) {para (j =0; j <8; j ++) {pila [j] [k] =pila [j] [k-1]; }} para (j =0; j <8; j ++) {pila [j] [0] =0; } updateLED (); retraso (50); i ++; }} for (i =0; i <8; i ++) {if (pile [i] [0]) gameover (); } return;} void gameover () {int i; int j; // cerrar ciego para (i =0; i <8; i ++) {para (j =0; j <16; j ++) {if (j% 2) {disp [i] [j] =1; } más {disp [7-i] [j] =1; }} retraso (60); } // calcular el tablero de puntuación int num_lines; num_lines =2; puntuación booleana [8] [17]; para (i =0; i <8; i ++) {para (j =0; j <16; j ++) {puntuación [i] [j] =0; }} int dígito1 =(líneas / 10)% 10; int dígito2 =(líneas)% 10; para (i =0; i <5; i ++) para (j =0; j <8; j ++) {puntuación [7-j] [i + 3] =lib [dígito1] [i] [j]; } para (i =0; i <5; i ++) para (j =0; j <8; j ++) {puntuación [7-j] [i + 9] =lib [dígito2] [i] [j]; } para (i =0; i <16; i ++) {puntuación [0] [i] =0; } // abrir ciego con puntuación para (i =0; i <8; i ++) {para (j =0; j <16; j ++) {if (j% 2) {disp [i] [j] =puntuación [ i] [j]; } else {disp [7-i] [j] =puntuación [7-i] [j]; }} retraso (60); } retraso (100); while (verdadero) {para (i =0; i <8; i ++) {para (j =0; j <16; j ++) {disp [i] [j] =puntuación [i] [j]; }} boolean tmpline [8]; para (i =0; i <8; i ++) {puntuación [i] [16] =puntuación [i] [0]; } para (i =0; i <8; i ++) {para (j =0; j <16; j ++) {puntuación [i] [j] =puntuación [i] [j + 1]; }} retraso (100); }} anular newBlock () {check_gameover (); tipo de bloque =aleatorio (7); if (tipo de bloque ==0) // 0 // 0 // 0 // 0 {bloque [3] [0] =1; bloque [3] [1] =1; bloque [3] [2] =1; bloque [3] [3] =1; } if (tipo de bloque ==1) // 0 // 0 0 0 {bloque [2] [0] =1; bloque [2] [1] =1; bloque [3] [1] =1; bloque [4] [1] =1; } if (tipo de bloque ==2) // 0 // 0 0 0 {bloque [4] [0] =1; bloque [2] [1] =1; bloque [3] [1] =1; bloque [4] [1] =1; } if (tipo de bloque ==3) // 0 0 // 0 0 {bloque [3] [0] =1; bloque [3] [1] =1; bloque [4] [0] =1; bloque [4] [1] =1; } if (tipo de bloque ==4) // 0 0 // 0 0 {bloque [4] [0] =1; bloque [5] [0] =1; bloque [3] [1] =1; bloque [4] [1] =1; } if (tipo de bloque ==5) // 0 // 0 0 0 {bloque [4] [0] =1; bloque [3] [1] =1; bloque [4] [1] =1; bloque [5] [1] =1; } if (tipo de bloque ==6) // 0 0 // 0 0 {bloque [3] [0] =1; bloque [4] [0] =1; bloque [4] [1] =1; bloque [5] [1] =1; } blockrotation =0;} boolean space_below () {int i; int j; for (i =15; i> =0; i--) {for (j =0; j <8; j ++) {if (block [j] [i]) {if (i ==15) return false; if (pila [j] [i + 1]) {devuelve falso; }}}} devuelve verdadero;} booleano space_left2 () {int i; int j; para (i =15; i> =0; i--) {para (j =0; j <8; j ++) {if (bloque [j] [i]) {if (j ==0 || j ==1) devuelve falso; if (pila [j-1] [i] | pila [j-2] [i]) {devuelve falso; }}}} devuelve verdadero;} booleano space_left3 () {int i; int j; para (i =15; i> =0; i--) {para (j =0; j <8; j ++) {if (bloque [j] [i]) {if (j ==0 || j ==1 || j ==2) devuelve falso; if (pila [j-1] [i] | pila [j-2] [i] | pila [j-3] [i]) {devolver falso; }}}} devuelve verdadero;} booleano space_left () {int i; int j; for (i =15; i> =0; i--) {for (j =0; j <8; j ++) {if (block [j] [i]) {if (j ==0) return false; if (pila [j-1] [i]) {devuelve falso; }}}} devuelve verdadero;} booleano space_right () {int i; int j; for (i =15; i> =0; i--) {for (j =0; j <8; j ++) {if (block [j] [i]) {if (j ==7) return false; if (pila [j + 1] [i]) {devuelve falso; }}}} devuelve verdadero;} booleano space_right3 () {int i; int j; para (i =15; i> =0; i--) {para (j =0; j <8; j ++) {if (bloque [j] [i]) {if (j ==7 || j ==6 || j ==5) devuelve falso; if (pila [j + 1] [i] | pila [j + 2] [i] | pila [j + 3] [i]) {devolver falso; }}}} devuelve verdadero;} booleano space_right2 () {int i; int j; para (i =15; i> =0; i--) {para (j =0; j <8; j ++) {if (bloque [j] [i]) {if (j ==7 || j ==6) devuelve falso; if (pila [j + 1] [i] | pila [j + 2] [i]) {devuelve falso; }}}} return true;} ISR (TIMER1_COMPA_vect) {// cambia el 0 a 1 para timer1 y 2 para timer2 LEDRefresh ();} void LEDRefresh () {int i; int k; ////////////////////////////////////////////////// // Solde mal los pines. (12345670 en lugar de 01234567). // por lo que esta parte del código es para corregir este problema mediante software. tmpdisp booleano [8] [16]; para (k =0; k <16; k ++) {para (i =1; i <8; i ++) {tmpdisp [i] [k] =disp [i-1] [k]; } tmpdisp [0] [k] =disp [7] [k]; } //////////////////////////////////////////////// para (i =0; i <8; i ++) {int j; si (i ==0) j =rowPin + 7; si no j =rowPin + i-1; byte superior =0; int b; para (b =0; b <8; b ++) {superior <<=1; if (! tmpdisp [b] [i]) superior | =1; } byte inferior =0; para (b =0; b <8; b ++) {inferior <<=1; si (! tmpdisp [b] [i + 8]) inferior | =1; } escritura digital (j, BAJA); digitalWrite (latchPin, LOW); shiftOut (dataPin, clockPin, LSBFIRST, inferior); shiftOut (dataPin, clockPin, LSBFIRST, superior); digitalWrite (latchPin, HIGH); digitalWrite (rowPin + i, HIGH); retraso (1); } digitalWrite (rowPin + 7, LOW); }
Esquemas
Proceso de manufactura
- Juego de giroscopio Arduino con MPU-6050
- Dados digitales Arduino
- Televisión casera B-Gone
- Controlador de juego Arduino
- Juego Arduino Pong en Matrix 24x16 con MAX7219
- Pixel Chaser Game
- Reloj Flip Arduino de matriz de un solo LED
- NeoMatrix Arduino Pong
- Contador Geiger de mano con Arduino Nano
- Juego DIY Arduino 1D Pong con tira de LED WS2812
- Nunca viaje solo