サイモン:ゲームの完成
CoddyのArduinoジャーニー「プロジェクト」セクションの一部。レッスン 16/24。
本物のSimonは小さく始まり、徐々に大きくなります。ラウンド1では1色が再生されます。ラウンドを正しく繰り返すたびに、ボードは同じ色を保ち、最後に1色追加します。間違えるまで続きます。
配列には長いゲームに対応できる容量が必要で、どれだけ使用しているかを示す変数 length も必要です。色を追加する処理は2行です。
sequence[length] = random(4);
length++;ゲーム開始時に一度だけシードを設定します。playSequence() は4色ではなく length 色を再生するようになり、step が length に達するとラウンドが終了します。
間違えると、音符とは明らかに異なる音(110 Hzを1秒間)を鳴らしてゲームが終了し、スコアが表示されます。スコアは完了したラウンド数、つまり length - 1 です。失敗したラウンドは数えません。
配列には20個の要素があり、スケッチは配列の末尾を越えて書き込んではいけません。そのため、20色を繰り返したプレイヤーの勝利です。
チャレンジ
難しい完全なゲームに仕上げましょう:
const int MAX_STEPS = 20;、int sequence[MAX_STEPS];、およびint length = 0;- ゲームは1色から始まり、各ラウンドを正しく繰り返すたびに1色追加され、すべての色が再生される
- 間違えた場合:110 Hzを1000 ms鳴らし、その後
Game over! Score:とスコアを出力して、ゲームを終了する - 20色を正しく繰り返した場合:
You win!を出力して、ゲームを終了する
Run を押して、どこまで進めるか試してから、Check を押しましょう。
自分で試してみよう
// 各色に1つずつの要素:赤、緑、青、黄
const int ledPins[4] = {9, 10, 11, 12};
const int buttonPins[4] = {2, 3, 4, 5};
const int notes[4] = {262, 330, 392, 523}; // C、E、Gと高いC
const int buzzerPin = 8;
int lastState[4] = {HIGH, HIGH, HIGH, HIGH}; // 各ボタンの前回の読み取り値
int sequence[4]; // ボードが再生する色
bool playing = false; // ボタンが押されてゲームが始まるまではfalse
int step = 0; // プレイヤーが繰り返した色の数
// 色iを点灯し、その音を鳴らす。
void lightOn(int i) {
digitalWrite(ledPins[i], HIGH);
tone(buzzerPin, notes[i]);
}
// 色iを消灯し、音を止める。
void lightOff(int i) {
digitalWrite(ledPins[i], LOW);
noTone(buzzerPin);
}
// シーケンスを再生する:各色を400 msずつ点灯し、その後200 ms無音にする。
void playSequence() {
delay(500);
for (int i = 0; i < 4; i++) {
lightOn(sequence[i]);
delay(400);
lightOff(sequence[i]);
delay(200);
}
}
// 新しいランダムなシーケンスを選び、再生する。
void startGame() {
randomSeed(micros());
for (int i = 0; i < 4; i++) {
sequence[i] = random(4);
}
playing = true;
step = 0;
playSequence();
}
// プレイヤーが色iのボタンを離した:シーケンスの次の色か?
void checkPress(int i) {
if (i != sequence[step]) {
Serial.println("Wrong!");
playing = false;
return;
}
step++;
if (step == 4) {
Serial.println("Well done!");
playing = false;
}
}
void setup() {
for (int i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT);
pinMode(buttonPins[i], INPUT_PULLUP);
}
Serial.begin(9600);
}
void loop() {
for (int i = 0; i < 4; i++) {
int state = digitalRead(buttonPins[i]);
if (state == LOW && lastState[i] == HIGH) { // 押された
lightOn(i);
}
if (state == HIGH && lastState[i] == LOW) { // ボタンを離した
lightOff(i);
if (playing == false) {
startGame();
} else {
checkPress(i);
}
}
lastState[i] = state;
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
プロジェクトのすべてのレッスン
自分で練習してみよう: Arduinoプレイグラウンド