所以我正在制作这个游戏"停止它"这是一个游戏(在我的情况下)是彼此相邻的6个,发光+发出声音1比1,每次按下按钮1(knop1),当led 1烧伤时,LED开始闪烁得更快
我已经明白了 但是我需要一个第二个按钮(knop2),你需要随时按下才能完全停止游戏,但我一直都在努力。 我尝试了很多东西,但每一个都失败了 同样抱歉有点复杂的代码...
这是代码:
#define NOTE_E4 330 //Declareren van de noten
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_0 000
//----------------------------------------------------------------------------------------------------------------------------------------
int noten[] = { //De noten
NOTE_E4, NOTE_G4, NOTE_A4, NOTE_E4, NOTE_A4
};
//----------------------------------------------------------------------------------------------------------------------------------------
int duur[] = { //de duur van elke noot
225, 225, 950, 225, 925
};
//----------------------------------------------------------------------------------------------------------------------------------------
const int buzzer = 9; //Hier staat de pin van de buzzer voor het lied
const int snelheid = 1.5; //Snelheid, een hoger getal laat alles trager gaan, een lager getal laat het sneller gaan
int led1 = 2;
int led2 = 3;
int led3 = 4;
int led4 = 5;
int led5 = 6;
int led6 = 7;
int gluid = 9;
int run = 0;
int knop = 12;
int knop2 = 11;
int n = 220;
//----------------------------------------------------------------------------------------------------------------------------------------
void setup() {
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(led5, OUTPUT);
pinMode(led6, OUTPUT);
pinMode(knop, INPUT_PULLUP);
Serial.begin(9600);
Serial.println("We shall begin. \n ");
delay(500);
for (int i=0;i<5;i++){ //5 staat voor het max aantal noten
int wacht = duur[i] * (snelheid * 0.9);
tone(buzzer,noten[i],wacht); //tone(pin,frequentie,duur)
delay(wacht);} //delay zorgt er hier voor dat de vorige noot niet word afgespeeld tijdens de vorige noot
delay(100);
Serial.println("Press the red button to start.");
Serial.println("You can press the black button any time to stop.");
}
//----------------------------------------------------------------------------------------------------------------------------------------
void loop(){
if (n <= 10)
{
n = 60;
}
else if (n == 20) {
Serial.begin(9600);
Serial.println("You won! Congratz!");
delay(150);
digitalWrite(led6, HIGH);
digitalWrite(led5, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led1, HIGH);
delay(150);
digitalWrite(led6, HIGH);
digitalWrite(led5, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led1, LOW);
delay(150);
digitalWrite(led6, HIGH);
digitalWrite(led5, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led2, LOW);
digitalWrite(led1, LOW);
delay(150);
digitalWrite(led6, HIGH);
digitalWrite(led5, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led3, LOW);
digitalWrite(led2, LOW);
digitalWrite(led1, LOW);
delay(150);
digitalWrite(led6, HIGH);
digitalWrite(led5, HIGH);
digitalWrite(led4, LOW);
digitalWrite(led3, LOW);
digitalWrite(led2, LOW);
digitalWrite(led1, LOW);
delay(150);
digitalWrite(led6, HIGH);
digitalWrite(led5, LOW);
digitalWrite(led4, LOW);
digitalWrite(led3, LOW);
digitalWrite(led2, LOW);
digitalWrite(led1, LOW);
delay(150);
digitalWrite(led6, HIGH);
digitalWrite(led5, HIGH);
digitalWrite(led4, LOW);
digitalWrite(led3, LOW);
digitalWrite(led2, LOW);
digitalWrite(led1, LOW);
delay(150);
digitalWrite(led6, HIGH);
digitalWrite(led5, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led3, LOW);
digitalWrite(led2, LOW);
digitalWrite(led1, LOW);
delay(150);
digitalWrite(led6, HIGH);
digitalWrite(led5, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led2, LOW);
digitalWrite(led1, LOW);
delay(150);
digitalWrite(led6, HIGH);
digitalWrite(led5, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led1, LOW);
delay(150);
digitalWrite(led6, HIGH);
digitalWrite(led5, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led1, HIGH);
delay(150);
digitalWrite(led6, LOW);
digitalWrite(led5, LOW);
digitalWrite(led4, LOW);
digitalWrite(led3, LOW);
digitalWrite(led2, LOW);
digitalWrite(led1, LOW);
digitalWrite(buzzer, LOW);
n = 10;
digitalWrite(led6, LOW);
digitalWrite(led5, LOW);
digitalWrite(led4, LOW);
digitalWrite(led3, LOW);
digitalWrite(led2, LOW);
digitalWrite(led1, LOW);
digitalWrite(buzzer, LOW);
digitalWrite(gluid, LOW);
n = 220;
delay(500);
}
else
if(digitalRead(knop) == LOW)
{
if(run == 0){
run = 255;
Serial.println("Next stage.");
n = n - 20; }
else{
run = 0;
}
}
if(run > 0)
{
{
digitalWrite(led6, HIGH);
delay(n);
digitalWrite(led6, LOW);
delay(n);
tone(gluid, 700);
}
{
digitalWrite(led5, HIGH);
delay(n);
digitalWrite(led5, LOW);
delay(n);
tone(gluid, 900);
}
{
digitalWrite(led4, HIGH);
delay(n);
digitalWrite(led4, LOW);
delay(n);
tone(gluid, 700);
}
{
digitalWrite(led3, HIGH);
delay(n);
digitalWrite(led3, LOW);
delay(n);
tone(gluid, 900);
}
{
digitalWrite(led2, HIGH);
delay(n);
digitalWrite(led2, LOW);
delay(n);
tone(gluid, 700);
}
{
digitalWrite(led1, HIGH);
delay(n);
digitalWrite(led1, LOW);
delay(n);
tone(gluid, 600);
}
}
}
答案 0 :(得分:1)
关键是将代码重新组织到状态机中。请记住,loop()
将被一遍又一遍地调用。每次调用时,都应该检查游戏的当前状态,并根据输入改变到下一个状态并返回。
为了说明,我将使用更简单的游戏。按开始按钮使一个LED闪烁,直到按下停止按钮。
// The WRONG WAY
void loop() {
while (digitalRead(knop1) == HIGH) {} // wait for start button
while (digitalRead(knop2) == HIGH) {
digitalWrite(led1, HIGH);
delay(250);
digitalWrite(led1, LOW);
delay(250);
}
}
上面的代码与您的代码类似,您尝试(几乎)在每次调用loop()
时执行所有操作。这使得难以观察输入。例如,请注意我们如何仅在每个完整的闪烁周期后检查停止按钮。这意味着响应时间可能不是很好(事实上,如果用户非常快地按下并释放按钮,我们可能会完全错过它。)
状态机方法使用一个或两个全局变量来跟踪游戏现在应该做什么。在每一点上,我们都会检查状态和输入,以确定是否需要更改状态。
// The BETTER WAY
enum { stopped, blink_on, blink_off } state = stopped;
unsigned long target = 0;
void loop() {
switch (state) {
case stopped:
if (digitalRead(knop1) == LOW) {
digitalWrite(led1, HIGH);
state = blink_on;
target = millis() + 250;
}
break;
case blink_on:
if (digitalRead(knop2) == LOW) {
digitalWrite(led1, LOW);
state = stopped;
} else if (millis() >= target) {
digitalWrite(led1, LOW);
state = blink_off;
target = millis() + 250;
}
break;
case blink_off:
if (digitalRead(knop2) == LOW) {
state = stopped;
} else if (millis() >= target) {
digitalWrite(led1, HIGH);
state = blink_on;
target = millis() + 250;
}
break;
}
}
还有其他方法来组织状态机代码,但它们基本上是等效的。例如,您可能决定在检查状态之前检查输入。您可能还想要分解转换以消除重复的代码。我还没有在这个示例中做过这些事情,因为我想说清楚状态机的工作原理。
将代码组织为状态机后,任何时候都可以相对轻松地响应任何输入。