基于Arduino制作這款打地鼠的街機(jī)游戲
你有沒有覺得有必要吹掉一些蒸汽,釋放你內(nèi)心的孩子,或者只是重溫從你的街機(jī)輝煌的日子粉碎東西的快感?進(jìn)入正常!這款游戲是對經(jīng)典打地鼠游戲的高科技改造,融合了懷舊和工程學(xué)。
我們從頭開始制作這款街機(jī)游戲:一個激光切割的木制盒子,里面裝著九個氣缸。但這不僅僅是蠻力,我們用磁鐵和3D磁傳感器取代了傳統(tǒng)的機(jī)械開關(guān),使撞擊檢測快速而精確。當(dāng)然,我們也不能只使用自己3D打印的錘子,這樣就能承受最激烈的游戲玩法。我們還提供了完整的構(gòu)建指南:組裝、編碼和校準(zhǔn)。準(zhǔn)備好開始了嗎?
游戲概述
在嘉年華上玩過打地鼠嗎?假鼴鼠會從不同的洞里鉆出來每次鉆出來,你就試著敲它。正常!《T》將這一概念現(xiàn)代化:玩家擊碎由壓縮空氣驅(qū)動的隨機(jī)彈出的9個氣動活塞。但這不是你爺爺?shù)慕謾C(jī)游戲:
智能命中檢測:活塞上的磁鐵與英飛凌最新系列的TLE493D磁性傳感器相互作用,取代機(jī)械開關(guān),實(shí)現(xiàn)即時、精確的命中。
自動游戲流程:xmc4700 Relax Lite kit微控制器套件是游戲的大腦,并使用OPTIGA?TrustMsecurity芯片隨機(jī)化活塞定時?;钊臍鈩娱y由使用單芯片的TLE94112ES 12倍半橋控制!最重要的是,游戲中的DPS368壓力傳感器和3d打印的錘子會在錘子被舉起時觸發(fā)游戲開始。
時間和得分跟蹤:一個雙位數(shù)的7段顯示剩余的比賽時間和你的最終得分。
它是如何工作的
開始:舉起錘子→DPS368測量錘子與游戲底座的高度差,觸發(fā)游戲開始倒計時5秒。
播放:15秒倒計時開始→OPTIGA?Trust M芯片隨機(jī)分配活塞→TLE94112ES激活閥門→活塞彈出。
得分:敲擊活塞→TLE493D檢測磁感應(yīng)→XMC4700點(diǎn)燃下一個活塞并增加得分。
接下來是什么?我們將開始建立和測試9活塞氣動系統(tǒng),然后整合3D磁傳感機(jī)制,添加雙7段顯示,最后我們3D打印智能錘子和組裝成一個拋光街機(jī)準(zhǔn)備的游戲。
硬件
氣動系統(tǒng):
此版本中的氣動系統(tǒng)基于Hackster項目:使用單個芯片驅(qū)動氣動系統(tǒng)。按照這個指南來創(chuàng)建你的主干!T游戲。
步驟2:將氣動系統(tǒng)變?yōu)榛顒踊钊?/strong>
為了準(zhǔn)備傳感器測試,我們現(xiàn)在將轉(zhuǎn)向組裝。確保所有的激光切割部件和3d打印部件都準(zhǔn)備好了,因?yàn)閺默F(xiàn)在開始,它們將在每一步中使用(請參閱附件中的設(shè)計文件)。
讓我們從組裝活塞外殼開始,它由激光切割的部件與9個活塞和傳感器的切口粘合在一起。之后,我們放置3d打印的活塞導(dǎo)軌,將它們鎖定在適當(dāng)?shù)奈恢茫乐剐D(zhuǎn)。我們還增加了一些填充物的活塞支持,以幫助吸收沖擊。
接下來,我們將9個活塞放入各自的插槽中,并將磁鐵粘在它們身上,因?yàn)樗鼈儗⒃诮酉聛淼臉?gòu)建中發(fā)揮重要作用。請注意,在照片中,我們也組裝了側(cè)墻,這是激光切割,也可以附加在最后的組裝。
接下來,我們放置9個活塞墊,擰緊支撐活塞的木板。這塊板作為運(yùn)動活塞和氣動系統(tǒng)之間的中間層。最后,你可以把活塞系統(tǒng)安裝到氣動系統(tǒng)上,就可以進(jìn)行測試了。
現(xiàn)在你已經(jīng)成功地制造了活塞和氣動系統(tǒng)!隨后,我們將添加OPTIGA?Trust M芯片來隨機(jī)化活塞行為。你會注意到活塞的木制外殼上有一些切口。這些切口是為3D磁傳感器的支架設(shè)計的
3D磁傳感器可以測量三個方向的磁場:X, Y和z。我們將在9個活塞之間放置4個傳感器,這樣就可以檢測到任何一個活塞受到撞擊時磁場的變化。
在圓柱體的底部,我們放置了磁鐵。這些磁鐵能讓我們探測到圓柱體被擊中的時間。
磁鐵被放置在盡可能靠近3D磁傳感器的地方,以確保磁場足夠強(qiáng),能夠被準(zhǔn)確檢測到。對于傳感器,我們使用3D磁傳感器的切割板。在附件的Fritzing文件中提供了接線說明。
四個傳感器安裝在支架上,如下圖所示。
現(xiàn)在,我們可以把傳感器支架放在氣動系統(tǒng)里。
為了使組裝更實(shí)用,我們創(chuàng)建了一個帶連接器的小板。布線如圖所附的fritz文件所示;按照這些方法進(jìn)行正確的連接。
現(xiàn)在我們可以把底板與9個氣缸在組裝和關(guān)閉一切的頂部。有了這一步,游戲的機(jī)制部分就完成了,可以進(jìn)行測試了。
最后,我們可以測試9個活塞和磁傳感器(測試代碼在附件文件中提供)。之后,我們可以移動到7段屏幕的顯示部分。
分?jǐn)?shù)顯示
我們使用兩個相互連接的7段數(shù)字來顯示游戲中的剩余時間和最終比分。我們將把顯示器安裝在“搞怪!”T游戲,這是設(shè)計來保持它。開始組裝激光切割的木制部件如下所示。一旦框架準(zhǔn)備好,將7段顯示器安裝到木板上,并通過木板布線,在那里它們將連接到XMC微控制器。
讓錘子更聰明
錘子是擊打的關(guān)鍵部分!T游戲。為了檢測錘子何時被舉起,我們使用了兩個DPS368空氣壓力傳感器:一個傳感器放置在錘子內(nèi)部。另一個被放置在里面!T框作為參考。
通過測量兩個傳感器之間的壓力差,我們可以測量錘與游戲之間的高度差,精度為±2厘米,并檢測錘何時被舉起。壓力傳感器接線圖在工程文件中提供。
對于錘子組件,您可以使用提供的3d打印部件。stl文件。這里有一些建議:水平打印錘子以獲得更好的穩(wěn)定性。將填充量增加到50%以增加重量和提高耐久性,將壁厚增加到2.4mm以增加堅固性。在電纜隧道區(qū)域(錘身)增加支架擋塊,避免支架難以拆除。
錘子由三部分組成:主錘體和兩個柔性TPU帽。這些蓋子可以在激烈的游戲過程中保護(hù)游戲免受損害。
在錘子的頂部,有放置DPS368壓力傳感器的空間。只需將傳感器推到位,如下圖所示:
另一個傳感器可以放置在任何地方。T游戲基地。
推動游戲發(fā)展
XMC4700放松套件需要5 V電源,顯示器工作在12 V,壓縮機(jī)和閥門都需要9 V電源。為了實(shí)現(xiàn)必要的電壓轉(zhuǎn)換,需要一個降壓轉(zhuǎn)換器從9v降壓到5v,從9v升壓到12v
為此,我們使用兩個TLD5190 VOLT DEMO評估板。這些板允許您通過調(diào)整板上微調(diào)器來選擇所需的輸出電壓。有關(guān)設(shè)置和使用這些評估板的詳細(xì)說明,TLD5190 VOLT DEMO評估板的用戶手冊提供了全面的解釋。
你可以通過向左轉(zhuǎn)動微調(diào)器來增加電壓,通過向右轉(zhuǎn)動來降低電壓。
軟件
現(xiàn)在讓我們一步一步地分解我們的Arduino代碼!首先,我們將闡明如何單獨(dú)使用和測試每個組件,然后我們將解釋整個應(yīng)用程序代碼的Whack!T游戲。
第1部分:組件代碼
7段顯示代碼
游戲開始前會出現(xiàn)5秒倒計時。游戲在這個倒計時后開始,另一個15秒倒計時從那里開始。在這段時間里,你必須盡可能多地打汽缸。在第二次倒計時結(jié)束時,你的最終得分顯示-所有這些都是使用7段顯示。為了測試這兩個7段數(shù)字,我們使用了下面的示例代碼。我們所做的唯一修改是將引腳分配更改為50 (segmentLatch), 51 (segmentData)和52 (segmentClock)。
代碼Optiga?信任M盾2go
Optiga?Trust M芯片在這里用于生成(真實(shí)且加密安全的)1到9之間的隨機(jī)值,這是我們項目中的關(guān)鍵一步,因?yàn)樗鼨z測到哪個圓柱體會彈出,使游戲變得不可預(yù)測和具有挑戰(zhàn)性。但在此之前,我們需要了解芯片的工作原理。
我們首先修改Optiga?Trust M Arduino庫中的一個示例,使其適應(yīng)我們的需求。首先,讓我們看一下這段代碼的基礎(chǔ):
頭文件和定義
要開始,我們需要包含“OPTIGATrustM.h”庫,它使我們能夠訪問TrustM功能。我們定義了隨機(jī)數(shù)生成的最大字節(jié)長度-將其設(shè)置為8確保我們一次可以生成最多8個隨機(jī)字節(jié)。
一個額外的調(diào)整:默認(rèn)代碼包括彩色輸出(來自“fprint.h”),但為了簡單起見,我們選擇禁用它。
設(shè)置函數(shù)
一切就緒后,是時候初始化芯片了。setup功能確保Trust M板準(zhǔn)備好生成安全隨機(jī)數(shù)。
這里有一個有趣的特性是電流限制——這個設(shè)置會影響主板的運(yùn)行速度。如果我們增加電流限制,電路板就會加速。對于這個設(shè)置,我選擇了8 mA的限制(setCurrentLimit(8)),以便在性能和穩(wěn)定性之間取得更好的平衡。
循環(huán)函數(shù):生成隨機(jī)數(shù)
每次循環(huán)運(yùn)行時,Optiga?Trust M模塊通過函數(shù)getRandom(RND_MAXLENGTH, rnd)提供8字節(jié)的隨機(jī)數(shù)據(jù)。但是我們需要一個介于1和9之間的數(shù)字,因此我們將原始字節(jié)數(shù)組轉(zhuǎn)換為int64_t數(shù)字(convertByteArrayToInt64()),并使用對9 + 1取模將其映射到我們想要的范圍。這確保了我們總是在目標(biāo)范圍內(nèi)得到結(jié)果。
結(jié)果看起來像這樣:
3D磁傳感器代碼
這部分在我們的Hackster文章中有很好的記錄:下一代TLE493D: 3D磁感測指南,但對于這個特定的項目,我們需要使其適應(yīng)XMC4700微控制器。
在深入游戲機(jī)制之前,我們需要測試所有四個傳感器,以驗(yàn)證它們是否正確連接和運(yùn)行。下面的代碼是專門為快速診斷設(shè)計的,允許我們檢查每個傳感器是否可操作。使用四個#define語句,我們可以激活或停用單個傳感器以進(jìn)行測試。我們還定義了numavg,它決定了在計算平均值之前測量每個傳感器的次數(shù)。
平均傳感器值
一旦初始化,循環(huán)函數(shù)不斷地從傳感器讀取數(shù)據(jù)。函數(shù)average_sensor_value()測量多個讀數(shù)的值并取平均值,以獲得更穩(wěn)定的輸出。
傳感器的內(nèi)置函數(shù)getTemperature()和getMagneticField()用于提取數(shù)據(jù),而計時函數(shù)測量收集50個值所需的時間。
ps傳感器代碼
在我們的比賽中,時機(jī)就是一切。在玩家準(zhǔn)備好之前,游戲不應(yīng)該開始——這就是DPS傳感器的作用所在。這些傳感器用于檢測錘子何時被舉起,發(fā)出倒計時開始的信號。
為了實(shí)現(xiàn)這一點(diǎn),我們使用了兩個DPS傳感器:一個傳感器放置在錘子內(nèi)部來跟蹤它的運(yùn)動。
第二個傳感器仍然固定在打!T設(shè)置,作為參考點(diǎn)。
關(guān)于如何使用傳感器的詳細(xì)解釋也可以在這篇Hackster文章中找到,但這里是我們?nèi)绾卧谖覀兊捻椖恐袑?shí)現(xiàn)它。
頭文件和對象
Dps3xx.h包含在#include中,創(chuàng)建兩個Dps傳感器對象:
設(shè)置/循環(huán)
在我們追蹤錘子的運(yùn)動之前,我們需要初始化傳感器并建立基線讀數(shù)。
設(shè)置功能確保兩個傳感器都正確初始化。
由于兩個傳感器在不同的位置,它們的壓力讀數(shù)自然會不同。這種差異可能相當(dāng)于高達(dá)8米的高度差異,因此我們首先計算一個初始參考差作為基線。
高度差是在ight()函數(shù)中計算的,稍后我們將使用該函數(shù)來檢測運(yùn)動。如果高度差大于10厘米,游戲?qū)㈤_始。
通過使用這兩個DPS傳感器,我們創(chuàng)造了一個直觀的游戲啟動機(jī)制。玩家不需要按下按鈕或打開開關(guān)——當(dāng)他們把錘子舉得足夠高時,游戲就會自動開始。
Part 2: Code for Whack!T游戲
顯示屏設(shè)置為顯示游戲時間和分?jǐn)?shù),而DPS和3D磁傳感器分別用于檢測舉起錘子和成功擊中。為了建立一個可靠的參考,在比賽開始前記錄初始傳感器值。
DPS傳感器-檢測當(dāng)錘子被舉起,信號的游戲開始。
3D磁傳感器-跟蹤撞擊時,活塞被擊中。
多半橋和執(zhí)行器-控制彈出的活塞,讓玩家擊中。
壓縮機(jī)—提供空氣壓力以移動活塞。
顯示-顯示比賽時間和比分更新。
設(shè)置
在操作開始之前,需要初始化系統(tǒng)的所有組件。setup()函數(shù)負(fù)責(zé)這一點(diǎn),準(zhǔn)備顯示器、傳感器和執(zhí)行器。
顯示屏設(shè)置為顯示比賽時間和分?jǐn)?shù),而DPS和3D傳感器配置為檢測錘的運(yùn)動和成功命中。為了建立一個可靠的參考,在游戲開始之前記錄初始傳感器值(measure_initial_values())??刂曝?fù)責(zé)移動活塞的執(zhí)行器的多半橋(MHB)通電,壓縮機(jī)開始積聚空氣壓力(kompressor.start()),確?;钊軌蛘R苿?。
短暫的延遲可以讓所有組件在游戲進(jìn)入主循環(huán)之前穩(wěn)定下來。幾個關(guān)鍵文件管理游戲的不同方面:display.hpp處理顯示功能,airpressure_sensor.hpp處理來自空氣壓力傳感器的數(shù)據(jù),3d_sensor.hpp檢測圓柱體何時被擊中,push.hpp控制執(zhí)行器,game_matrix.hpp管理活塞運(yùn)動的核心游戲邏輯。
GameLoop
一旦設(shè)置好一切,游戲便進(jìn)入主循環(huán),在此它將持續(xù)監(jiān)視玩家的行動,更新顯示內(nèi)容并管理游戲邏輯。
游戲如何在循環(huán)中運(yùn)行:
1?游戲計時器管理
函數(shù)getRemainingSeconds()檢查還剩下多少時間。
如果游戲處于活動狀態(tài)(start_counting == true)并且還有剩余時間,它會在屏幕上顯示倒計時。
如果計時器達(dá)到零,游戲?qū)⒋鎯ψ罱K分?jǐn)?shù),重置命中計數(shù)器,并為新一輪做好準(zhǔn)備。
2?.命中檢測與計分
命中檢測是基于磁場的變化。當(dāng)氣缸的頂部位置與其當(dāng)前位置之間的差值超過0.1 mT時,將記錄命中(compare_difference(piston_now, 0.1))。
分?jǐn)?shù)是用game_hit_counter實(shí)現(xiàn)的。
3?.氣缸體爆破機(jī)構(gòu)
游戲使用calculate_average(piston_now)連續(xù)檢查活塞運(yùn)動。
一旦檢測到撞擊,系統(tǒng)隨機(jī)選擇一個活塞(1到10),并使用push(random(1,10))激活它。
這讓游戲變得不可預(yù)測,確保玩家不知道下一個圓柱體會彈出哪個圓柱體,從而保持他們的沉浸感。
4? .游戲結(jié)束并重新開始
如果計時器跑完,將顯示最終分?jǐn)?shù),游戲?qū)⒌却N子再次被舉起,然后重新開始。
這種平滑的過渡確保了無縫的游戲體驗(yàn),而無需額外的按鈕或手動重置。
倒數(shù)計時器
正常!游戲采用倒計時計時器,確保每回合持續(xù)固定時間(15秒)。getRemainingSeconds()函數(shù)通過測量游戲開始后經(jīng)過的毫秒數(shù)來計算剩余時間。如果經(jīng)過的時間超過倒計時持續(xù)時間,則返回0。
開始新游戲
在start_game()函數(shù)中,我們檢查游戲是否處于非活動狀態(tài)(start_counting ==false),然后啟動倒計時。當(dāng)?shù)褂嫊r達(dá)到0時,游戲開始,記錄開始時間(startMillis),設(shè)置游戲持續(xù)時間,并啟用倒計時。
該系統(tǒng)確保平穩(wěn)和自動啟動,無需手動輸入。
現(xiàn)在我們可以結(jié)束了!所以T游戲代碼,一切就緒,游戲就準(zhǔn)備開始了!拿你的錘子瞄準(zhǔn)一些汽缸!!
本文編譯自hackster.io