基于Arduino制作这款打地鼠的街机游戏
扫描二维码
随时随地手机看文章
你有没有觉得有必要吹掉一些蒸汽,释放你内心的孩子,或者只是重温从你的街机辉煌的日子粉碎东西的快感?进入正常!这款游戏是对经典打地鼠游戏的高科技改造,融合了怀旧和工程学。
我们从头开始制作这款街机游戏:一个激光切割的木制盒子,里面装着九个气缸。但这不仅仅是蛮力,我们用磁铁和3D磁传感器取代了传统的机械开关,使撞击检测快速而精确。当然,我们也不能只使用自己3D打印的锤子,这样就能承受最激烈的游戏玩法。我们还提供了完整的构建指南:组装、编码和校准。准备好开始了吗?
游戏概述
在嘉年华上玩过打地鼠吗?假鼹鼠会从不同的洞里钻出来每次钻出来,你就试着敲它。正常!《T》将这一概念现代化:玩家击碎由压缩空气驱动的随机弹出的9个气动活塞。但这不是你爷爷的街机游戏:
智能命中检测:活塞上的磁铁与英飞凌最新系列的TLE493D磁性传感器相互作用,取代机械开关,实现即时、精确的命中。
自动游戏流程:xmc4700 Relax Lite kit微控制器套件是游戏的大脑,并使用OPTIGA™TrustMsecurity芯片随机化活塞定时。活塞的气动阀由使用单芯片的TLE94112ES 12倍半桥控制!最重要的是,游戏中的DPS368压力传感器和3d打印的锤子会在锤子被举起时触发游戏开始。
时间和得分跟踪:一个双位数的7段显示剩余的比赛时间和你的最终得分。
它是如何工作的
开始:举起锤子→DPS368测量锤子与游戏底座的高度差,触发游戏开始倒计时5秒。
播放:15秒倒计时开始→OPTIGA™Trust M芯片随机分配活塞→TLE94112ES激活阀门→活塞弹出。
得分:敲击活塞→TLE493D检测磁感应→XMC4700点燃下一个活塞并增加得分。
接下来是什么?我们将开始建立和测试9活塞气动系统,然后整合3D磁传感机制,添加双7段显示,最后我们3D打印智能锤子和组装成一个抛光街机准备的游戏。
硬件
气动系统:
此版本中的气动系统基于Hackster项目:使用单个芯片驱动气动系统。按照这个指南来创建你的主干!T游戏。
步骤2:将气动系统变为活动活塞
为了准备传感器测试,我们现在将转向组装。确保所有的激光切割部件和3d打印部件都准备好了,因为从现在开始,它们将在每一步中使用(请参阅附件中的设计文件)。
让我们从组装活塞外壳开始,它由激光切割的部件与9个活塞和传感器的切口粘合在一起。之后,我们放置3d打印的活塞导轨,将它们锁定在适当的位置,防止旋转。我们还增加了一些填充物的活塞支持,以帮助吸收冲击。
接下来,我们将9个活塞放入各自的插槽中,并将磁铁粘在它们身上,因为它们将在接下来的构建中发挥重要作用。请注意,在照片中,我们也组装了侧墙,这是激光切割,也可以附加在最后的组装。
接下来,我们放置9个活塞垫,拧紧支撑活塞的木板。这块板作为运动活塞和气动系统之间的中间层。最后,你可以把活塞系统安装到气动系统上,就可以进行测试了。
现在你已经成功地制造了活塞和气动系统!随后,我们将添加OPTIGA™Trust M芯片来随机化活塞行为。你会注意到活塞的木制外壳上有一些切口。这些切口是为3D磁传感器的支架设计的
3D磁传感器可以测量三个方向的磁场:X, Y和z。我们将在9个活塞之间放置4个传感器,这样就可以检测到任何一个活塞受到撞击时磁场的变化。
在圆柱体的底部,我们放置了磁铁。这些磁铁能让我们探测到圆柱体被击中的时间。
磁铁被放置在尽可能靠近3D磁传感器的地方,以确保磁场足够强,能够被准确检测到。对于传感器,我们使用3D磁传感器的切割板。在附件的Fritzing文件中提供了接线说明。
四个传感器安装在支架上,如下图所示。
现在,我们可以把传感器支架放在气动系统里。
为了使组装更实用,我们创建了一个带连接器的小板。布线如图所附的fritz文件所示;按照这些方法进行正确的连接。
现在我们可以把底板与9个气缸在组装和关闭一切的顶部。有了这一步,游戏的机制部分就完成了,可以进行测试了。
最后,我们可以测试9个活塞和磁传感器(测试代码在附件文件中提供)。之后,我们可以移动到7段屏幕的显示部分。
分数显示
我们使用两个相互连接的7段数字来显示游戏中的剩余时间和最终比分。我们将把显示器安装在“搞怪!”T游戏,这是设计来保持它。开始组装激光切割的木制部件如下所示。一旦框架准备好,将7段显示器安装到木板上,并通过木板布线,在那里它们将连接到XMC微控制器。
让锤子更聪明
锤子是击打的关键部分!T游戏。为了检测锤子何时被举起,我们使用了两个DPS368空气压力传感器:一个传感器放置在锤子内部。另一个被放置在里面!T框作为参考。
通过测量两个传感器之间的压力差,我们可以测量锤与游戏之间的高度差,精度为±2厘米,并检测锤何时被举起。压力传感器接线图在工程文件中提供。
对于锤子组件,您可以使用提供的3d打印部件。stl文件。这里有一些建议:水平打印锤子以获得更好的稳定性。将填充量增加到50%以增加重量和提高耐久性,将壁厚增加到2.4mm以增加坚固性。在电缆隧道区域(锤身)增加支架挡块,避免支架难以拆除。
锤子由三部分组成:主锤体和两个柔性TPU帽。这些盖子可以在激烈的游戏过程中保护游戏免受损害。
在锤子的顶部,有放置DPS368压力传感器的空间。只需将传感器推到位,如下图所示:
另一个传感器可以放置在任何地方。T游戏基地。
推动游戏发展
XMC4700放松套件需要5 V电源,显示器工作在12 V,压缩机和阀门都需要9 V电源。为了实现必要的电压转换,需要一个降压转换器从9v降压到5v,从9v升压到12v
为此,我们使用两个TLD5190 VOLT DEMO评估板。这些板允许您通过调整板上微调器来选择所需的输出电压。有关设置和使用这些评估板的详细说明,TLD5190 VOLT DEMO评估板的用户手册提供了全面的解释。
你可以通过向左转动微调器来增加电压,通过向右转动来降低电压。
软件
现在让我们一步一步地分解我们的Arduino代码!首先,我们将阐明如何单独使用和测试每个组件,然后我们将解释整个应用程序代码的Whack!T游戏。
第1部分:组件代码
7段显示代码
游戏开始前会出现5秒倒计时。游戏在这个倒计时后开始,另一个15秒倒计时从那里开始。在这段时间里,你必须尽可能多地打汽缸。在第二次倒计时结束时,你的最终得分显示-所有这些都是使用7段显示。为了测试这两个7段数字,我们使用了下面的示例代码。我们所做的唯一修改是将引脚分配更改为50 (segmentLatch), 51 (segmentData)和52 (segmentClock)。
代码Optiga™信任M盾2go
Optiga™Trust M芯片在这里用于生成(真实且加密安全的)1到9之间的随机值,这是我们项目中的关键一步,因为它检测到哪个圆柱体会弹出,使游戏变得不可预测和具有挑战性。但在此之前,我们需要了解芯片的工作原理。
我们首先修改Optiga™Trust M Arduino库中的一个示例,使其适应我们的需求。首先,让我们看一下这段代码的基础:
头文件和定义
要开始,我们需要包含“OPTIGATrustM.h”库,它使我们能够访问TrustM功能。我们定义了随机数生成的最大字节长度-将其设置为8确保我们一次可以生成最多8个随机字节。
一个额外的调整:默认代码包括彩色输出(来自“fprint.h”),但为了简单起见,我们选择禁用它。
设置函数
一切就绪后,是时候初始化芯片了。setup功能确保Trust M板准备好生成安全随机数。
这里有一个有趣的特性是电流限制——这个设置会影响主板的运行速度。如果我们增加电流限制,电路板就会加速。对于这个设置,我选择了8 mA的限制(setCurrentLimit(8)),以便在性能和稳定性之间取得更好的平衡。
循环函数:生成随机数
每次循环运行时,Optiga™Trust M模块通过函数getRandom(RND_MAXLENGTH, rnd)提供8字节的随机数据。但是我们需要一个介于1和9之间的数字,因此我们将原始字节数组转换为int64_t数字(convertByteArrayToInt64()),并使用对9 + 1取模将其映射到我们想要的范围。这确保了我们总是在目标范围内得到结果。
结果看起来像这样:
3D磁传感器代码
这部分在我们的Hackster文章中有很好的记录:下一代TLE493D: 3D磁感测指南,但对于这个特定的项目,我们需要使其适应XMC4700微控制器。
在深入游戏机制之前,我们需要测试所有四个传感器,以验证它们是否正确连接和运行。下面的代码是专门为快速诊断设计的,允许我们检查每个传感器是否可操作。使用四个#define语句,我们可以激活或停用单个传感器以进行测试。我们还定义了numavg,它决定了在计算平均值之前测量每个传感器的次数。
平均传感器值
一旦初始化,循环函数不断地从传感器读取数据。函数average_sensor_value()测量多个读数的值并取平均值,以获得更稳定的输出。
传感器的内置函数getTemperature()和getMagneticField()用于提取数据,而计时函数测量收集50个值所需的时间。
ps传感器代码
在我们的比赛中,时机就是一切。在玩家准备好之前,游戏不应该开始——这就是DPS传感器的作用所在。这些传感器用于检测锤子何时被举起,发出倒计时开始的信号。
为了实现这一点,我们使用了两个DPS传感器:一个传感器放置在锤子内部来跟踪它的运动。
第二个传感器仍然固定在打!T设置,作为参考点。
关于如何使用传感器的详细解释也可以在这篇Hackster文章中找到,但这里是我们如何在我们的项目中实现它。
头文件和对象
Dps3xx.h包含在#include中,创建两个Dps传感器对象:
设置/循环
在我们追踪锤子的运动之前,我们需要初始化传感器并建立基线读数。
设置功能确保两个传感器都正确初始化。
由于两个传感器在不同的位置,它们的压力读数自然会不同。这种差异可能相当于高达8米的高度差异,因此我们首先计算一个初始参考差作为基线。
高度差是在ight()函数中计算的,稍后我们将使用该函数来检测运动。如果高度差大于10厘米,游戏将开始。
通过使用这两个DPS传感器,我们创造了一个直观的游戏启动机制。玩家不需要按下按钮或打开开关——当他们把锤子举得足够高时,游戏就会自动开始。
Part 2: Code for Whack!T游戏
显示屏设置为显示游戏时间和分数,而DPS和3D磁传感器分别用于检测举起锤子和成功击中。为了建立一个可靠的参考,在比赛开始前记录初始传感器值。
DPS传感器-检测当锤子被举起,信号的游戏开始。
3D磁传感器-跟踪撞击时,活塞被击中。
多半桥和执行器-控制弹出的活塞,让玩家击中。
压缩机—提供空气压力以移动活塞。
显示-显示比赛时间和比分更新。
设置
在操作开始之前,需要初始化系统的所有组件。setup()函数负责这一点,准备显示器、传感器和执行器。
显示屏设置为显示比赛时间和分数,而DPS和3D传感器配置为检测锤的运动和成功命中。为了建立一个可靠的参考,在游戏开始之前记录初始传感器值(measure_initial_values())。控制负责移动活塞的执行器的多半桥(MHB)通电,压缩机开始积聚空气压力(kompressor.start()),确保活塞能够正常移动。
短暂的延迟可以让所有组件在游戏进入主循环之前稳定下来。几个关键文件管理游戏的不同方面:display.hpp处理显示功能,airpressure_sensor.hpp处理来自空气压力传感器的数据,3d_sensor.hpp检测圆柱体何时被击中,push.hpp控制执行器,game_matrix.hpp管理活塞运动的核心游戏逻辑。
GameLoop
一旦设置好一切,游戏便进入主循环,在此它将持续监视玩家的行动,更新显示内容并管理游戏逻辑。
游戏如何在循环中运行:
1️游戏计时器管理
函数getRemainingSeconds()检查还剩下多少时间。
如果游戏处于活动状态(start_counting == true)并且还有剩余时间,它会在屏幕上显示倒计时。
如果计时器达到零,游戏将存储最终分数,重置命中计数器,并为新一轮做好准备。
2️.命中检测与计分
命中检测是基于磁场的变化。当气缸的顶部位置与其当前位置之间的差值超过0.1 mT时,将记录命中(compare_difference(piston_now, 0.1))。
分数是用game_hit_counter实现的。
3️.气缸体爆破机构
游戏使用calculate_average(piston_now)连续检查活塞运动。
一旦检测到撞击,系统随机选择一个活塞(1到10),并使用push(random(1,10))激活它。
这让游戏变得不可预测,确保玩家不知道下一个圆柱体会弹出哪个圆柱体,从而保持他们的沉浸感。
4️ .游戏结束并重新开始
如果计时器跑完,将显示最终分数,游戏将等待锤子再次被举起,然后重新开始。
这种平滑的过渡确保了无缝的游戏体验,而无需额外的按钮或手动重置。
倒数计时器
正常!游戏采用倒计时计时器,确保每回合持续固定时间(15秒)。getRemainingSeconds()函数通过测量游戏开始后经过的毫秒数来计算剩余时间。如果经过的时间超过倒计时持续时间,则返回0。
开始新游戏
在start_game()函数中,我们检查游戏是否处于非活动状态(start_counting ==false),然后启动倒计时。当倒计时达到0时,游戏开始,记录开始时间(startMillis),设置游戏持续时间,并启用倒计时。
该系统确保平稳和自动启动,无需手动输入。
现在我们可以结束了!所以T游戏代码,一切就绪,游戏就准备开始了!拿你的锤子瞄准一些汽缸!!
本文编译自hackster.io