從零到一:用Godot打造我的第一款2D遊戲《叢林探險》 | 程序員節特輯

每一行代碼都是對邏輯世界的構建,每一個像素都是對想象力的具象。謹以此文,記錄我與Godot引擎的第一次親密接觸。

一、緣起:為什麼選擇Godot?

在遊戲開發的世界中,Unity、Unreal 等引擎如雷貫耳,而我卻選擇了一個相對“小眾”但極具潛力的開源引擎——Godot。它輕量、免費、跨平台,更重要的是,它擁有極其清晰的節點化場景結構和原生的 GDScript 語言支持,非常適合獨立開發者和小團隊快速原型開發。

我決定以一款2D像素風遊戲《叢林探險》作為我的第一個Godot項目,目標是實現一個具備移動、射擊、敵人AI、UI交互和音效的完整遊戲循環。


二、起步:場景、節點與腳本的三位一體

1. 場景樹的構建邏輯

Godot 的核心設計理念是“一切皆節點”。我將遊戲拆分為多個場景:

  • Game.tscn:主場景,包含背景、攝像機、空氣牆、敵人生成器等;
  • Player.tscn:玩家角色,包含動畫、碰撞體、子彈發射邏輯;
  • Slime.tscn:史萊姆敵人,具備移動、受擊、死亡動畫;
  • Bullet.tscn:子彈,具備飛行、碰撞檢測、自動銷燬機制。

這種模塊化設計不僅便於複用,也使得調試和維護變得清晰。

2. GDScript:Godot 的靈魂語言

我選擇 GDScript 作為開發語言。它語法類似 Python,簡潔易讀,與引擎深度集成。例如,下面這段代碼實現了玩家的移動與動畫控制:

gdscript

@export var move_speed: float = 100
@onready var animator: AnimatedSprite2D = $AnimatedSprite2D

func _physics_process(delta):
    if not is_game_over:
        velocity = Input.get_vector("left", "right", "up", "down") * move_speed
        if velocity != Vector2.ZERO:
            animator.play("run")
        else:
            animator.play("idle")
        move_and_slide()

通過 @export 將變量暴露在檢查器中,便於實時調試;使用 _physics_process 保證物理計算的穩定性。


三、進階:信號、狀態與交互設計

1. 信號系統:解耦的利器

Godot 的信號機制讓我實現了玩家與敵人、子彈與敵人之間的鬆耦合通信。例如,當子彈擊中史萊姆時:

gdscript

func _on_area_entered(area):
    if area.is_in_group("bullet") and not is_dead:
        is_dead = true
        $DeathSound.play()
        $AnimatedSprite2D.play("death")
        await get_tree().create_timer(0.6).timeout
        area.queue_free()
        queue_free()

這種事件驅動的方式,讓邏輯流清晰且易於擴展。

2. 狀態管理:遊戲流程的控制

我在玩家腳本中引入了 is_game_over 布爾變量,用於控制遊戲狀態。當玩家撞到敵人時:

gdscript

func game_over():
    if not is_game_over:
        is_game_over = true
        $GameOverSound.play()
        animator.play("game_over")
        get_tree().current_scene.show_game_over()
        $RestartTimer.start()

配合 Timer 節點實現延時重啓,避免場景閃爍問題。


四、整合:UI、音效與性能優化

1. UI 系統的搭建

使用 CanvasLayer 節點實現獨立於遊戲場景的 UI 層,通過 Label 節點動態顯示分數:

gdscript

func _process(delta):
    score_label.text = "Score: " + str(score)

2. 音效與背景音樂

通過 AudioStreamPlayer 節點實現音效播放,並將 BGM 設置為“自動加載”,使其在場景重啓時不被中斷。

3. 性能優化實踐

  • 子彈和敵人超出屏幕後自動 queue_free()
  • 使用 clamp() 限制敵人生成速度;
  • 通過 Y Sort 實現圖層動態渲染;
  • 使用分組管理子彈與敵人的碰撞檢測。

五、發佈:從編輯器到可執行文件

1. 導出設置與模板配置

在“項目設置”中配置窗口拉伸模式為 canvas_items,支持全屏與自適應分辨率。通過“管理導出模板”下載對應平台模板,導出為 Windows 可執行文件與 Web 版本。

2. 上傳 itch.io 分享作品

將 Web 版本打包為 index.html 並上傳至 itch.io,設置運行環境為 HTML5,勾選“全屏支持”,即可在瀏覽器中暢玩。


六、回顧與展望:代碼與成長的雙重收穫

通過《叢林探險》這個項目,我不僅掌握了 Godot 的基本工作流,更深刻理解了以下關鍵點:

  • 節點化思維:將複雜系統拆解為可複用的場景與節點;
  • 信號驅動:降低耦合,提升代碼可維護性;
  • 狀態管理:合理控制遊戲流程與資源生命週期;
  • 性能意識:在開發初期就考慮資源管理與對象池機制。

未來,我計劃為遊戲加入更多功能:

  • 積分榜與存檔系統;
  • 多類型敵人與技能系統;
  • 關卡設計與劇情推進;
  • 粒子特效與光影增強。

結語:每一行代碼,都是與自我對話的過程

在這個項目中,我經歷了無數次的調試、重構與優化。每一次報錯都是學習的機會,每一次成功運行都是對堅持的回報。Godot 不僅是一個引擎,更是一個陪伴我成長的夥伴。