산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

아두이노 메모리 게임 (사이먼 클론) 만들기 – 단계별 튜토리얼

부품 및 소모품

부품 수량 비고
아두이노 우노 (Arduino UNO) 1
330옴 저항 (SparkFun) 4개 4개만 필요
10k옴 저항 (SparkFun) 4개 4개만 필요
여러 색상 LED (SparkFun) 4개 서로 다른 색상 4개 필요
미니 스피커 (SparkFun) 1 소리 필요 없으면 생략 가능
브레드보드 (풀 사이즈, SparkFun) 1
점퍼 와이어 (범용) 1세트

앱 및 온라인 서비스

서비스
아두이노 IDE

프로젝트 개요

"사이먼(Simon)" 게임 기억하시나요? 70년대생인 제 또래 많은 분들이 이 게임에 시간을 많이 쏟았을 겁니다. 게임은 단순했습니다. 서로 다른 색상의 버튼 4개가 순서대로 불이 켜지면 그 순서를 따라 누르는 방식입니다. 맞출 때마다 마지막에 색상 하나가 추가돼 난이도가 올라갑니다.

어릴 적 크리스마스 선물로 받았지만 이사를 거듭하며 상자 속에 묻혀버렸죠...

"어른"이 되어 아두이노의 즐거움을 알게 되었고, 잃어버린 추억의 친구를 되살릴 기회가 생겼습니다.

이 튜토리얼에서는 아두이노 우노, 몇 개의 LED와 저항, 비교적 간단한 회로로 비슷한 게임을 만드는 방법을 보여드립니다.

프로그램 자체는 초보자에게 약간 복잡할 수 있어 코드에 상세히 주석을 달았습니다.

가장 간단한 실행 방법은 다음과 같습니다.

  1. 회로도대로 정확히 배선하세요. 전선 색상은 상관없으니 검은 선이 부족해도 괜찮습니다. :)
  2. 소스 코드를 아두이노 에디터에 붙여넣고 보드에 업로드하세요.
  3. 게임을 즐기세요!

게임은 약 3초 후 모든 LED가 5번 느리게 점멸하며 시작합니다.

아두이노 메모리 게임 (사이먼 클론) 만들기 – 단계별 튜토리얼

LED 중 하나 이상이 점멸하지 않으면 배선을 확인하세요. 제 보드에선 작은 버튼들이 제대로 안 끼워져 튀어나오곤 합니다.

배선이 맞는데도 안 되면, 작동하는 LED와 안 되는 LED를 바꿔 껴서 배선 문제인지 LED 불량인지 확인해 보세요.

5번 점멸 완료 후 LED 하나가 켜집니다. 어느 건지는 비밀입니다 :) 해당 LED의 버튼을 누르세요. 그 LED가 다시 켜지고 새로운 LED가 추가됩니다. 순서대로 올바른 버튼을 누르면 됩니다...

아두이노 메모리 게임 (사이먼 클론) 만들기 – 단계별 튜토리얼

곧 모든 LED가 빠르게 점멸합니다. 그건 패배라는 뜻이죠! :D

마지막으로 주어졌던 시퀀스가 재생돼 점수를 셀 수 있고, 다시 5번 느린 점멸과 함께 새 게임이 시작됩니다.

버튼 입력 제한 시간은 2초입니다.

자, 즐겨보세요!

더 어렵게 만들고 싶으신가요? 코드 최상단 값을 바꿔보세요:

#define PLAYER_WAIT_TIME 2000

LED를 더 추가하고 싶다면? 회로의 이 부분을 복제하세요:

아두이노 메모리 게임 (사이먼 클론) 만들기 – 단계별 튜토리얼

여기 주황색 선은 아두이노의 빈 핀에 연결하세요 (0, 1번 핀은 피하세요).

코드에서 다음 줄을 수정하세요:

byte noPins = 4 
byte pins[] = {2, 13, 10, 8};

핀 6에 LED를 추가했다면:

byte noPins = 5 
byte pins[] = {2, 13, 10, 8, 6};

아두이노 코드 작성 팁:

void setup() { 
  delay(3000); 
  Serial.begin(9600); 
  Reset(); 
}

setup() 첫 줄에 짧은 딜레이를 두세요. 아두이노가 무한 루프에 빠지거나 락업되기 쉬운데, 이 딜레이 덕분에 리셋 후 빈 스케치 업로드할 시간을 벌 수 있습니다.

이 아이디어를 발전시켜 휴대용으로도 만들었습니다...

비슷하지만 훨씬 더 진보한 게임 아이디어를 보시려면 Peter Kent의 레고 미니 메모리 게임을 확인하세요. 레고 자동차와 인터페이스한 모바일 게임으로 정말 멋집니다!

코드

메모리 게임 코드

#define PLAYER_WAIT_TIME 2000 // 버튼 간 허용 시간 - 2초 
byte sequence[100]; // 점등 시퀀스 저장 
byte curLen = 0; // 현재 시퀀스 길이 
byte inputCount = 0; // 플레이어가 올바른 버튼을 누른 횟수 (턴당) 
byte lastInput = 0; // 플레이어 마지막 입력 
byte expRd = 0; // 플레이어가 켜야 할 LED 
bool btnDwn = false; // 버튼 눌림 상태 체크 
bool wait = false; // 프로그램의 사용자 입력 대기 여부 
bool resetFlag = false; // 플레이어 패배 시 표시 
byte soundPin = 5; // 스피커 출력 핀 
byte noPins = 4; // 버튼/LED 개수 (작업 중엔 2개만 사용) 
// LED/버튼/저항 조합 추가로 난이도 올릴 수 있음 
byte pins[] = {2, 13, 10, 8}; // 버튼 입력 및 LED 출력 핀 - 다른 핀 사용 시 변경 
// 요소 개수는 noPins와 일치해야 함 
long inputTime = 0; // 사용자 입력 간격 타이머 변수 

void setup() { 
  delay(3000); // 아두이노 연결 후 숨 돌릴 시간 - 원치 않으면 제거 
  Serial.begin(9600); // 시리얼 모니터 시작 - 제거 시 아래 Serial 참조도 모두 삭제 
  Reset(); 
} 

/// 
/// 'dir' 값에 따라 모든 핀을 INPUT 또는 OUTPUT으로 설정 
/// 
void setPinDirection(byte dir){ 
  for(byte i = 0; i < noPins; i++){ 
    pinMode(pins[i], dir); 
  } 
} 

// 모든 LED 핀에 같은 값 출력 
void writeAllPins(byte val){ 
  for(byte i = 0; i < noPins; i++){ 
    digitalWrite(pins[i], val); 
  } 
} 

// (꽤 성가신) 비프음 내기 
void beep(byte freq){ 
  analogWrite(soundPin, 2); 
  delay(freq); 
  analogWrite(soundPin, 0); 
  delay(freq); 
} 

/// 
/// 모든 LED 함께 점멸 
/// freq: 점멸 속도 - 작을수록 빠름, 클수록 느림 
/// 
void flash(short freq){ 
  setPinDirection(OUTPUT); 
  for(int i = 0; i < 5; i++){ 
    writeAllPins(HIGH); 
    beep(50); 
    delay(freq); 
    writeAllPins(LOW); 
    delay(freq); 
  } 
} 

/// 
/// 모든 게임 변수 기본값으로 리셋 
/// 
void Reset(){ 
  flash(500); 
  curLen = 0; 
  inputCount = 0; 
  lastInput = 0; 
  expRd = 0; 
  btnDwn = false; 
  wait = false; 
  resetFlag = false; 
} 

/// 
/// 사용자 패배 처리 
/// 
void Lose(){ 
  flash(50); 
} 

/// 
/// 아두이노가 사용자에게 외울 시퀀스 보여주기 
/// 패배 후 마지막 시퀀스 보여줄 때도 호출 
/// 
void playSequence(){ 
  for(int i = 0; i < curLen; i++){ 
    Serial.print("Seq: "); 
    Serial.print(i); 
    Serial.print("Pin: "); 
    Serial.println(sequence[i]); 
    digitalWrite(sequence[i], HIGH); 
    delay(500); 
    digitalWrite(sequence[i], LOW); 
    delay(250); 
  } 
} 

/// 
/// 패배 시 발생하는 이벤트들 
/// 
void DoLoseProcess(){ 
  Lose(); // 모든 LED 빠른 점멸 (Lose 함수 참조) 
  delay(1000); 
  playSequence(); // 사용자에게 마지막 시퀀스 보여주기 - 최고 점수 기억용, 제 기록은 22예요 :) 
  delay(1000); 
  Reset(); // 새 게임 위해 모든 것 리셋 
} 

/// 
/// 핵심 로직 
/// 
void loop() { 
  if(!wait){ 
    //****************// 
    // 아두이노 턴 
    //****************// 
    setPinDirection(OUTPUT); // LED 사용 
    randomSeed(analogRead(A0)); // https://www.arduino.cc/en/Reference/RandomSeed 
    sequence[curLen] = pins[random(0,noPins)]; // 시퀀스 다음 위치에 랜덤 값 저장 
    curLen++; // 시퀀스 길이 증가 
    playSequence(); // 플레이어에게 시퀀스 보여주기 
    beep(50); // 플레이어 인지용 비프음 
    wait = true; // 이제 플레이어 턴 
    inputTime = millis(); // 플레이어 반응 시간 측정용 시간 저장 
  }else{ 
    //***************// 
    // 플레이어 턴 
    //***************// 
    setPinDirection(INPUT); // 버튼 사용 
    if(millis() - inputTime > PLAYER_WAIT_TIME){ 
      // 허용 시간 초과 시 
      DoLoseProcess(); // 게임 오버 
      return; 
    } 
    if(!btnDwn){ 
      expRd = sequence[inputCount]; // 플레이어 기대 입력값 
      Serial.print("Expected: "); 
      Serial.println(expRd); 
      for(int i = 0; i < noPins; i++){ 
        if(pins[i]==expRd) continue; // 정답 핀 무시 
        if(digitalRead(pins[i]) == HIGH){ // 버튼 눌림? 
          lastInput = pins[i]; 
          resetFlag = true; // 패배 플래그 
          btnDwn = true; // 중복 처리 방지 
          Serial.print("Read: "); 
          Serial.println(lastInput); 
        } 
      } 
    } 
    if(digitalRead(expRd) == 1 && !btnDwn) { // 정답 버튼 눌림 
      inputTime = millis(); 
      inputCount++; // 올바른 버튼 누름 횟수 증가 
      btnDwn = true; 
      Serial.print("Read: "); 
      Serial.println(lastInput); 
    }else{ 
      if(btnDwn && digitalRead(lastInput) == LOW){ // 버튼 떼짐 확인 
        btnDwn = false; 
        delay(20); 
        if(resetFlag){ // 위에서 true 설정됐으면 패배 
          DoLoseProcess(); 
        } else{ 
          if(inputCount == curLen){ // 시퀀스 완료? 
            wait = false; // 다음 턴은 아두이노 
            inputCount = 0; 
            delay(1500); 
          } 
        } 
      } 
    } 
  } 
}

회로도

simonsays_siKds3Jmk2.fzz

아두이노 메모리 게임 (사이먼 클론) 만들기 – 단계별 튜토리얼

제조공정

  1. 아두이노로 모니터 앰비라이트(Ambilight) 시스템 직접 만들기
  2. 아두이노 나노와 MPU-6050으로 실시간 자이로스코프 게임 만들기
  3. NeoPixel 링과 Arduino로 만드는 인터랙티브 자이로스코프 LED 디스플레이
  4. 아두이노 우노와 OLED 디스플레이로 클래식 퐁(Pong) 게임 만들기: 단계별 튜토리얼
  5. DIY 아두이노 USB 게임 컨트롤러 - 나만의 고성능 게임패드 만들기
  6. 아두이노 터치 브레이크아웃 게임: 2.4" TFT LCD로 클래식 아케이드 구현
  7. Pixie: 아두이노 기반 네오픽셀 손목시계 – 세련된 DIY LED 타임피스
  8. 픽셀 체이서: 아두이노 나노로 만든 인터랙티브 원탭 LED 게임
  9. 아두이노로 크롬 공룡 게임 자동화하기 – LDR과 파이썬으로 장애물 감지
  10. 휴대용 원격 감시 카메라 로봇 시스템