反応ゲーム:フライング
CoddyのArduinoジャーニー「プロジェクト」セクションの一部。レッスン 7/24。
今なら、ずる賢いプレイヤーは不正ができます。待っている間に何度も押し続けると、そのうちの1回がライト点灯直後に当たります。レースにはこれを防ぐルールがあります。合図の前に動くのはフライングで、スタートは取り消されます。
ステートマシンは、プレイヤーが早すぎるタイミングで操作したことをすでに検知できます。WAITING状態でのすべての押下です。時計を確認する前に、そこで検知しましょう。
case WAITING:
if (pressed) {
Serial.println("Too soon!");
state = READY;
} else if (millis() - waitStart >= waitTime) {
// 前と同じようにLEDを点灯させる
}
break;READYに戻るとラウンドが終了します。LEDは点灯せず、次の押下で新しいランダムな待ち時間を使って新しいゲームが始まります。delay(waitTime)では、ボードはこの押下をまったく検知できませんでした。
チャレンジ
中級フライングを検出する:
WAITING中にボタンを押すと、Too soon!と表示され、LEDを点灯させずにREADYに戻る- それ以外は変更なし:次にボタンを押すと新しいラウンドが始まる
Runを押し、すばやく2回押してから、Checkを押す。
自分で試してみよう
const int ledPin = 12;
const int buttonPin = 2;
// 1回の試行における3つの状態
enum State { READY, WAITING, LIT };
State state = READY;
int lastButton = HIGH; // 前回のボタンの読み取り値
unsigned long waitStart = 0; // 待機が始まった時刻
unsigned long waitTime = 0; // 今回の待機時間
unsigned long litAt = 0; // LEDが点灯した時刻
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
Serial.begin(9600);
Serial.println("Press the button to start");
}
void loop() {
int button = digitalRead(buttonPin);
bool pressed = (button == LOW && lastButton == HIGH); // たった今押された
lastButton = button;
unsigned long now = millis();
switch (state) {
case READY:
if (pressed) {
randomSeed(micros()); // ボタンが押される時刻は毎回異なる
waitTime = random(1000, 3001);
waitStart = now;
state = WAITING;
}
break;
case WAITING:
if (now - waitStart >= waitTime) {
digitalWrite(ledPin, HIGH);
litAt = now;
state = LIT;
}
break;
case LIT:
if (pressed) {
digitalWrite(ledPin, LOW);
unsigned long reaction = now - litAt;
Serial.print("Reaction: ");
Serial.print(reaction);
Serial.println(" ms");
state = READY;
}
break;
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
プロジェクトのすべてのレッスン
自分で練習してみよう: Arduinoプレイグラウンド