프로젝트

나도 메이커! 메이커스 여러분들의 작품/프로젝트를 공유하는 공간입니다.

터치패드와 LED matrix를 이용하여 간단한 게임을 만들어 보자

2014-09-05 15:47:46

개요

개요

픽셀을 사용하는 게임들은 80-90년도에 테트리스를 비롯하여 많이 출시 되었고 컴퓨터 출시 이후, 거의 사장되었지만 프로그래밍 언어를 이해하고 있고 게임의 원리만 알고 있다면 쉽게 코드를 작성하여 완성할 수 있는 괜찮은 프로젝트 주제들이다.





이번에는 터치패드와 LEDmatrix를 이용하여 아두이노와 땅싸움을 하는 게임을 만들어 보자.
사용자는 터치패드를 문질러서 LEDmatrix의 픽셀을 초록색으로 변환하고 아두이노는 픽셀을 빨간색으로 변환시킨다.
약 10초가 지나게 되면 남아 있는 픽셀의 색깔을 체크하여 많은 쪽이 이기게 된다.



동영상




필요한 사전지식

터치패드
8x8LEDmatrix




부품 목록

NO 부품명 수량 상세정보
1 아두이노 보드 1  
2 브레드보드 1  
3 8x8 LEDmatrix 1  
4 좌표 터치 센서 1  
5 케이블 10  


부품명 아두이노 보드 브레드보드 8x8 LEDmatrix 좌표 터치 센서 케이블
부품사진

하드웨어 making

브레드 보드




전자 회로도

소프트웨어 coding

#include <Wire.h>
#include <mpr121.h>
#include <swRTC.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"

Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();

int x, y;
int difficultie = 15; //난이도 변수
int randomX, randomY;
int redScore, greenScore = 0;
int nowSecond = 0;
swRTC rtc;
int score[8][8];

//초기화하는 함수
//swRTC와 점수를 초기화 시키며 초기화 후에 게임 시작을 위해 Start를 준비한다 void initialize() { redScore = 0; greenScore = 0; rtc.stopRTC(); rtc.setTime(0,0,0); //시간, 분, 초 초기화 rtc.startRTC(); delay(1000);
//시작전 텍스트 출력 matrix.setTextSize(1); matrix.setTextColor(LED_RED); matrix.setCursor(1,0); matrix.clear(); matrix.print("3"); matrix.writeDisplay(); delay(1000); matrix.clear(); matrix.setCursor(1,0); matrix.print("2"); matrix.writeDisplay(); delay(1000); matrix.clear(); matrix.setCursor(1,0); matrix.print("1"); matrix.writeDisplay(); delay(1000); Serial.println("Start!!"); matrix.clear(); matrix.writeDisplay(); }
//8x8배열 초기화 void initialize_array(int arr[][8]) { for(int i = 0; i<8; i++) { for(int j = 0; j<8; j++) { arr[i][j] = 3; } } } void setup() { Serial.begin(9600); Serial.println("8x8 LED Matrix Game"); Wire.begin(); CapaTouch.begin(); //터치패드 초기화 matrix.begin(0x70); //LEDmatrix 초기화 initialize_array(score); initialize(); } void loop() { while(true) { while(nowSecond <= 15) { //15초가 흐르지 않았다면 게임 계속 진행 nowSecond = rtc.getSeconds();
//아두이노는 랜덤숫자를 받아서 matrix에 랜덤한 위치를 빨간색으로 바꾸게 된다
//빨간색으로 칠해진 픽셀은 2차원 배열에서 1로 세팅된다. randomX = random(8); randomY = random(8); score[randomX][randomY] = 1; matrix.drawPixel(randomX, randomY, LED_RED); matrix.writeDisplay();
//사용자가 matrix를 칠하는 부분
//터치패드에서 받아온 좌표값에 해당하는 위치의 픽셀을 녹색으로 바꾼다
//사용자가 칠한 픽셀은 2차원 배열에서 0으로 세팅된다. for(int i = 0; i < difficultie; i++) { x = CapaTouch.getX(); y = CapaTouch.getY(); if(x != -1 && y != -1) { matrix.drawPixel(x-1, y-1, LED_GREEN); score[x-1][y-1] = 0; } matrix.writeDisplay(); delay(10); }
//15초가 지나면 2차원 배열의 값으로 점수를 계산하고 출력한다 if(nowSecond == 15) { for(int i = 0; i<8; i++) { for(int j = 0; j<8; j++) { if(score[i][j] == 0) greenScore += 1; else if(score[i][j] == 1) redScore += 1; } } Serial.print("green score is "); Serial.println(greenScore); Serial.print("red score is "); Serial.println(redScore);
//빨간색이 많으면 LED를 빨간색으로 채우고 녹색이 많으면 LED를 녹색으로 채운다 if(greenScore > redScore) { Serial.println("Greenteam win!"); matrix.fillRect(0,0, 8,8, LED_GREEN); } else if(greenScore < redScore) { Serial.println("GAME OVER. Redteam win!"); matrix.fillRect(0,0, 8,8, LED_RED); } delay(1000); } } //게임이 끝난 후 왼쪽 아래를 누르게 되면 난이도를 한 단계 올려서 시작한다 if(CapaTouch.getX()<=2 && 12<= CapaTouch.getY()) { Serial.println("difficultie UP!"); difficultie--; Serial.print("stage is "); Serial.println(abs(difficultie-15)); initialize(); initialize_array(score); nowSecond = rtc.getSeconds(); } //게임이 끝난 후 오른쪽 아래를 누르게 되면 이번 난이도를 다시 플레이한다 else if(CapaTouch.getX()>=8 && 12<= CapaTouch.getY()) { Serial.println("Retry. cheer up!"); Serial.print("stage is "); Serial.println(abs(difficultie-15)); initialize(); initialize_array(score); nowSecond = rtc.getSeconds(); } } }

이번 프로젝트에서 중요한 역할은 터치패드에서 값을 받아서 아두이노를 통해 8x8 LEDmatrix로 값을 전송하는 것과 랜덤값을 받아 8x8 LEDmatrix에 랜덤한 위치에 색을 뿌려주는 것과 8x8의 2차원 배열을 생성하는 것이다.

터치패드와 8x8 LEDmatrix모두 아날로그 4번핀과 5번핀을 사용하여 I2C통신을 하게 되는데 두 선을 공유하여 A4와 A5에 꽂아도 각각의 주소가 있기 때문에 잘 돌아간다.
http://playground.arduino.cc/Main/I2cScanner# <- 링크 참조

void initialize_array(int arr[][8]) {
  for(int i = 0; i<8; i++) {
    for(int j = 0; j<8; j++) {
      arr[i][j] = 3;
    }
  } 
}
8x8 LEDmatrix는 각각의 픽셀의 색깔 정보를 가지고 있지 않기 때문에 사용자가 하나하나 체크해 주어야 한다. 그렇기 때문에 8x8LEDmatrix와 동일한 크기의 8x8의 2차원 배열을 생성하여 기본값을 세팅하여 초기화 하고 예를들어 빨간색일 경우에는 1 녹색일 경우에는 0으로 그 위치에 해당하는 배열을 바꿔준다면 쉽게 LEDmatrix의 픽셀을 제어할 수 있다.
함수에서는 2차원 배열을 인자값으로 인식하지 못하기 때문에 함수를 작성할 때는 위와 같이 하나는 []이렇게 작성하고 하나는 [8]로 작성하여 준다.

randomX = random(8);
randomY = random(8);
score[randomX][randomY] = 1;
matrix.drawPixel(randomX, randomY, LED_RED); 
matrix.writeDisplay();
컴퓨터는 랜덤한 위치에 빨간색을 뿌려주기 때문에 0부터 7까지의 값을 랜덤하게 받아서 matrix위에 빨간색으로 하나하나씩 바꿔준다.

for(int i = 0; i < difficultie; i++) {
   x = CapaTouch.getX();        
   y = CapaTouch.getY();
   if(x != -1 && y != -1) {
     matrix.drawPixel(x-1, y-1, LED_GREEN); 
     score[x-1][y-1] = 0; 
   }
     matrix.writeDisplay();
     delay(10);
}
사용자가 터치한 부분을 터치패드에서 좌표값을 받아와서 그 위치에 해당하는 matrix상의 픽셀을 녹색으로 바꾸는 부분이다. 녹색으로 바꿔주게 되면 2차원 배열 score[][]에서는 그 위치에 해당하는 값을 0으로 채운다.
for문을 돌리는 이유는 스케치상의 loop문은 터치패드가 터치를 인식하여 값을 전해주는 속도보다 훨씬 빠르기 때문에 for문을 통해 컴퓨터와의 속도를 어느정도 맞춰준다. for문의 변수를 통해 난이도를 제어 할 수 있다.

for(int i = 0; i<8; i++) {
  for(int j = 0; j<8; j++) {
    if(score[i][j] == 0)
      greenScore += 1;
    else if(score[i][j] == 1)
      redScore += 1;
  }
}
일정 시간이 지나면 생성한 2차원 배열을 통해 전체 스코어를 계산하게 된다. 2차원 배열에서 각각 색마다의 특정 값을 부여했기 때문에 그 값을 합하면 그 색이 matrix상에서 얼마나 차지했는지 알 수 있게 된다. 
계산이 끝나면 greenScore와 redScore를 비교하여 어느쪽이 더 많이 차지 했는지 알 수 있다.



수박쨈

아두이노, 터치패드, 8x8 LEDmatrix, I2C통신, swRTC