728x90
개발 툴 : Arduino IDE
프로젝트 기간 : 5일
게임 진행도
처음 시작 했을 때
레벨 2에서 한 번 틀렸을 때
레벨 4에서 총 3번 틀렸을 때 -> 게임 오버
게임 진행 영상
진행 중 문제점
7세그먼트에서 전압을 많이 쓰다보니, 조이스틱 값이 최대치까지 오르지 않음을 확인
-> 테스트를 통해 조이스틱 움직임의 기준치를 조정하여 해결
소스코드
const int VRX = A0; //답 입력 조이스틱
const int VRY = A1;
const int SW = A2;
const int LED_U = 10; //문제, 답 출력 led 핀 번호
const int LED_R = 11;
const int LED_D = 12;
const int LED_L = 9;
const int RED = A3; // 목숨 표시 RGB led
const int GREEN = A4;
const int BLUE = A5;
const int pins[] = {2,3,4,5,6,7,8}; //세그먼트 연결
const int numberCode[15] = {
B11000000, //0 dp/gfedcba
B11111001, //1
B10100100, //2
B10110000, //3
B10011001, //4
B10010010, //5
B10000010, //6
B11011000, //7
B10000000, //8
B10010000, //9
B10001000, //A
B10000011, //b
B10100111, //c
B10100001, //E
B10001110 //F
};
#include "pitches.h"
const int buzzer = 13;
//시작 노래
int melody[] = {
NOTE_B4, 16, NOTE_B5, 16, NOTE_FS5, 16, NOTE_DS5, 16, //1
NOTE_B5, 32, NOTE_FS5, -16, NOTE_DS5, 8, NOTE_C5, 16,
NOTE_C6, 16, NOTE_G6, 16, NOTE_E6, 16, NOTE_C6, 32, NOTE_G6, -16, NOTE_E6, 8,
NOTE_B4, 16, NOTE_B5, 16, NOTE_FS5, 16, NOTE_DS5, 16, NOTE_B5, 32, //2
NOTE_FS5, -16, NOTE_DS5, 8, NOTE_DS5, 32, NOTE_E5, 32, NOTE_F5, 32,
NOTE_F5, 32, NOTE_FS5, 32, NOTE_G5, 32, NOTE_G5, 32, NOTE_GS5, 32, NOTE_A5, 16, NOTE_B5, 8
};
// 끝 노래
int melodyOver[] = {NOTE_C4, 4, NOTE_G3, 8, NOTE_G3, 8, NOTE_A3, 4, NOTE_G3, 4, REST, 4, NOTE_B3, 4, NOTE_C4, 4};
int input_cnt = 0, level = 1, lifeN = 3; //1레벨, 목숨 3개로 시작
void setup() {
pinMode(SW, INPUT_PULLUP); //스위치
pinMode(LED_U, OUTPUT); //LED
pinMode(LED_R, OUTPUT);
pinMode(LED_D, OUTPUT);
pinMode(LED_L, OUTPUT);
for (int i = 0; i < 7; i++){ //7세그먼트
pinMode(pins[i], OUTPUT);
}
pinMode(RED, OUTPUT); //RGB LED
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
randomSeed(analogRead(0));
digitalWrite(GREEN, HIGH); //시작 목숨 알림
showScore(level); //시작 level
sing(melody, 120); //시작 알림 노래
}
void loop() {
while (lifeN){
int answer[level] = {}, response[level] ={}; //레벨 당 게임 끝날 때마다 초기화
for (int i = 0; i < 2; i++){ //시작 의미로 반복
for (int j = 9; j < 13; j++){
ledOn(j, 50);
}
}
randQuestion(answer); //문제 난수 생성
inputJoy(response); //정답 입력
correctCheck(answer, response); //정답 확인
showScore(level); //레벨 확인
}
}
void ledOn(int n, int t){ //led OnOff함수
digitalWrite(n, HIGH);
delay(t); //켜진 상태로 유지
digitalWrite(n, LOW);
delay(t); //끈 상태로 유지
}
void randQuestion(int ans[]){ //문제 만들기 함수
for (int i = 0; i < level; i++){ //레벨 수만큼 문제 만들기
int seed = random(9,13); //난수 받아서 값 만들기
ans[i] = seed;
ledOn(ans[i],300); //해당 값의 LED 점등
}
}
bool isJoystickMoved(int x, int y, int z){ //조이스틱의 반응이 있는지 확인
return (x < 100 || x > 900 || y < 100 || y > 900 || z < 50);
}
void inputJoy(int resp[]){ //답 입력 함수
input_cnt = 0; //시작 시 초기화
while(input_cnt < level){ //level 수만큼 입력될 때까지 실행
int x = analogRead(VRX); //조이스틱 값
int y = analogRead(VRY);
int z = analogRead(SW);
if (isJoystickMoved(x, y, z)){ //조이스틱의 반응이 있을 경우
if (z < 50){ //스위치 누르면 재입력
input_cnt = 0;
}
else if (y < 100){
ledOn(LED_U, 300); //해당 LED 점등
resp[input_cnt] = 10; //답 배열에 해당 값 넣기
input_cnt++;
}
else if (x > 900){
ledOn(LED_R, 300);
resp[input_cnt] = 11;
input_cnt++;
}
else if (y > 900){
ledOn(LED_D, 300);
resp[input_cnt] = 12;
input_cnt++;
}
else if (x < 100){
ledOn(LED_L, 300);
resp[input_cnt] = 9;
input_cnt++;
}
}
}
}
void correctCheck(int ans[], int resp[]){ //정답과 답 일치 확인 함수
bool correct = true;
for (int i = 0; i < level; i++){ //하나라도 틀린 게 있을 경우
if (ans[i] != resp[i]) {
correct = false;
lifeN--; //목숨 하나 깎임
if(lifeN == 2){ //목숨2 = 파랑
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, HIGH);
}
else if (lifeN == 1){ //목숨1 = 자주
digitalWrite(RED, HIGH);
}
else if (lifeN == 0){ //목숨0 = 빨강
digitalWrite(BLUE, LOW);
sing(melodyOver, 180); //끝나는 노래 재생
}
break;
}
}
if (correct == true){ //틀린 게 없을 경우
level++; //다음 레벨 진행
}
}
void showScore(int num){ //num=레벨
boolean segmentBit;
for (int bitP = 0; bitP < 8; bitP++){ //세그먼트
segmentBit = bitRead(numberCode[num], bitP); //해당 레벨 세그먼트 패턴 가져와서 넣음
digitalWrite(pins[bitP], segmentBit); //세그먼트 LED 켜기
}
}
void sing(int mel[], int tem){ //멜로디 재생 함수
int notes = sizeof(melody) / sizeof(mel[0]) / 2;
int wholenote = (60000 * 4) / tem;
int divider = 0, noteDuration = 0;
for (int thisNote = 0; thisNote < notes * 2; thisNote = thisNote + 2) {
divider = mel[thisNote + 1];
if (divider > 0) {
noteDuration = (wholenote) / divider;
} else if (divider < 0) {
noteDuration = (wholenote) / abs(divider);
noteDuration *= 1.5;
}
tone(buzzer, mel[thisNote], noteDuration * 0.9);
delay(noteDuration);
noTone(buzzer);
}
}
728x90