从零打造Godot 2D射击游戏全记录
摘要: 作者Briana分享了使用Godot 4.3开发2D像素射击游戏《丛林探险》的全过程。项目采用模块化设计,通过GDScript实现角色控制、动画状态机、碰撞检测和对象池优化,并利用CanvasLayer构建UI系统。文章详细介绍了技术实现细节,包括多平台导出和itch.io发布经验,并开源项目代码。作者认为Godot凭借轻量、开源等特性非常适合独立开发者,未来计划扩展关卡和技能系统。项目地
【我的第一个开源项目】从零到一:用Godot打造2D射击游戏《丛林探险》全记录
作者:Briana
首发平台:GitCode
转载条件:发文满3个工作日后可转
引言:为什么选择Godot?
在游戏开发的世界中,引擎的选择往往决定了开发者的创作路径。Unity、Unreal 固然强大,但对于独立开发者和小团队来说,Godot 以其轻量、开源、跨平台和高度自由的特性,正逐渐成为不可忽视的选择。
今年初,我决定用 Godot 4.3 开发我的第一个完整游戏项目——《丛林探险》。这是一个2D像素风格的射击游戏,玩家扮演一只小狐狸,在森林中射击不断出现的史莱姆敌人。从零开始,我完整经历了场景搭建、角色控制、动画系统、碰撞检测、UI设计、音效集成、性能优化、多平台导出等全流程。
本文将分享我从零开始构建这个开源项目的完整过程,包括技术选型、核心实现、踩坑经验与开源感悟。
一、项目架构设计
1.1 场景树结构与节点设计
Godot 的核心设计理念是“一切皆节点”。在《丛林探险》中,我构建了清晰的场景树结构:
text
- Main (Node2D)
- Camera2D
- Background (Sprite2D)
- Player (CharacterBody2D)
- Boundary (StaticBody2D)
- CanvasLayer (UI)
- GameManager (Node)
- Timer (Spawner)
每个场景(如 Player、Slime、Bullet)都独立存储,便于复用与维护。这种模块化设计让我在后期调试和扩展功能时游刃有余。
1.2 代码结构:GDScript 与信号系统
Godot 自带的 GDScript 语法类似 Python,上手快,与引擎高度集成。我使用 @export 暴露变量到编辑器,使用 signal 实现节点间通信。
例如,玩家死亡时发出信号,由 GameManager 统一处理:
gdscript
# Player.gd
signal player_died
func game_over():
emit_signal("player_died")
is_game_over = true
$AnimatedSprite2D.play("game_over")
$GameOverSound.play()
二、核心技术实现
2.1 角色控制与动画状态机
玩家控制采用 CharacterBody2D,配合 _physics_process 实现平滑移动:
gdscript
func _physics_process(delta):
if not is_game_over:
var input_vector = Input.get_vector("left", "right", "up", "down")
velocity = input_vector * move_speed
move_and_slide()
# 动画控制
if velocity != Vector2.ZERO:
$AnimatedSprite2D.play("run")
else:
$AnimatedSprite2D.play("idle")
动画系统使用 AnimatedSprite2D,支持 Sprite Sheet 自动切割与帧动画播放。我为其设计了 idle、run、game_over 三种状态,并通过代码动态切换。
2.2 碰撞检测与分组系统
Godot 的碰撞系统非常灵活。我为子弹和敌人设置了分组(Group),便于检测碰撞:
gdscript
# Bullet.gd
func _on_area_entered(area):
if area.is_in_group("enemy"):
area.take_damage()
queue_free()
2.3 对象池与性能优化
随着子弹和敌人数量增加,频繁实例化与销毁节点会严重影响性能。我使用 queue_free() 结合 Timer 实现自动回收:
gdscript
# Bullet.gd
func _ready():
await get_tree().create_timer(3.0).timeout
queue_free()
同时,通过检测敌人是否超出屏幕范围来及时销毁,避免内存泄漏。
三、UI 与游戏逻辑
3.1 使用 CanvasLayer 构建 UI
Godot 的 UI 系统与游戏场景分离,我使用 CanvasLayer 来显示得分和游戏结束画面:
gdscript
# GameManager.gd
@export var score_label: Label
@export var game_over_label: Label
func update_score():
score_label.text = "Score: " + str(score)
func show_game_over():
game_over_label.visible = true
3.2 游戏管理器:全局状态控制
GameManager 负责生成敌人、计分、控制游戏流程:
gdscript
func _on_timer_timeout():
var slime = slime_scene.instantiate()
slime.position = Vector2(265, randf_range(52, 116))
get_tree().current_scene.add_child(slime)
四、音效与背景音乐
Godot 的 AudioStreamPlayer 节点支持 2D/3D 音效。我为射击、死亡、脚步声等分别配置了音效,并使用 AutoLoad 让 BGM 在场景重载时不中断:
gdscript
# BGM.gd (AutoLoad)
func _ready():
$AudioStreamPlayer.play()
五、多平台导出与发布
5.1 导出设置与模板安装
在 Godot 中导出游戏非常简单,只需安装对应平台的导出模板,配置好分辨率与拉伸模式,即可一键导出 Windows、Web、Linux 等版本。
5.2 发布到 itch.io
我将 Web 版本打包为 index.html,上传到 itch.io,并配置为 HTML5 项目。Windows 版本则直接上传为可下载文件。
六、开源感悟与后续计划
这个项目不仅让我掌握了 Godot 的基本用法,更让我体会到开源协作的魅力。我将完整项目源码上传至 GitCode,欢迎任何人对代码提出建议、提交 PR 或复用到自己的项目中。
未来我计划为游戏添加:
-
多关卡系统
-
敌人类型多样化
-
技能系统
-
本地化语言支持
结语
《丛林探险》虽然是一个简单的 2D 游戏,但它涵盖了一个完整游戏项目的所有核心环节。从场景搭建到代码编写,从动画设计到性能优化,每一步都是对游戏开发流程的深入理解。
如果你也想尝试游戏开发,Godot 是一个绝佳的起点。它不仅免费开源,还拥有活跃的社区和丰富的文档。希望我的项目能为你带来灵感,也欢迎你在 GitCode 上与我交流。
项目地址:https://gitcode.com/Brianna_Home/my-frist-game
在线试玩:https://brianna-home.itch.io/forest-adventure
更多推荐


所有评论(0)