Trò chơi phản xạ: Khởi động sớm
Thuộc phần Dự án trong hành trình Arduino của Coddy. Bài học 7 trên 24.
Hiện tại, người chơi tinh quái có thể gian lận: nhấn liên tục trong lúc chờ, rồi một lần nhấn sẽ rơi đúng ngay sau khi đèn bật. Các cuộc đua có quy tắc xử lý việc này: di chuyển trước hiệu lệnh là xuất phát sớm, và lượt bắt đầu sẽ bị hủy.
Máy trạng thái đã biết khi nào người chơi nhấn quá sớm: bất kỳ lần nhấn nào trong trạng thái WAITING. Hãy kiểm tra tại đó, trước khi kiểm tra đồng hồ:
case WAITING:
if (pressed) {
Serial.println("Too soon!");
state = READY;
} else if (millis() - waitStart >= waitTime) {
// Bật đèn LED như trước
}
break;Quay lại READY sẽ kết thúc lượt chơi: đèn LED không bao giờ bật, và lần nhấn tiếp theo sẽ bắt đầu trò chơi mới với thời gian chờ ngẫu nhiên mới. Với delay(waitTime), bo mạch sẽ không thể nhận biết lần nhấn này.
Thử thách
Trung bìnhPhát hiện lần nhấn quá sớm:
- ở
WAITING, khi bạn nhấn nút, chương trình in raToo soon!rồi quay lạiREADYmà không bật đèn LED - mọi thứ khác vẫn giữ nguyên: lần nhấn tiếp theo bắt đầu vòng mới
Nhấn Chạy, thử nhấn nút hai lần thật nhanh, rồi nhấn Kiểm tra.
Tự làm thử
const int ledPin = 12;
const int buttonPin = 2;
// Ba trạng thái của một lượt
enum State { READY, WAITING, LIT };
State state = READY;
int lastButton = HIGH; // Trạng thái của nút ở lần đọc trước
unsigned long waitStart = 0; // Thời điểm bắt đầu chờ
unsigned long waitTime = 0; // Thời gian chờ của lượt này
unsigned long litAt = 0; // Thời điểm đèn LED sáng
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); // Vừa được nhấn
lastButton = button;
unsigned long now = millis();
switch (state) {
case READY:
if (pressed) {
randomSeed(micros()); // Thời điểm nhấn không bao giờ trùng nhau giữa hai lần
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;
}
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Dự án
2Trò chơi phản xạ
Trò chơi phản xạ: Thời gian chờ ngẫu nhiênTrò chơi phản xạ: Bộ hẹn giờTrò chơi phản xạ: Khởi động sớmTrò chơi phản xạ: Thời gian tốt nhấtTự luyện tập: Playground Arduino