【20 Games 挑戰 #2】《Jetpack Joyride》
遊戲簡介
這是一款 2011 年推出的經典手機遊戲,其特色是單一按鍵操作:
- 按住時角色上升,放開時角色會自然下墜
- 地圖會自動向左捲動,障礙從右側生成
- 玩家需閃避電網、飛彈,並盡可能遠行、收集金幣
連結為原始遊戲影片:
成果分享
這是「20 款遊戲挑戰」中的第 2 步,過程中學習以下:
- 重複利用前一款的資料或程式碼
- 儲存高分的機制
- 加入簡單音效(包含跑步、噴射、受傷)
- 加入粒子效果(例如噴射火焰)
0:00
/0:18
點選以下連結試玩:
噴射背包 by Peter_kncok_code
Play in your browser
場景架構總覽
以下是我用 Godot 建立的場景結構:
┖╴Main
┠╴background2D (Node2D):背景群組,用來包含多層捲動背景
┃ ┠╴background1 (Sprite2D):第一張背景圖,用來做視差捲動
┃ ┖╴background2 (Sprite2D):第二張背景圖,與 background1 輪流重複
┠╴Player (CharacterBody2D):玩家角色,負責控制移動與碰撞
┃ ┠╴CollisionShape2D (CollisionShape2D):碰撞框
┃ ┠╴AnimatedSprite2D (AnimatedSprite2D):角色動畫(跑步、跳躍等)
┃ ┠╴CPUParticles2D (CPUParticles2D):噴射粒子效果(噴射火焰)
┃ ┠╴RunAudio (AudioStreamPlayer2D):跑步聲音
┃ ┠╴JetAudio (AudioStreamPlayer2D):噴射時的火焰音效
┃ ┖╴HurtAudio (AudioStreamPlayer2D):受傷音效(撞到陷阱、飛彈)
┠╴Ground (TileMapLayer):地板,由 tilemap 組成,會自動向左移動
┠╴Trap (Area2D):靜態陷阱(如電網),可與玩家碰撞觸發扣血
┃ ┠╴AnimatedSprite2D (AnimatedSprite2D):陷阱動畫(如電光)
┃ ┖╴CollisionShape2D (CollisionShape2D):陷阱碰撞框
┠╴CoinSpawner (Node):產生金幣群組的腳本控制器
┠╴TrapSpawner (Node):產生陷阱的控制器
┃ ┖╴MissileWarningSpawner (Node):追蹤玩家高度、先產生警告圖再發射飛彈
┠╴HUD (CanvasLayer):顯示 UI 分數、金幣、生命等資訊的畫面層
┃ ┠╴CoinLabel (Label):顯示目前取得的金幣數量
┃ ┠╴DistanceLabel (Label):顯示目前奔跑距離
┃ ┠╴HeartFull1 (Sprite2D):顯示目前剩餘血量的圖案(愛心)
┃ ┠╴HeartFull2
┃ ┠╴HeartFull3
┃ ┠╴HeartEmpty1 (Sprite2D):顯示已失去血量(灰色愛心)
┃ ┠╴HeartEmpty2
┃ ┠╴HeartEmpty3
┃ ┖╴JumpBtn (TouchScreenButton):手機版使用者點擊畫面跳躍(模擬空白鍵)
┖╴AudioStreamPlayer2D (AudioStreamPlayer2D):背景音樂播放器
小技巧補充:任意節點加上以下程式碼,可以打印出場景樹!
func _ready():
print_tree_pretty()
踩坑記錄與解法
TileMapLayer 產生地板
一開始用 StaticBody2D
+ add_child()
不斷新增地板,結果節點太多、效能下降。
改用 TileMapLayer
並動態平移與補格,達成無限捲動效果,效能大幅提升。
音效播放被 queue_free() 清除
角色受傷後要播放音效再消失,若直接寫:
func _on_body_entered(body):
if body.is_in_group("Player"):
audio_player.play()
queue_free()
結果聲音根本播不出來!因為節點馬上被刪掉了。
解法是先隱藏並關掉碰撞,等音效播完再刪除:
visible = false
$CollisionShape2D.disabled = true
audio_player.play()
audio_player.connect("finished", Callable(self, "queue_free"))
TouchScreenButton 必須設定 InputMap
我原本以為 TouchScreenButton
放上去就能按,但其實需要設定 action
為 ui_accept
,才能與空白鍵邏輯對應。
小結與下一步
這款《Jetpack Joyride》是我在「20 款遊戲挑戰」中的第二款作品,練習了粒子效果、簡單音效與 UI 設計,也在效能優化上學到不少技巧。
雖然還有可以再雕琢的地方,但在限定時間內完成預定功能,已經很滿足。這次的經驗會帶進下一款遊戲中。
這篇文章是我進行「20 款遊戲挑戰」的其中一站,目前已完成第 2 款,接下來將挑戰更多經典遊戲機制、動畫特效與關卡設計!
如果你對以下內容有興趣:
- Godot 遊戲開發實戰經驗
- 獨立遊戲創作的完整紀錄
也歡迎到 Threads 與我互動,一起交流開發心得。
彼得叩叩 (@peter_knock_code) • Threads, Say more
658 Followers • 0 Threads • 獨立遊戲開發 x 機器視覺工程師. See the latest conversations with @peter_knock_code.

— Peter