Игра на реакцию: фальстарт
Часть раздела Проекты путешествия по Arduino на Coddy. Урок 7 из 24.
Сейчас хитрый игрок может жульничать: многократно нажимать во время ожидания, и одно из нажатий придётся сразу после включения света. В гонках для этого есть правило: движение до сигнала считается фальстартом, и старт отменяется.
Конечный автомат уже знает, когда игрок нажимает слишком рано: при любом нажатии в состоянии WAITING. Проверяй это там, до проверки времени:
case WAITING:
if (pressed) {
Serial.println("Too soon!");
state = READY;
} else if (millis() - waitStart >= waitTime) {
// зажгите светодиод, как и раньше
}
break;Возврат в состояние READY завершает раунд: LED так и не загорается, а следующее нажатие начинает новую игру с новым случайным временем ожидания. При использовании delay(waitTime) плата вообще не смогла бы заметить это нажатие.
Задание
СреднеОбрабатывайте фальстарты:
- в состоянии
WAITINGнажатие выводитToo soon!и возвращает программу в состояниеREADY, не включая светодиод - всё остальное остаётся как есть: следующее нажатие начинает новый раунд
Нажмите Run, попробуйте быстро нажать дважды, затем нажмите Check.
Попробуйте сами
const int ledPin = 12;
const int buttonPin = 2;
// Три состояния одного раунда
enum State { READY, WAITING, LIT };
State state = READY;
int lastButton = HIGH; // предыдущее показание кнопки
unsigned long waitStart = 0; // когда началось ожидание
unsigned long waitTime = 0; // сколько длится это ожидание
unsigned long litAt = 0; // когда загорелся светодиод
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;
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Проекты
2Игра на реакцию
Игра на реакцию: случайное ожиданиеИгра на реакцию: таймерИгра на реакцию: фальстартИгра на реакцию: лучшее времяПотренируйтесь самостоятельно: Песочница Arduino