如何创建一个反应游戏

电子说

1.3w人已加入

描述

步骤1:基本设计

led

led

反应游戏非常简单。它是一个计时器,一个显示器以及您需要多少个发光按钮。

反应游戏接线的主要部分是两个重复的独立电路的集合。这两个电路是:

1。按钮

在Arduino官方网站上有很多关于向Arduino添加按钮的教程。

2。独立点亮的LED(12v)

对于LED,由于我们使用的是12v LED,我们需要与Arduino分开的外部电源,该电源只能在5v的电压下工作。对于先前的项目(我希望在某个时候写一个照相亭),我使用MOSFET在Raspberry PI和一些LED灯之间建立接口。我使用了关于PI和LED之间的连接的出色教程。对于这个项目,我只是简单地重复了多次练习。

输出显示

游戏的第三部分是用于显示得分的LED矩阵显示和剩余时间。为此,我使用了4个链接的MAX7219矩阵显示器。为了使它们正常工作,我使用了链接到驱动程序库的链接教程,并提供了使用显示器的示例。

步骤2:电路板-按钮连接器

在构建我制作的第二个反应游戏时,编写了指令。在制作第一个反应游戏的过程中,我犯了一些小错误,因此在设计上有所改进。 (理想情况下,我想为所有电子设备制作PCB,并且我打算在有更多时间的情况下这样做)。

在其中钻两个6mm孔vero板位于方便的位置。如果使用相同的Vero板,则建议使用与以前相同的位置。这样可以避免所有主要路线,包括我用于地面的大型路线。这些孔用于将板安装到反应游戏的背面。在我最初的设计中,我没有这样做,最终将电路板热粘合。除非出现问题,否则我很麻烦!

使用1.5mm的钻头,沿一个边缘增加销的尺寸。我用来将每个按钮连接到板上的4针凹型连接器的针脚明显更宽。由于4针连接器每个跨2个孔,因此仅每个其他孔都需要加宽。

将所有8个母连接器推到板上,并焊接到位。

步骤3:电路板-主接线

led

本节详细介绍了主要组件与电路板的接线。

一个16针公插头,它在板的底部。这是按钮,LED和Arduino

之间的接口。由于使用了Vero板,因此很容易将单独的电路(LED和按钮)分为几组。母连接器跨越8个孔。这意味着LED可以使用4个孔,按钮可以使用4个孔,以将电路保持在相同的“垂直”状态。因此,所有8个电路可以以8个孔的间隔重复进行。

为使布线更简单,我倾向于依次为每个电路依次布线所有相同的零件(如图所示)

步骤4 :板

要安装电子设备,我购买了可以运输的最大的板(610毫米x 1220毫米x 9毫米)。

我标记了所有按钮的位置。

每个角按钮距角100毫米x 100毫米。

中间的顶部和底部按钮位于中间,但距离边缘100毫米

中间的两个按钮(左侧和右侧)与其他按钮的距离相等适当的一面。

在标记了按钮的位置之后,我使用了25毫米的平头钻头来钻出按钮的孔。

我标记了显示器的位置

一个朋友有一个摆动的多功能工具,所以我借用他在显示器上切出矩形孔。

由于我使用的显示器的厚度和设计,我使用了路由器将MDF的深度去除了约5mm。

我为木板切了3个支撑腿。腿部被切割成一定角度,使木板既可以躺在桌子上,也可以直立在墙上。中腿需要一个用于穿过电缆的插槽。

在项目的第1版中,我只用了2条腿,但是当倾斜到“桌面”(平躺)位置时,会导致板子弹跳很多。

将腿粘到位。

我用黑板漆画了木板。这主要是为了使我们能够使用粉笔在板上画广告,并在按钮上写下不同的游戏名称。

最后,我将两个螺栓热粘合到电路板上(电路板顶部附近),以通过先前在PCB中钻出的2个孔安装电子设备。我还将一圈胶水热粘在螺栓上(现在在螺栓的上侧),以最大程度地减少短路的风险。

步骤5:接线并组装

为每个按钮切断适当长度的电缆。这些电缆的长度会因面板/按钮的距离而异。

在一端,将剥开的电线拧入连接块中。对于每个连接块,将所有4根电线保持在相同的顺序,因为这将简化以后的接线,也使解决任何问题变得更加容易。我使用的顺序是:

红色-LED 12v

黑色-LED接地

黄色-切换到引脚

灰色-切换5v

在另一端,我压接了连接器以保持连接的美观和整洁。我确实没用完连接器,所以不是我的所有连接器都做完了

所有连接器都连接好后,按如下所示组装按钮。我的LED没有标记,因此按正确的方向进行操作会引起反复试验,但这要等到代码完成后才能实现

我的按钮背面有两小块塑料在板上时停止旋转按钮。这就要求在每个按钮的板子前面钻两个小孔。我发现最简单的方法是将按钮放入并旋转45度。取出按钮后,可以看到销钉画的两条线。用一个3mm的小钻头在每条线的一端钻孔。确保您在每条线的同一端都进行了钻孔(例如,两行的顺时针方向!)

步骤6:接线Arduino

以下说明用于连接Arduino MEGA。

需要将16针公对母带状跨接电缆从PCB上的16针接头连接到Arduino上的数字数据针,如图所示。

两个引脚从Arduino连接到PCB。 5v转到具有红线的PCB上的小电路。接地引脚从Arduino到PCB,

显示器的接线方式如接线图所示。

最后将LED的12v线连接到母插孔连接器上。

显示器

显示器已配对并放入孔(确保正确放置)。我使用胶带将显示屏固定在板上。

我使用胶带并且不将显示屏永久固定在原位的原因是我希望能够与玩家站在一块墙,或平躺在桌子上。这就是为什么后面的支杆被切成一定角度的原因。但是,这两个位置都需要切换显示,以便每次都能正确显示。因此,通过使用胶带方法可以轻松更改它们。

第7步:对Arduino进行编码

我不会在此提供大量教程Arduino编程,因为有一些很棒的教程,但是我将逐步介绍我的代码,并提供一般概述。我确信我可以改进代码,并添加许多其他游戏。

该项目需要HCMAX7219库。可能有多个版本,但是我使用了Hobby Components Blog引用的版本。这就是我建议从此处获取矩阵显示的原因,因为使用它们的工作似乎很厚道而不捐赠!

下载后,编辑HCMAX7219.h文件并将以下行更改为4:

(第31行)

#define NUMBEROFDRIVERS 4

此值确定以菊花链方式将多少个LED矩阵显示器链接在一起。对于单人游戏,我们使用4;对于两人游戏,我们使用8。

附加到Instructable是我的代码。

该代码包含两个数组,一个用于LED,一个用于按钮:

const int LED[8] = { 2, 4, 6, 8, 22, 24, 26, 28 };

const int BUTTON[8] = { 3, 5, 7, 9, 23, 25, 27, 29 };

通过使用数组,可以索引特定的按钮,然后返回

该程序包括以下主要部分:

设置-在Arduino通电时运行一次以设置游戏

循环-持续运行

ScreenSaver-随机点亮按钮,直到按下按钮。程序中有3个屏幕保护程序,它们是随机选择的

CountDown-按下按钮时,请进行短暂的倒计时,并越来越快地闪烁灯光,以便播放器准备开始

PlayGame-玩实际游戏

设置

设置通过从屏幕上读取“噪声”来随机化种子模拟端口。

如果设置了DEBUG,它将打开串行端口。在设置了DEBUG的情况下运行时,读取按钮会有很大的延迟,因此在正确运行游戏时应关闭DEBUG

正确设置所有输入和输出引脚

/*

Set up the game

*/

void setup() {

// Set up the seed

randomSeed(analogRead(0));

if (DEBUG)

Serial.begin(9600);

// Set up the pins

for (int i = 0; i 《 NUMBER_BUTTONS; i++)

{

pinMode(LED[i], OUTPUT);

pinMode(BUTTON[i], INPUT);

}

}

循环

主循环启动“屏幕保护程序”,等待按钮按下

显示闪烁的倒计时在开始播放

玩游戏之前

/*

The main loop

*/

void loop()

{

Debug(“DEBUG ON - ”, 0);

// Run the screen saver

ScreenSaver();

// Countdown to start

CountDown();

// Play the game

PlayGame();

}

屏幕保护程序

“屏幕保护程序”只是闪烁按钮在不同的模式。这对于调试电子设备以及“宣传”反应游戏正在运行并准备就绪可发挥作用。我创建了3种不同的屏幕保护程序,从简单地随机显示灯光,建立和分解所有灯光,以及以“反弹”的不同线条显示灯光。每个屏幕保护程序都有其自身的功能,可以在等待按下按钮的同时打开和关闭相应的灯。因为我们有8个按钮,所以每个按钮对应一个字节中的一位。这使SetLEDs函数可以使用按位操作来打开和关闭灯。

“构建和行”屏幕保护程序使用包含要显示的字节模式的查找表。随机屏幕保护程序仅选择一个介于1和255之间的b =数字,并显示与该数字相对应的灯光。

/*

Randomly does a screen saver

*/

void ScreenSaver()

{

int screenSaver = random(3);

bool response = false;

while (!response)

{

switch(screenSaver)

{

case 0:

Debug(“Screen saver random: ”, screenSaver);

response = ScreenSaverRandom();

break;

case 1:

Debug(“Screen saver build up: ”, screenSaver);

response = ScreenSaverBuildUp();

break;

case 2:

Debug(“Screen saver lines: ”, screenSaver);

response = ScreenSaverLines();

break;

default:

Debug(“Screen saver default: ”, screenSaver);

response = ScreenSaverRandom();

}

}

}

设置LED

以下两个功能用于设置LED的开和关(取决于调用它们的要求)。

SetLED写入特定的引脚,将引脚设置为HIGH或LOW。

SetLEDs使用字节模式来设置多个LED的开和关。

/*

Set a button

*/

void SetLED (int button, int led)

{

if (button != HIGH)

digitalWrite(led, LOW);

else

digitalWrite(led, HIGH);

}

/*

Set the LED pattern using bits

0000 0001 - LED 01

0000 0010 - LED 02

0000 0100 - LED 03

0000 1000 - LED 04

0001 0000 - LED 05

0010 0000 - LED 06

0100 0000 - LED 07

1000 0000 - LED 08

*/

void SetLEDs (int pattern)

{

Debug(“SetLEDs: ”, pattern);

int bitPattern = 0x01;

for(int i=0;i if ((pattern & bitPattern) != 0)

SetLED(HIGH, LED[i]);

else

SetLED(LOW, LED[i]);

bitPattern = bitPattern 《《 1;

}

}

检查是否按下了按钮

如果按下了任何按钮,则以下函数返回true,

/*

Check to see if any button is pressed

*/

bool CheckButtons()

{

for (int i=0; i《 NUMBER_BUTTONS; i++)

{

if(digitalRead(BUTTON[i]) 》 0)

{

Debug(“CheckButtons() - pressed: ”, i);

return true;

}

} Debug(“CheckButtons() - NOT PRESSED - ”, -1);

return false;

}

玩游戏

此功能是主要的单人游戏。它仅循环运行31秒,即可更新时间,打开单个LED并等待按下相应的按钮。按下适当的按钮后,它会增加分数,随机选择其他按钮并重复。

游戏实际上持续了31秒,但使用30秒时,您的感觉是您获得了29秒。对于31秒的游戏,计时器显示30秒,然后等待一秒钟递减。当达到0时,游戏停止。如果使用30秒计时器,则游戏将显示30秒,然后立即更改为29秒。看来您还没用完30秒(尽管可以)。我发现,比让用户认为自己在被骗更值得多花一秒钟!

时间一到,它会显示玩家得分10秒,并在适当的时候更新高分并返回到屏幕保护程序(显示游戏的最高得分)。

/*

Play the game

*/

void PlayGame()

{

unsigned long endTime = millis() + 31000;

int score = 0;

Debug(“endTime: ”, endTime);

Debug(“millis(): ”, millis()); long randButton = random(8);

while (millis() 《 endTime)

{

// Set the button to press as lit

SetLED(HIGH, LED[randButton]);

UpdateDisplay((endTime - millis())/1000, score);

// Check to see if the button was pressed

if(digitalRead(BUTTON[randButton]))

{

score ++;

// Turn off the button

SetLED(LOW, LED[randButton]);

// Get the new button and check it has changed

int newButton = random(8);

while(newButton == randButton)

{

newButton = random(8);

}

// Values differ, so continue

randButton = newButton;

}

}

// Clear all the LEDs

SetLEDs(0);

// Wait 10 seconds to show the score

delay(10000);

// If a new high score, set it

if (score 》 highScore)

highScore = score;

}

更新显示内容

此功能可在游戏过程中更新显示内容。该函数将时间和分数转换为字符串,在任何1个字符值的前面加上“ 0”以将其填充。然后将缓冲区发送到HCMAX7219库以打印值,然后刷新显示。

高分函数的工作非常相似,但显示值HI和高分。

void UpdateDisplay(unsigned long time, int score)

{

// Update the time, make sure it is 2 digits

String timeStr = String(time);

if(timeStr.length() 《 2)

timeStr = “0” + timeStr;

// Add the score which must be 2 digits

String scoreStr = String(score);

if(scoreStr.length() 《 2)

scoreStr = “0” + scoreStr;

// Combine the string

String numberStr = timeStr + scoreStr;

char charBuf[5];

numberStr.toCharArray(charBuf, 5);

// Display the string

HCMAX7219.printMatrix(charBuf,32);

HCMAX7219.Refresh();

}

2人游戏的改进

我对2人游戏进行了一些改进,应将其移回到单人游戏。其中包括:

高分存储在EEPROM中,以便在关闭游戏时保存高分。首次打开游戏时,已修改设置以查找被按下的按钮7。如果在启动时按下按钮7,则会将高分重置为0。

如果未按下任何按钮或按下的按钮的值,则CheckButtons函数已更改为返回-1。这样,主菜单就可以检查返回的值并选择要在主循环中玩的其他游戏。

步骤8:可选改进

随着我在原始项目上的进展,我正在不断改进,更新和完善自己的工作。

用于2个玩家游戏的第二个板子

最初,我只是在看一个玩家反应游戏,但在进行游戏测试时,提出了其他可以实施的想法。第一个是两个玩家选项。通过拥有第二块棋盘,可以对大量其他游戏进行编码。通过使用Arduino Mega,可以在一个处理器上运行两个板。

提高游戏类型的数量

有很多游戏类型可用。大多数是主题的变体

反应游戏-类似于“‘鼠”。如果它点亮,请按按钮,得到一个指示,重复30秒。

反应减游戏-与游戏#1相同,但是每次按错都会输掉一个点。不过,您只能返回零(显示的大小不足以容纳负数)。

多个按钮反应游戏-与#1类似,但多个按钮会亮起,并且必须先清除所有按钮,然后才能显示一组新的随机按钮。

西蒙(Simon)说-尽管我所有的按钮都是单一颜色,但可以按给定顺序点亮灯光并让玩家重复给定图案

将显示添加到按钮中

如果可以将矩阵显示添加到每个按钮中,并在中间添加较大的矩阵显示,则可以提出简单的问题,并选择多项答案。即使每个按钮上都没有显示,您也可以给每个按钮编号,然后问一些简单的数学问题。

责任编辑:wv

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分