Menu
CoddyTech

Simon:随机序列

本课属于 Coddy Arduino 学习旅程的“项目”单元。第 14 课,共 24 课。

现在轮到游戏板了。第一次松开按钮时,游戏开始:游戏板会随机选出四种颜色,将它们保存在数组中,并依次播放。

random(4)会生成 0、1、2 或 3:对应一种颜色。一个 for 循环会填充数组。和反应游戏一样,在按下按钮时用 micros() 设置随机数种子,否则每局游戏的颜色顺序都会相同:

randomSeed(micros());
for (int i = 0; i < 4; i++) {
  sequence[i] = random(4);
}

第二个 for 循环会播放这个模式:点亮一种颜色并播放对应的音符,等待片刻,将它熄灭,再等待片刻。第二次等待很重要,因为颜色可能连续出现两次:没有这次等待,红色、红色听起来就像是一段持续较长的红色。现在玩家只需观看,所以使用 delay() 没问题。

for (int i = 0; i < 4; i++) {
  lightOn(sequence[i]);
  delay(400);
  lightOff(sequence[i]);
  delay(200);
}

一个名为 playing 的 bool 会记住游戏是否已开始,因此只有第一次按下按钮时才会启动游戏。

challenge icon

挑战

中等

让电路板播放一个序列:

  • 添加 int sequence[4]; 和 bool playing = false;
  • 松开按钮时,如果 playing 的值为 false:设置随机数种子,用 random(4) 填充数组,将 playing 设为 true,然后播放序列
  • 序列规则:等待 500 ms,然后依次播放每种颜色对应的音符,每个音符持续 400 ms,之后静音 200 ms

之后,按钮会像之前一样亮起并播放声音。按“运行”,按下一个按钮,然后按“检查”。

亲手试试

// 每种颜色对应一个元素:红、绿、蓝、黄
const int ledPins[4] = {9, 10, 11, 12};
const int buttonPins[4] = {2, 3, 4, 5};
const int notes[4] = {262, 330, 392, 523};  // C、E、G 和高音 C
const int buzzerPin = 8;

int lastState[4] = {HIGH, HIGH, HIGH, HIGH};  // 每个按钮上一次的读数

// 点亮颜色 i,并播放对应的音符。
void lightOn(int i) {
  digitalWrite(ledPins[i], HIGH);
  tone(buzzerPin, notes[i]);
}

// 熄灭颜色 i,并停止发声。
void lightOff(int i) {
  digitalWrite(ledPins[i], LOW);
  noTone(buzzerPin);
}

void setup() {
  for (int i = 0; i < 4; i++) {
    pinMode(ledPins[i], OUTPUT);
    pinMode(buttonPins[i], INPUT_PULLUP);
  }
}

void loop() {
  for (int i = 0; i < 4; i++) {
    int state = digitalRead(buttonPins[i]);
    if (state == LOW && lastState[i] == HIGH) {  // 按下
      lightOn(i);
    }
    if (state == HIGH && lastState[i] == LOW) {  // 松开
      lightOff(i);
    }
    lastState[i] = state;
  }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

项目中的所有课

自己练习: Arduino 在线编辑器