Arduino智能设计|“跟我一起做”游戏机

网友投稿 2019-11-05 13:59

案例概述

“跟我一起做”是一款记忆类游戏机,由3个LED灯和3个按键组成。游戏总共设置了10个关卡。开始时,LED灯会按一定顺序闪烁,闪烁结束后,玩家需要依次按下3个对应的按钮。如果顺序一致,进入更有挑战性的下一关;如果按错按钮,游戏结束。

游戏用Arduino设计,在制作过程中学生能够得到计算思维和编程能力的锻炼。

适合年龄

初中到高中

使用材料

功能材料:Arduino UNO板(如有一体主板,可直接使用,如无一体主板,可安装IO扩展板使用),LED模块×3,按键模块×3,3p连接线×6

结构材料:瓦楞纸板、彩色卡纸、蓝泥胶、束线带、装饰贴纸

思路分析

在制作开始前,我们应该先理清整个游戏的思路,才能更好地设计游戏机的程序。我们可以先绘制流程图(如图1),让你的思路更加明确。

https://cdn.china-scratch.com/timg/191107/13591V008-0.jpg

程序设计

步骤1:硬件连接

如图2所示,分别将蓝、红、黄3个按钮杜邦接口端接在Arduino的5、6、7接口上,再将蓝、红、黄3个LED杜邦接口接在Arduino的8、9、10接口上。

https://cdn.china-scratch.com/timg/191107/13591UM8-1.jpghttps://cdn.china-scratch.com/timg/191107/13591U922-2.jpg

步骤2:变量初始化

首先,要将所有在这个程序中需要用到的变量先声明好。这里我们需要声明的分别有按键接口、LED灯接口、保存关卡数组LedA、保存玩家输入答案用数组userLed、一个专门记录目前关卡数的变量Level,以及通往下一关的布尔变量nextL。程序如下:

// Buttons Pins

int GrBpin = 5;

int ReBpin = 6;

int YeBpin = 7;

// Leds Pins

int GrLpin = 8;

int ReLpin = 9;

int YeLpin = 10;

// Leds Array

int LedA [10];               // 定义关卡数组

int userLed [10];             // 玩家记录数组

int Level;                   // 计数目前关卡

boolean nextL = true;        // 表示是否通关

步骤3:程序初始定义

 在游戏开始之前,程序中与硬件沟通相关的指令,都需在setup()函数中完成预先声明。在这里我们要声明输入输出接口、随机种子、开始使用串口沟通的指令。程序如下:

void setup() {     

randomSeed(analogRead(0));   //随机种子

  // 定义LED灯为输出接口OUTPUT

  pinMode(BlLpin, OUTPUT);    

  pinMode(ReLpin, OUTPUT);    

  pinMode(YeLpin, OUTPUT);    

  // 定义按钮为输入接口INPUT

  pinMode(BlBpin, INPUT);    

  pinMode(ReBpin, INPUT);    

  pinMode(YeBpin, INPUT);    

}

步骤4:设置关卡题目

在游戏开始之前,我们必须先将游戏关卡新题目准备好。为了不让主程序过于冗长,我们可以将设置关卡题目功能写进restartLeds()函数中,这样,每一个游戏回合结束后调用1次即可。该函数需要通过随机种子运算,运算结果运用循环一一存储到关卡数组中。程序如下:

// 通过随机种子运算出来的题目存储到关卡数组中

void restartLeds() {

  Level = 1;

  nextL = true;

  int index = 0;

  while (index < 10) {

    LedA [index] = random (BlLpin, YeLpin+1);

    index++;

  }

}

步骤5:闯关结果灯号函数

我们让LED灯会显示出不同的状态,用来表示玩家的闯关结果。当玩家闯关成功,LED灯显示为流水灯;当玩家闯关失败,3盏LED灯同时闪烁。为了表示这个状态,我们需要设计2组函数,分别表示闯关成功和失败。程序如下:

// 闯关成功灯号函数

void winnerDance () {

  for (int id=1; id <= 5; id++) {

    digitalWrite (BlLpin, HIGH);

    digitalWrite (ReLpin, LOW);

    digitalWrite (YeLpin, LOW);

    delay (100);

    digitalWrite (BlLpin, LOW);

    digitalWrite (ReLpin, HIGH);

    delay (100);

    digitalWrite (ReLpin, LOW);

    digitalWrite (YeLpin, HIGH);

    delay (100);

  }

  digitalWrite (YeLpin, LOW);

  delay (2900);

}

// 闯关失败灯号函数

void Loose () {

  digitalWrite (BlLpin, HIGH);

  digitalWrite (ReLpin, HIGH);

  digitalWrite (YeLpin, HIGH);

  delay (200);

  digitalWrite (BlLpin, LOW);

  digitalWrite (ReLpin, LOW);

  digitalWrite (YeLpin, LOW);

  delay (200);

  digitalWrite (BlLpin, HIGH);

  digitalWrite (ReLpin, HIGH);

  digitalWrite (YeLpin, HIGH);

  delay (200);

  digitalWrite (BlLpin, LOW);

  digitalWrite (ReLpin, LOW);

  digitalWrite (YeLpin, LOW);

}

步骤6:按键侦测函数

我们还需要设计一个函数让按键和相应颜色的LED灯对应起来。程序如下:

// 等待按键按下并回传被按下的按键接口号

char w4press() {

  boolean bottPress = false;

  while (bottPress == false) {

    if (digitalRead(BlBpin) == HIGH) {                                        // 读取蓝色按键是否被按下

      while (digitalRead (BlBpin) == HIGH) {}                                            // 等待按键是否被放开

      return BlLpin;                                                                       // 返回蓝灯接口号码

      bottPress = true;

    }

    if (digitalRead(ReBpin) == HIGH) {                                                // 读取红色按键是否被按下

      while (digitalRead (ReBpin) == HIGH) {}                                 // 等待按键是否被放开

      return ReLpin;                                                                      // 返回红灯接口号码

      bottPress = true;

    }

    if (digitalRead(YeBpin) == HIGH) {                                       // 读取黄色按键是否被按下

      while (digitalRead (YeBpin) == HIGH) {}                                  // 等待按键是否被放开

      return YeLpin;                                                                      // 返回黄灯接口号码

      bottPress = true;

    }

  }

  delay (200);

}

步骤7:显示关卡题目函数

在步骤4中,我们已经把每一关的题目函数设置好,但并没有用LED灯显示出来。在这一步,我们需要设计一个函数,用LED灯显示步骤4的题目。程序如下:

/ 显示当前关卡题目灯号

void questionLeds () {

  int index = 0;

  while (index < Level) {

    digitalWrite (LedA [index], HIGH);

    delay (500);

    digitalWrite (LedA [index], LOW);

    if (LedA [index] == LedA [index+1])

      delay (200);

    if (index >= 9)

      break ;

    index++;

  }

}

步骤8:主程序

声明完所有的函数之后,就可以开始设计主程序。由于游戏需要重复执行,所以整个主程序需要写在loop()函数中。主程序分为2个部分:关卡判断和答案判断,其中,答案判断程序嵌套在关卡判断的while语句中。

●  关卡判断。主程序需要判断玩家是否通关,它判断2个变量:Level和nextL。Level变量是确认玩家是否通过全部关卡,当所处关卡不小于总关卡数,即处于最高关卡时,有可能闯关成功,否则继续进入游戏;布尔变量nextL记录玩家是否通关,若为false,代表闯关失败。

只有在布尔变量nextL为true,且所处关卡不小于总关卡数时,程序才会调用winnerDance()函数发出表示胜利的流水灯。

以下为判断部分主程序:

void loop() {

     restartLeds();

 while (nextL == true && Level <=10) {

 // 在这里嵌套步骤8答案判断程序

 }

   if (nextL == false) {

     Loose ();

     delay (3000);

    }

   if (nextL == true && Level >=10)

     winnerDance();

 }

答案判断:

定义一个新的局部变量ubc,用来计算玩家按键次数。同时调用w4press()按键侦测函数,将其返回值保存至userLED数组中,并核对玩家记录数组userLED和题目数组LedA中的内容是否一致。若不一致,将nextL设为false,闯关失败,并将ubc变量改为低于目前关卡数的Level变量跳出循环结束判断。程序如下:

questionLeds();                          // 播放目前关卡

int ubc=0;

while (Level>=ubc+1) {              // 读取玩家输入按键并比较循环

  userLed[ubc] = w4press();

  if (userLed[ubc] != LedA[ubc]) {

    nextL = false;

    ubc = Level-1;

  }

  ubc ++;

}

Level ++;

delay (1000);                      // 每一关卡等待2秒

步骤9:编译上传测试

将程序编译并上传到Arduino,并进行测试,直到游戏机正常工作。

结构设计

完成“跟我一起做”游戏机功能的实现之后,我们还需要为游戏机制作一个外壳,以拥有更好的游戏体验。

步骤1:切割1块10 cm×13 cm长方形纸板和1块10 cm×10 cm纸板,将它们垂直粘贴起来,作为游戏机的底板和背板(如图3)。

https://cdn.china-scratch.com/timg/191107/1359191095-3.jpg

(图3)

步骤2:用蓝泥胶将Arduino板、LED模块、按键模块粘贴到纸板上,并用束线带将线缆捆扎起来(如图4)。

https://cdn.china-scratch.com/timg/191107/1359195545-4.jpg

(图4)

步骤3:用纸板制作游戏机的侧面和顶部。注意留出Arduino板的数据接口和电源接口(如图5)。

https://cdn.china-scratch.com/timg/191107/1359193352-5.jpg

(图5)

步骤4:裁出一段长方形彩色卡纸,在按键和LED灯的对应处挖出圆形窗口。将彩色卡纸粘贴在游戏机的正面。最后粘贴上装饰贴纸,“跟我一起做”游戏机就完成了。连上电源线,玩起游戏机啦(如图6)!

https://cdn.china-scratch.com/timg/191107/1359194349-6.jpg

--end--

声明:本文章由网友投稿作为教育分享用途,如有侵权原作者可通过邮件及时和我们联系删除:freemanzk@qq.com