反应力游戏:最佳成绩
本课属于 Coddy Arduino 学习旅程的“项目”单元。第 8 课,共 24 课。
这个程序会把最佳(最短)时间保存在一个变量中,并在每轮结束后打印出来。
一开始还没有最佳时间。用一个真实轮次不可能得到的值 0 表示“还没有”。每轮结束后,如果还没有最佳时间,或者这一轮的用时更短,这一轮的用时就是新的最佳时间。
if (best == 0 || reaction < best) {
best = reaction;
}
Serial.print("Best: ");
Serial.print(best);
Serial.println(" ms");把这段代码放在 LIT 状态中,这个状态会在一轮结束并得到真实用时后执行。抢跑不会执行这段代码,所以不会成为纪录。
最佳时间保存在开发板的内存(RAM)中,断电后会被清除。因此,按下“运行”后,这条纪录会一直保留到下一次按下“运行”。
挑战
中等记录最佳成绩:
- 创建变量
best,初始值为 0 - 每轮计时结束后,如果
best为 0,或者本轮用时更短,就将本轮成绩保存为新的最佳成绩 - 每轮结束后都打印它,例如
Best: 250 ms - 抢先按下按钮时不做任何更改
按“运行”,试着刷新你的最佳成绩,然后按“检查”。
亲手试试
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; // 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 (pressed) {
// 灯亮之前就按下了按钮:抢按。
Serial.println("Too soon!");
state = READY;
} else 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 在线编辑器