Jogo Arduino Nano Tetris em Matriz 16x8 caseira
Componentes e suprimentos
| | × | 1 | |
| SparkFun Botão de pressão 12 mm | | × | 4 | |
| Texas Instruments Shift Register- Serial to Parallel | | × | 2 | |
| | × | 1 | |
| | × | 128 | |
Aplicativos e serviços online
Sobre este projeto
Construí este jogo de tetris com matriz de LED 16x8 caseira, Arduino Nano e dois registradores de deslocamento 74hc595. Eu também adicionei um som de bipe quando você pressiona qualquer botão.
Código
código Arduino
/ * Autor:Jae Yeong Bae UBC ECE jocker.tistory.com Data:18 de janeiro de 2013 Arquivo:Tetris v2Changelog:v2:exibe pontuação no gameover Objetivo:matar o tempo .. + para se divertir Circuitos + Pins:Led Matrix:2 74HC575 Shift registra em ordem:pinos verdes, azuis, vermelhos:trava =3 Relógio =2 dados =4 anodos de linha =5 a 13 (8pins) compartilhados entre os dois botões de matriz (como digital):A4 =esquerdo A5 =baixo A6 =direito A7 =up (rotate) Comentário:Este é meu segundo projeto Arduino. O código pode ser confuso e ineficiente. Referências da biblioteca Arduino e planilhas de dados. * / 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 curto =30; btsidedelay curto =80; tipo de bloco de caracteres sem sinal; rotação de bloco de caracteres sem sinal; linhas internas =0; bloco booleano [8] [18]; // 2 extras para rotação pilha 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; semente int =(analogRead (0) +1) * (analogRead (1) +1) * (analogRead (2) +1) * (analogRead (3) +1); randomSeed (seed); aleatório (10,9610806); seed =seed * random (3336,15679912) + analogRead (random (4)); randomSeed (seed); aleatório (10.98046); cli (); // parar as interrupções // definir a interrupção do timer0 em 2kHz TCCR1A =0; // definir todo o registro TCCR0A para 0 TCCR1B =0; // o mesmo para TCCR0B TCNT1 =0; // inicializar o valor do contador para 0 // definir comparar o registro de correspondência para incrementos de 2 khz OCR1A =259; // =(16 * 10 ^ 6) / (2000 * 64) - 1 (deve ser <256) // ativar o modo CTC TCCR1A | =(1 < 0; i--) {para (j =0; j <16; j ++) {bloco [i] [j] =bloco [i-1] [j]; }} para (j =0; j <16; j ++) {bloco [0] [j] =0; } updateLED (); return 1; } return 0;} int readBut () {if (bdelay> millis ()) {return 0; } if (analogRead (A4)> 500) {// left bdelay =millis () + btsidedelay; return 3; } if (analogRead (A5)> 500) {// down bdelay =millis () + btdowndelay; return 4; } if (analogRead (A6)> 500) {// bdelay direito =millis () + btsidedelay; return 2; } if (analogRead (A7)> 500) {// up bdelay =millis () + buttondelay; return 1; } return 0;} void updateLED () {int i; int j; for (i =0; i <8; i ++) {for (j =0; j <16; j ++) {disp [i] [j] =bloco [i] [j] | pilha [i] [j]; }}} void rotate () {// pula para o bloco quadrado (3) if (blocktype ==3) return; int xi; int yi; int i; int j; // detecta esquerda para (i =7; i> =0; i--) {para (j =0; j <16; j ++) {if (bloco [i] [j]) {xi =i; }}} // detectar para (i =15; i> =0; i--) {para (j =0; j <8; j ++) {if (bloco [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; } bloco [xi] [yi] =0; bloco [xi] [yi + 2] =0; bloco [xi] [yi + 3] =0; bloco [xi-1] [yi + 1] =1; bloco [xi + 1] [yi + 1] =1; bloco [xi + 2] [yi + 1] =1; rotação em bloco =1; } else {bloco [xi] [yi] =0; bloco [xi + 2] [yi] =0; bloco [xi + 3] [yi] =0; bloco [xi + 1] [yi-1] =1; bloco [xi + 1] [yi + 1] =1; bloco [xi + 1] [yi + 2] =1; rotação de bloco =0; }} // deslocamento para o meio xi ++; yi ++; if (blocktype ==1) {if (blockrotation ==0) {block [xi-1] [yi-1] =0; bloco [xi-1] [yi] =0; bloco [xi + 1] [yi] =0; bloco [xi] [yi-1] =1; bloco [xi + 1] [yi-1] =1; bloco [xi] [yi + 1] =1; rotação em bloco =1; } else if (blockrotation ==1) {if (! space_left ()) {if (! moveright ()) return; xi ++; } XI--; bloco [xi] [yi-1] =0; bloco [xi + 1] [yi-1] =0; bloco [xi] [yi + 1] =0; bloco [xi-1] [yi] =1; bloco [xi + 1] [yi] =1; bloco [xi + 1] [yi + 1] =1; rotação em bloco =2; } else if (blockrotation ==2) {yi -; bloco [xi-1] [yi] =0; bloco [xi + 1] [yi] =0; bloco [xi + 1] [yi + 1] =0; bloco [xi] [yi-1] =1; bloco [xi] [yi + 1] =1; bloco [xi-1] [yi + 1] =1; rotação em bloco =3; } else {if (! space_right ()) {if (! moveleft ()) return; XI--; } bloco [xi] [yi-1] =0; bloco [xi] [yi + 1] =0; bloco [xi-1] [yi + 1] =0; bloco [xi-1] [yi-1] =1; bloco [xi-1] [yi] =1; bloco [xi + 1] [yi] =1; rotação de bloco =0; }} if (blocktype ==2) {if (blockrotation ==0) {block [xi + 1] [yi-1] =0; bloco [xi-1] [yi] =0; bloco [xi + 1] [yi] =0; bloco [xi] [yi-1] =1; bloco [xi + 1] [yi + 1] =1; bloco [xi] [yi + 1] =1; rotação em bloco =1; } else if (blockrotation ==1) {if (! space_left ()) {if (! moveright ()) return; xi ++; } XI--; bloco [xi] [yi-1] =0; bloco [xi + 1] [yi + 1] =0; bloco [xi] [yi + 1] =0; bloco [xi-1] [yi] =1; bloco [xi + 1] [yi] =1; bloco [xi-1] [yi + 1] =1; rotação em bloco =2; } else if (blockrotation ==2) {yi -; bloco [xi-1] [yi] =0; bloco [xi + 1] [yi] =0; bloco [xi-1] [yi + 1] =0; bloco [xi] [yi-1] =1; bloco [xi] [yi + 1] =1; bloco [xi-1] [yi-1] =1; rotação em bloco =3; } else {if (! space_right ()) {if (! moveleft ()) return; XI--; } bloco [xi] [yi-1] =0; bloco [xi] [yi + 1] =0; bloco [xi-1] [yi-1] =0; bloco [xi + 1] [yi-1] =1; bloco [xi-1] [yi] =1; bloco [xi + 1] [yi] =1; rotação de bloco =0; }} if (blocktype ==4) {if (blockrotation ==0) {block [xi + 1] [yi-1] =0; bloco [xi-1] [yi] =0; bloco [xi + 1] [yi] =1; bloco [xi + 1] [yi + 1] =1; rotação em bloco =1; } else {if (! space_left ()) {if (! moveright ()) return; xi ++; } XI--; bloco [xi + 1] [yi] =0; bloco [xi + 1] [yi + 1] =0; bloco [xi-1] [yi] =1; bloco [xi + 1] [yi-1] =1; rotação de bloco =0; }} if (blocktype ==5) {if (blockrotation ==0) {block [xi] [yi-1] =0; bloco [xi-1] [yi] =0; bloco [xi + 1] [yi] =0; bloco [xi] [yi-1] =1; bloco [xi + 1] [yi] =1; bloco [xi] [yi + 1] =1; rotação em bloco =1; } else if (blockrotation ==1) {if (! space_left ()) {if (! moveright ()) return; xi ++; } XI--; bloco [xi] [yi-1] =0; bloco [xi + 1] [yi] =0; bloco [xi] [yi + 1] =0; bloco [xi-1] [yi] =1; bloco [xi + 1] [yi] =1; bloco [xi] [yi + 1] =1; rotação em bloco =2; } else if (blockrotation ==2) {yi -; bloco [xi-1] [yi] =0; bloco [xi + 1] [yi] =0; bloco [xi] [yi + 1] =0; bloco [xi] [yi-1] =1; bloco [xi-1] [yi] =1; bloco [xi] [yi + 1] =1; rotação em bloco =3; } else {if (! space_right ()) {if (! moveleft ()) return; XI--; } bloco [xi] [yi-1] =0; bloco [xi-1] [yi] =0; bloco [xi] [yi + 1] =0; bloco [xi] [yi-1] =1; bloco [xi-1] [yi] =1; bloco [xi + 1] [yi] =1; rotação de bloco =0; }} if (blocktype ==6) {if (blockrotation ==0) {block [xi-1] [yi-1] =0; bloco [xi] [yi-1] =0; bloco [xi + 1] [yi-1] =1; bloco [xi] [yi + 1] =1; rotação em bloco =1; } else {if (! space_left ()) {if (! moveright ()) return; xi ++; } XI--; bloco [xi + 1] [yi-1] =0; bloco [xi] [yi + 1] =0; bloco [xi-1] [yi-1] =1; bloco [xi] [yi-1] =1; rotação de bloco =0; }} // se o bloco feito em rotação e a pilha se sobrepõem, empurre as linhas para cima enquanto (! check_overlap ()) {for (i =0; i <18; i ++) {for (j =0; j <8; j ++) {bloco [j] [i] =bloco [j] [i + 1]; }} atrasos =milis () + atraso_; } updateLED (); } void movedown () {if (space_below ()) {// move para baixo int i; para (i =15; i> =0; i--) {int j; para (j =0; j <8; j ++) {bloco [j] [i] =bloco [j] [i-1]; }} para (i =0; i <7; i ++) {bloco [i] [0] =0; }} else {// mescla e novo bloco int i; int j; para (i =0; i <8; i ++) {para (j =0; j <16; j ++) {if (bloco [i] [j]) {pilha [i] [j] =1; bloco [i] [j] =0; }}} newBlock (); } updateLED (); } boolean check_overlap () {int i; int j; for (i =0; i <16; i ++) {for (j =0; j <7; j ++) {if (bloco [j] [i]) {if (pilha [j] [i]) return false; }}} for (i =16; i <18; i ++) {for (j =0; j <7; j ++) {if (bloco [j] [i]) {return false; }}} return true;} 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 (pilha [j] [i]) {cnt ++; }} if (cnt ==8) {linhas ++; para (j =0; j <8; j ++) {pilha [j] [i] =0; } updateLED (); atraso (50); int k; for (k =i; k> 0; k--) {for (j =0; j <8; j ++) {pilha [j] [k] =pilha [j] [k-1]; }} para (j =0; j <8; j ++) {pilha [j] [0] =0; } updateLED (); atraso (50); i ++; }} para (i =0; i <8; i ++) {if (pilha [i] [0]) gameover (); } return;} void gameover () {int i; int j; // fechar às cegas para (i =0; i <8; i ++) {for (j =0; j <16; j ++) {if (j% 2) {disp [i] [j] =1; } else {disp [7-i] [j] =1; }} atraso (60); } // calcula o placar int num_lines; num_lines =2; pontuação booleana [8] [17]; para (i =0; i <8; i ++) {para (j =0; j <16; j ++) {pontuação [i] [j] =0; }} int digito1 =(linhas / 10)% 10; dígito interno 2 =(linhas)% 10; para (i =0; i <5; i ++) para (j =0; j <8; j ++) {pontuação [7-j] [i + 3] =lib [dígito1] [i] [j]; } para (i =0; i <5; i ++) para (j =0; j <8; j ++) {pontuação [7-j] [i + 9] =lib [dígito2] [i] [j]; } para (i =0; i <16; i ++) {pontuação [0] [i] =0; } // abre às cegas com pontuação para (i =0; i <8; i ++) {for (j =0; j <16; j ++) {if (j% 2) {disp [i] [j] =pontuação [ eu j]; } else {disp [7-i] [j] =pontuação [7-i] [j]; }} atraso (60); } atraso (100); enquanto (verdadeiro) {para (i =0; i <8; i ++) {para (j =0; j <16; j ++) {disp [i] [j] =pontuação [i] [j]; }} tmpline boolean [8]; para (i =0; i <8; i ++) {pontuação [i] [16] =pontuação [i] [0]; } para (i =0; i <8; i ++) {para (j =0; j <16; j ++) {pontuação [i] [j] =pontuação [i] [j + 1]; }} atraso (100); }} void newBlock () {check_gameover (); tipo de bloco =aleatório (7); if (blocktype ==0) // 0 // 0 // 0 // 0 {block [3] [0] =1; bloco [3] [1] =1; bloco [3] [2] =1; bloco [3] [3] =1; } if (blocktype ==1) // 0 // 0 0 0 {block [2] [0] =1; bloco [2] [1] =1; bloco [3] [1] =1; bloco [4] [1] =1; } if (blocktype ==2) // 0 // 0 0 0 {block [4] [0] =1; bloco [2] [1] =1; bloco [3] [1] =1; bloco [4] [1] =1; } if (blocktype ==3) // 0 0 // 0 0 {block [3] [0] =1; bloco [3] [1] =1; bloco [4] [0] =1; bloco [4] [1] =1; } if (blocktype ==4) // 0 0 // 0 0 {block [4] [0] =1; bloco [5] [0] =1; bloco [3] [1] =1; bloco [4] [1] =1; } if (blocktype ==5) // 0 // 0 0 0 {block [4] [0] =1; bloco [3] [1] =1; bloco [4] [1] =1; bloco [5] [1] =1; } if (blocktype ==6) // 0 0 // 0 0 {block [3] [0] =1; bloco [4] [0] =1; bloco [4] [1] =1; bloco [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 (bloco [j] [i]) {if (i ==15) return false; if (pilha [j] [i + 1]) {return false; }}}} return true;} boolean space_left2 () {int i; int j; for (i =15; i> =0; i--) {for (j =0; j <8; j ++) {if (bloco [j] [i]) {if (j ==0 || j ==1) retorna falso; if (pilha [j-1] [i] | pilha [j-2] [i]) {retorno falso; }}}} return true;} boolean space_left3 () {int i; int j; for (i =15; i> =0; i--) {for (j =0; j <8; j ++) {if (bloco [j] [i]) {if (j ==0 || j ==1 || j ==2) retornar falso; if (pilha [j-1] [i] | pilha [j-2] [i] | pilha [j-3] [i]) {retorno falso; }}}} return true;} boolean space_left () {int i; int j; for (i =15; i> =0; i--) {for (j =0; j <8; j ++) {if (bloco [j] [i]) {if (j ==0) return false; if (pilha [j-1] [i]) {retorno falso; }}}} return true;} boolean space_right () {int i; int j; for (i =15; i> =0; i--) {for (j =0; j <8; j ++) {if (bloco [j] [i]) {if (j ==7) return false; if (pilha [j + 1] [i]) {retorno falso; }}}} return true;} boolean space_right3 () {int i; int j; for (i =15; i> =0; i--) {for (j =0; j <8; j ++) {if (bloco [j] [i]) {if (j ==7 || j ==6 || j ==5) retornar falso; if (pilha [j + 1] [i] | pilha [j + 2] [i] | pilha [j + 3] [i]) {retorno falso; }}}} return true;} boolean space_right2 () {int i; int j; for (i =15; i> =0; i--) {for (j =0; j <8; j ++) {if (bloco [j] [i]) {if (j ==7 || j ==6) retornar falso; if (pilha [j + 1] [i] | pilha [j + 2] [i]) {retorno falso; }}}} return true;} ISR (TIMER1_COMPA_vect) {// alterar 0 para 1 para timer1 e 2 para timer2 LEDRefresh ();} void LEDRefresh () {int i; int k; //////////////////////////////////////////////////// // Eu soldei os pinos errados. (12345670 em vez de 01234567). // portanto, esta parte do código deve ser corrigida pelo software. boolean tmpdisp [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]; } ////////////////////////////////////////////////// for (i =0; i <8; i ++) {int j; if (i ==0) j =rowPin + 7; senão 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; if (! tmpdisp [b] [i + 8]) inferior | =1; } digitalWrite (j, LOW); digitalWrite (latchPin, LOW); shiftOut (dataPin, clockPin, LSBFIRST, inferior); shiftOut (dataPin, clockPin, LSBFIRST, superior); digitalWrite (latchPin, HIGH); digitalWrite (rowPin + i, HIGH); atraso (1); } digitalWrite (rowPin + 7, LOW); }
Esquemas