이 프로젝트 정보
집에서 만든 16x8 LED 매트릭스, Arduino Nano 및 2개의 74hc595 시프트 레지스터로 이 테트리스 게임을 만들었습니다. 아무 버튼이나 누를 때 삐 소리가 나는 것도 추가했습니다.
섹션> <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드"> 코드
<울> 코드
코드Arduino
/*작성자:배재영 UBC ECE jocker.tistory.com 날짜:2013년 1월 18일 파일:Tetris v2Changelog:v2:게임오버 시 점수 표시 목적:킬링타임.. + 재미를 위한 회로+핀:Led Matrix:2 74HC575 순서대로 레지스터 이동:녹색, 파란색, 빨간색 핀:래치 =3 클록 =2 데이터 =4 행 양극 =두 매트릭스 버튼 간에 공유되는 5 ~ 13(8핀)(디지털):A4 =왼쪽 A5 =아래쪽 A6 =오른쪽 A7 =up (rotate) 코멘트:이것은 저의 두 번째 Arduino 프로젝트입니다. 코드가 지저분하고 비효율적일 수 있습니다. Arduino 라이브러리 및 데이터시트의 참조.*/unsigned char latchPin =3, unsigned char clockPin =2, unsigned char dataPin =4, unsigned char rowPin =5, 긴 지연 =0, 짧은 지연_ =500, 긴 bdelay =0, 짧은 버튼 지연 =150, 짧은 btdowndelay =30, 짧은 btsidedelay =80, unsigned char blocktype, unsigned char blockrotation, int lines =0, boolean block[8][18]; //회전을 위한 추가 2개boolean pile[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; 정수 시드 =(analogRead(0)+1)* (analogRead(1)+1)* (analogRead(2)+1)* (analogRead(3)+1); randomSeed(시드); 랜덤(10,9610806); 시드 =시드 *random(3336,15679912)+analogRead(random(4)); randomSeed(시드); 랜덤(10,98046); cli();//인터럽트 중지//2kHz에서 타이머0 인터럽트 설정 TCCR1A =0;// 전체 TCCR0A 레지스터를 0으로 설정 TCCR1B =0;// TCCR0B와 동일 TCNT1 =0;//카운터 값을 0으로 초기화 // 설정 2khz 증분에 대한 비교 일치 레지스터 OCR1A =259;// =(16*10^6) / (2000*64) - 1 (<256이어야 함) // CTC 모드 켜기 TCCR1A |=(1 <0;i--) { for (j=0;j<16;j++) { block[i][j]=block[i-1][j]; } } for (j=0;j<16;j++) { 블록[0][j]=0; } 업데이트LED(); 반환 1; } return 0;}int readBut(){ if (bdelay> millis()) { return 0; } if (analogRead(A4)> 500) { //왼쪽 bdelay =millis() + btsidedelay; 반환 3; } if (analogRead(A5)> 500) { //다운 bdelay =millis() + btdowndelay; 반환 4; } if (analogRead(A6)> 500) { //오른쪽 bdelay =millis() + btsidedelay; 반환 2; } if (analogRead(A7)> 500) { //업 bdelay =millis() + buttondelay; 반환 1; } 반환 0;} 무효 updateLED(){ int i; 정수 j; for (i=0;i<8;i++) { for (j=0;j<16;j++) { disp[i][j] =블록[i][j] | 더미[i][j]; } }}void 회전(){ //정사각형 블록(3) 건너뛰기 if (blocktype ==3) return; 정수 x; 정수이; 정수 나; 정수 j; // 왼쪽 감지 for (i=7;i>=0;i--) { for (j=0;j<16;j++) { if (block[i][j]) { xi =i; } } } //(i=15;i>=0;i--) { for (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 if (!space_right()) { if (space_left3()) { if (!moveleft()) return; if (! moveleft()) 반환; xi--; xi--; } 그렇지 않으면 반환; } else if (!space_right2()) { if (space_left2()) { if (!moveleft()) return; xi--; } 그렇지 않으면 반환; } 블록[xi][yi]=0; 블록[xi][yi+2]=0; 블록[xi][yi+3]=0; 블록[xi-1][yi+1]=1; 블록[xi+1][yi+1]=1; 블록[xi+2][yi+1]=1; 블록 회전 =1; } else { 블록[xi][yi]=0; 블록[xi+2][yi]=0; 블록[xi+3][yi]=0; 블록[xi+1][yi-1]=1; 블록[xi+1][yi+1]=1; 블록[xi+1][yi+2]=1; 블록 회전 =0; } } //가운데 xi로 오프셋 ++; 이 ++; if (블록 유형 ==1) { if (블록 회전 ==0) { 블록[xi-1][yi-1] =0; 블록[xi-1][yi] =0; 블록[xi+1][yi] =0; 블록[xi][yi-1] =1; 블록[xi+1][yi-1] =1; 블록[xi][yi+1] =1; 블록 회전 =1; } else if (blockrotation ==1) { if (!space_left()) { if (!moveright()) return; xi++; } xi--; 블록[xi][yi-1] =0; 블록[xi+1][yi-1] =0; 블록[xi][yi+1] =0; 블록[xi-1][yi] =1; 블록[xi+1][yi] =1; 블록[xi+1][yi+1] =1; 블록 회전 =2; } else if (블록 회전 ==2) { yi --; 블록[xi-1][yi] =0; 블록[xi+1][yi] =0; 블록[xi+1][yi+1] =0; 블록[xi][yi-1] =1; 블록[xi][yi+1] =1; 블록[xi-1][yi+1] =1; 블록 회전 =3; } else { if (!space_right()) { if (!moveleft()) return; xi--; } 블록[xi][yi-1] =0; 블록[xi][yi+1] =0; 블록[xi-1][yi+1] =0; 블록[xi-1][yi-1] =1; 블록[xi-1][yi] =1; 블록[xi+1][yi] =1; 블록 회전 =0; } } if (블록 유형 ==2) { if (블록 회전 ==0) { 블록[xi+1][yi-1] =0; 블록[xi-1][yi] =0; 블록[xi+1][yi] =0; 블록[xi][yi-1] =1; 블록[xi+1][yi+1] =1; 블록[xi][yi+1] =1; 블록 회전 =1; } else if (blockrotation ==1) { if (!space_left()) { if (!moveright()) return; xi++; } xi--; 블록[xi][yi-1] =0; 블록[xi+1][yi+1] =0; 블록[xi][yi+1] =0; 블록[xi-1][yi] =1; 블록[xi+1][yi] =1; 블록[xi-1][yi+1] =1; 블록 회전 =2; } else if (블록 회전 ==2) { yi --; 블록[xi-1][yi] =0; 블록[xi+1][yi] =0; 블록[xi-1][yi+1] =0; 블록[xi][yi-1] =1; 블록[xi][yi+1] =1; 블록[xi-1][yi-1] =1; 블록 회전 =3; } else { if (!space_right()) { if (!moveleft()) return; xi--; } 블록[xi][yi-1] =0; 블록[xi][yi+1] =0; 블록[xi-1][yi-1] =0; 블록[xi+1][yi-1] =1; 블록[xi-1][yi] =1; 블록[xi+1][yi] =1; 블록 회전 =0; } } if (블록 유형 ==4) { if (블록 회전 ==0) { 블록[xi+1][yi-1] =0; 블록[xi-1][yi] =0; 블록[xi+1][yi] =1; 블록[xi+1][yi+1] =1; 블록 회전 =1; } else { if (!space_left()) { if (!moveright()) return; xi++; } xi--; 블록[xi+1][yi] =0; 블록[xi+1][yi+1] =0; 블록[xi-1][yi] =1; 블록[xi+1][yi-1] =1; 블록 회전 =0; } } if (블록 유형 ==5) { if (블록 회전 ==0) { 블록[xi][yi-1] =0; 블록[xi-1][yi] =0; 블록[xi+1][yi] =0; 블록[xi][yi-1] =1; 블록[xi+1][yi] =1; 블록[xi][yi+1] =1; 블록 회전 =1; } else if (blockrotation ==1) { if (!space_left()) { if (!moveright()) return; xi++; } xi--; 블록[xi][yi-1] =0; 블록[xi+1][yi] =0; 블록[xi][yi+1] =0; 블록[xi-1][yi] =1; 블록[xi+1][yi] =1; 블록[xi][yi+1] =1; 블록 회전 =2; } else if (블록 회전 ==2) { yi --; 블록[xi-1][yi] =0; 블록[xi+1][yi] =0; 블록[xi][yi+1] =0; 블록[xi][yi-1] =1; 블록[xi-1][yi] =1; 블록[xi][yi+1] =1; 블록 회전 =3; } else { if (!space_right()) { if (!moveleft()) return; xi--; } 블록[xi][yi-1] =0; 블록[xi-1][yi] =0; 블록[xi][yi+1] =0; 블록[xi][yi-1] =1; 블록[xi-1][yi] =1; 블록[xi+1][yi] =1; 블록 회전 =0; } } if (블록 유형 ==6) { if (블록 회전 ==0) { 블록[xi-1][yi-1] =0; 블록[xi][yi-1] =0; 블록[xi+1][yi-1] =1; 블록[xi][yi+1] =1; 블록 회전 =1; } else { if (!space_left()) { if (!moveright()) return; xi++; } xi--; 블록[xi+1][yi-1] =0; 블록[xi][yi+1] =0; 블록[xi-1][yi-1] =1; 블록[xi][yi-1] =1; 블록 회전 =0; } } //만든 블록과 더미가 겹치면 회전하면서 행을 위로 올립니다. while (!check_overlap()) { for (i=0;i<18;i++) { for (j=0;j<8;j++) { block [j][i] =블록[j][i+1]; } } 지연 =millis() + delay_; } 업데이트LED(); }void movedown(){ if (space_below()) { //아래로 이동 int i; for (i=15;i>=0;i--) { int j; for (j=0;j<8;j++) { 블록[j][i] =블록[j][i-1]; } } for (i=0;i<7;i++) { 블록[i][0] =0; } } else { // 병합 및 새 블록 int i; 정수 j; for (i=0;i<8;i++) { for(j=0;j<16;j++) { if (block[i][j]) { 말뚝[i][j]=1; 블록[i][j]=0; } } } newBlock(); } 업데이트LED(); }부울 check_overlap(){ int i; 정수 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; } } } 반환 true;} 무효 check_gameover(){ int i; 정수 j; 정수 cnt=0;; for(i=15;i>=0;i--) { cnt=0; for (j=0;j<8;j++) { if (pile[j][i]) { cnt ++; } } if (cnt ==8) { lines++; for (j=0;j<8;j++) { 말뚝[j][i]=0; } 업데이트LED(); 지연(50); 정수 k; for(k=i;k>0;k--) { for (j=0;j<8;j++) { 말뚝[j][k] =말뚝[j][k-1]; } } for (j=0;j<8;j++) { 더미[j][0] =0; } 업데이트LED(); 지연(50); 나는 ++; } } for(i=0;i<8;i++) { if (pile[i][0]) gameover(); } 반환;} 무효 gameover(){ int i; 정수 j; // 블라인드 닫기 for (i=0;i<8;i++) { for (j=0;j<16;j++) { if (j%2) { disp[i][j]=1; } else { disp[7-i][j]=1; } } 지연(60); } // 스코어 보드 계산 int num_lines; num_lines =2; 부울 점수[8][17]; for (i=0;i<8;i++) { for (j=0;j<16;j++) { 점수[i][j] =0; } } 정수 숫자1 =(줄/10) % 10; int digit2 =(줄) % 10; for (i=0;i<5;i++) for (j=0;j<8;j++) { score[7-j][i+3] =lib[digit1][i][j]; } for (i=0;i<5;i++) for (j=0;j<8;j++) { score[7-j][i+9] =lib[digit2][i][j]; } for (i=0;i<16;i++) { 점수[0][i]=0; } // 오픈 블라인드 점수 for (i=0;i<8;i++) { for (j=0;j<16;j++) { if (j%2) { disp[i][j]=score[ 나][j]; } else { disp[7-i][j]=점수[7-i][j]; } } 지연(60); } 지연(100); while(true) { for (i=0;i<8;i++) { for (j=0;j<16;j++) { disp[i][j] =점수[i][j]; } } 부울 템플릿[8]; for (i=0;i<8;i++) { 점수[i][16]=점수[i][0]; } for (i=0;i<8;i++) { for (j=0;j<16;j++) { 점수[i][j] =점수[i][j+1]; } } 지연(100); } } 무효 newBlock(){ check_gameover(); 블록 유형 =무작위(7); if (블록 유형 ==0) // 0 // 0 // 0 // 0 { 블록[3][0]=1; 블록[3][1]=1; 블록[3][2]=1; 블록[3][3]=1; } if (블록 유형 ==1) // 0 // 0 0 0 { 블록[2][0]=1; 블록[2][1]=1; 블록[3][1]=1; 블록[4][1]=1; } if (블록 유형 ==2) // 0 // 0 0 0 { 블록[4][0]=1; 블록[2][1]=1; 블록[3][1]=1; 블록[4][1]=1; } if (블록 유형 ==3) // 0 0 // 0 0 { 블록[3][0]=1; 블록[3][1]=1; 블록[4][0]=1; 블록[4][1]=1; } if (블록 유형 ==4) // 0 0 // 0 0 { 블록[4][0]=1; 블록[5][0]=1; 블록[3][1]=1; 블록[4][1]=1; } if (블록 유형 ==5) // 0 // 0 0 0 { 블록[4][0]=1; 블록[3][1]=1; 블록[4][1]=1; 블록[5][1]=1; } if (블록 유형 ==6) // 0 0 // 0 0 { 블록[3][0]=1; 블록[4][0]=1; 블록[4][1]=1; 블록[5][1]=1; } 블록 회전 =0;}부울 space_below(){ int i; 정수 j; for (i=15;i>=0;i--) { for (j=0;j<8;j++) { if (block[j][i]) { if (i ==15) return false; if (pile[j][i+1]) { false를 반환합니다. } } } } 반환 true;}부울 space_left2(){ int i; 정수 j; for (i=15;i>=0;i--) { for (j=0;j<8;j++) { if (block[j][i]) { if (j ==0 || j ==1) 거짓을 반환합니다. if (말뚝[j-1][i] | 말뚝[j-2][i]) { false를 반환합니다. } } } } 반환 true;}부울 space_left3(){ int i; 정수 j; for (i=15;i>=0;i--) { for (j=0;j<8;j++) { if (block[j][i]) { if (j ==0 || j ==1 ||j ==2 ) false를 반환합니다. if (말뚝[j-1][i] | 말뚝[j-2][i]|말뚝[j-3][i]) { false를 반환합니다. } } } } 반환 true;}부울 space_left(){ int i; 정수 j; for (i=15;i>=0;i--) { for (j=0;j<8;j++) { if (block[j][i]) { if (j ==0) return false; if (pile[j-1][i]) { false를 반환합니다. } } } } 반환 true;}부울 space_right(){ int i; 정수 j; for (i=15;i>=0;i--) { for (j=0;j<8;j++) { if (block[j][i]) { if (j ==7) return false; if (pile[j+1][i]) { false를 반환합니다. } } } } 반환 true;}부울 space_right3(){ int i; 정수 j; for (i=15;i>=0;i--) { for (j=0;j<8;j++) { if (block[j][i]) { if (j ==7||j ==6||j ==5) false를 반환합니다. if (말뚝[j+1][i] |말뚝[j+2][i] | 말뚝[j+3][i]) { false를 반환합니다. } } } } 반환 true;}부울 space_right2(){ int i; 정수 j; for (i=15;i>=0;i--) { for (j=0;j<8;j++) { if (block[j][i]) { if (j ==7 || j ==6) 거짓을 반환합니다. if (pile[j+1][i] |pile[j+2][i]) { return false; } } } } return true;}ISR(TIMER1_COMPA_vect){ // timer1의 경우 0, timer2의 경우 2로 변경 LEDRefresh();}void LEDRefresh(){ int i; 정수 k; //////////////////////////////////////////////////// // 핀을 잘못 납땜했습니다. (01234567 대신 12345670). // 따라서 이 코드 부분은 이 문제를 소프트웨어로 수정하기 위한 것입니다. 부울 tmpdisp[8][16]; for (k=0;k<16;k++) { for(i=1;i<8;i++) { tmpdisp[i][k]=disp[i-1][k]; } tmpdisp[0][k]=disp[7][k]; } ///////////////////////////////////////////////// for(i =0;i<8;i++) { 정수 j; if (i ==0) j =rowPin+7; 그렇지 않으면 j =rowPin+i-1; 바이트 상위 =0; 정수 b; for(b =0;b<8;b++) { 위 <<=1; if (!tmpdisp[b][i]) 위 |=1; } 하위 바이트 =0; for(b =0;b<8;b++) { 아래 <<=1; if (!tmpdisp[b][i+8]) 더 낮은 |=1; } 디지털 쓰기(j,LOW); digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, 하위); shiftOut(dataPin, clockPin, LSBFIRST, 상위); digitalWrite(래치핀, 높음); digitalWrite(rowPin+i,HIGH); 지연(1); } 디지털 쓰기(rowPin+7,LOW); }
섹션> 회로도