電子工作

SIMONゲームを作ってみた。(音付き)

  • 閲覧数: 1834
  • 1
  • C.120x80.e1be53c84cf4b9f1ae71542b6d31a2a4

作品説明

前回のSIMONを音付きに改良しました。
やはり、このゲームは音付きのほうが良いようです。
ついでにさまざまな機能を追加しました。
  • ゲームに負けた時に出るブ・ブーを追加
  • ゲームに勝った時の「ぱっぱぱぱん、ぱぱぱぱっぱぱぱーん」を追加
  • 最初の色をまだ押してない場合、ブブーを鳴らさないようにした。
  • 最初の問題が出た後に、青と黄色を同時に押すと音が出ないモードに出来る
現在は10回分正確に入力すると、勝てますがMOVE_TO_WINのパラメータを変更すると回数を変更することができます。

勝った時の「ぱっぱぱぱん、ぱぱぱぱっぱぱぱーん」はまだ改良の余地があります。絶対音感を持っていない私にはどのように修正すればよいのかさっぱり分かりません。分かる人がいらっしゃいましたら教えて下さい。

色に対する音はSparkfunのSIMONを参考にしましたが、米国のWikipediaに載っている音程と違うのですが・・・・・
音の名称で「ド」とか「ミ」は見慣れているのですが、「C4」とか「E4」とかは良く分からんのですよ。
もともと、音楽の授業が苦手で・・・・

あと、インクルードファイルの「pitches.h」ですが、スケッチの例>02Digital>toneMelodyに入っている「pitches.h」をコピーしてください。

レシピ


ブレッドボードイメージ

ブレッドボードイメージ

スピーカーを追加しました。


回路図です。スピーカーを追加した以外には変わりはありません。

回路図です。

スピーカーを追加した以外には変わりはありません。

スケッチはかなり変わっています。
家族や親戚の意見を取り入れ、改良しています。

#include "pitches.h"
#define  LED_RED            0
#define  LED_GREEN          1
#define  LED_BLUE           2
#define  LED_YELLOW         3
#define  FAILURE            9
#define  SPEAKER            5            
#define  LED_RED_PIN       10
#define  LED_GREEN_PIN     11
#define  LED_BLUE_PIN      12
#define  LED_YELLOW_PIN    13
#define  RELAY              4
#define  BUTTON_RED_PIN     6
#define  BUTTON_GREEN_PIN   7
#define  BUTTON_BLUE_PIN    8
#define  BUTTON_YELLOW_PIN  9
#define  TIME_LIMIT       300
#define  MOVE_TO_WIN        10  //問題の回数
#define  MARK_OF_LOST       false
#define  MARK_OF_WIN        true
#define  LED_RED_TONE       NOTE_A4
#define  LED_GREEN_TONE     NOTE_A5
#define  LED_BLUE_TONE      NOTE_D5
#define  LED_YELLOW_TONE    NOTE_G5

int moves[32];
int nmoves = 0;
int leave_counter;
boolean speaker_on_off = true;
int melody[] = { NOTE_E5, NOTE_E5,NOTE_E5, NOTE_E5, NOTE_F5, NOTE_E5, NOTE_F5,NOTE_E5, NOTE_E5,NOTE_E5, NOTE_E5};
int noteDurations[] = { 3, 5, 5, 1, 5, 5, 5, 6, 6, 6, 2};
int win_led[]={0,1,3,2};

void setup() {
  pinMode(LED_RED_PIN, OUTPUT);  
  pinMode(LED_GREEN_PIN, OUTPUT);  
  pinMode(LED_BLUE_PIN, OUTPUT);  
  pinMode(LED_YELLOW_PIN, OUTPUT);  
  pinMode(BUTTON_RED_PIN, INPUT);  
  pinMode(BUTTON_GREEN_PIN, INPUT);  
  pinMode(BUTTON_BLUE_PIN, INPUT);  
  pinMode(BUTTON_YELLOW_PIN, INPUT);
  pinMode(RELAY,OUTPUT);
  digitalWrite(RELAY,HIGH);
  randomSeed(analogRead(0));
}

void loop() {
  delay(1000);
  if (game_mode() == MARK_OF_WIN){
    play_winner();
  }else{
    play_loser();
  }
}

void led_all_switch_on(){
  for ( int i = 0 ; i <= 25 ; ++i){
    for ( int j = 0 ; j<= 3 ; ++j){
      set_leds(j);
      delay(1);
    }
  }
}

void play_loser(){
  for (int i = 0; i <=5 ;++ i){
    //ブ・ブーを入れた
    if((i == 0 || i > 1)  && speaker_on_off == true && nmoves != 1 ){
      tone (SPEAKER,NOTE_D3);
    }else{
      noTone(SPEAKER);
    }
    //
    led_all_switch_on();
    set_leds(4);
    delay(100);
  }
  noTone(SPEAKER);
}

//勝った時
void play_winner(){
    for ( int i = 0 ; i <= 10; ++i){
       int noteDuration = 1000/noteDurations[i];
       if(speaker_on_off == true ){
         tone(SPEAKER, melody[i],noteDuration);
       }
       set_leds(win_led[i % 4]);
       int pauseBetweenNotes = noteDuration * 1.20;
       delay(pauseBetweenNotes);
       noTone(SPEAKER);
       set_leds(4);
       delay(20);
  }
}

//問題を表示する
void play_moves(){
  for (int c_move = 0 ; c_move < nmoves ; ++c_move){
    toner(moves[c_move]);
    delay(200);
  }
}

//新しい色を加える
void add_to_moves(){
  int new_button;
  moves[nmoves] = random(4);
  ++nmoves;
}
  
// ボタンが押されるか、タイムアウトまで待つ。返り値は0から3までの色かFAILURE=9のどれか。
int wait_for_button(){
  int old_button = FAILURE;
  int time_limit = TIME_LIMIT;
  while( time_limit > 0){
    int button;
    button = check_button();
    if (((old_button == 0)||(old_button == 1)||(old_button == 2)||(old_button == 3))&&(button == FAILURE)){
      return old_button;
    }
    old_button = button;
    delay(10);
    --time_limit;
  }
  return FAILURE;
}

//ゲームのメインサブルーチン
boolean game_mode(){
  nmoves= 0;
  while ( nmoves < MOVE_TO_WIN){
    add_to_moves();
    play_moves();
    for ( int c_move = 0 ; c_move < nmoves ; ++c_move){
      int choice = wait_for_button();
      if (choice == FAILURE) {
        //リレーを操作  auto power off
        if (nmoves == 1) {
          ++leave_counter ;
          if (leave_counter >= 5) digitalWrite(RELAY,LOW);
        }else leave_counter =0;
        //        
        return MARK_OF_LOST;
      }
      toner(choice);
      if (choice != moves[c_move]) return MARK_OF_LOST;
    }
    delay(1000);
  }
  return MARK_OF_WIN;

//ボタンをチェック。0~3の色かFAILURE=9の返り値    
int check_button(){
  int i = FAILURE;
  //音を出す・消す
  if (digitalRead(BUTTON_BLUE_PIN) == HIGH && digitalRead(BUTTON_YELLOW_PIN) == HIGH){
    speaker_on_off = !speaker_on_off;
    delay(100);
  }
  //
  if (digitalRead(BUTTON_RED_PIN) == HIGH){
    delay(10);
    i = LED_RED;
  }
  if (digitalRead(BUTTON_GREEN_PIN) == HIGH){
    delay(10);
    i = LED_GREEN;
  }
  if (digitalRead(BUTTON_BLUE_PIN) == HIGH){
    delay(10);
    i = LED_BLUE;
  }
  if (digitalRead(BUTTON_YELLOW_PIN) == HIGH){
    delay(10);
    i = LED_YELLOW;
  }
  return i;
}

//LEDの表示。返り値なし  
void set_leds(int leds){
  digitalWrite(LED_RED_PIN,LOW);  
  digitalWrite(LED_GREEN_PIN,LOW);  
  digitalWrite(LED_BLUE_PIN,LOW);  
  digitalWrite(LED_YELLOW_PIN,LOW);  
  switch (leds){
    case 0:
      digitalWrite(LED_RED_PIN,HIGH);
      break;
    case 1:
      digitalWrite(LED_GREEN_PIN,HIGH);
      break;
    case 2:
      digitalWrite(LED_BLUE_PIN,HIGH);
      break;
    case 3:
      digitalWrite(LED_YELLOW_PIN,HIGH);
      break;
  }
}

//表示及び音出し
void toner(int which){
  set_leds(which);
  if (speaker_on_off == true){
    switch (which){
      case LED_RED:
      tone(SPEAKER,LED_RED_TONE);
      break;
      case LED_GREEN:
      tone(SPEAKER,LED_GREEN_TONE);
      break;
      case LED_BLUE:
      tone(SPEAKER,LED_BLUE_TONE);
      break;
      case LED_YELLOW:
      tone(SPEAKER,LED_YELLOW_TONE);
      break;
    }
  }
  delay(200);
  noTone(SPEAKER);
  set_leds(4);
}
    
      

コメント (0件)

コメントはまだありません