Arduino游戏"停止它"

时间:2017-12-04 14:51:25

标签: loops button arduino

所以我正在制作这个游戏"停止它"这是一个游戏(在我的情况下)是彼此相邻的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); 
    }      
  }
}

1 个答案:

答案 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;
    }
}

还有其他方法来组织状态机代码,但它们基本上是等效的。例如,您可能决定在检查状态之前检查输入。您可能还想要分解转换以消除重复的代码。我还没有在这个示例中做过这些事情,因为我想说清楚状态机的工作原理。

将代码组织为状态机后,任何时候都可以相对轻松地响应任何输入。