HOME / 第 3 部分 · 2D 游戏开发实战 / 第 30 课
MODULE 3 · 2D 游戏开发实战
第 30 课 · 平台跳跃小游戏综合实战(一)
🎯 本课学习目标
- 综合运用第 1-29 课所有知识
- 完成一个可玩的平台跳跃小游戏
- 学会独立组织游戏项目结构
检验成果的时刻!本课把之前学的一切整合成一个完整平台跳跃小游戏。建议一边做一边复习前面课程。
📖 详细教学步骤
游戏设计(先想清楚)设计
目标:一个极简平台跳跃小游戏
- 玩家:左右移动 + 跳跃
- 地形:TileMap 地面与平台
- 目标:吃到全部金币即通关
- 危险:碰到敌人扣命,命尽游戏结束
- UI:分数/命/通关提示
项目结构规划搭建
文件夹规划:
项目根目录/
├── scenes/
│ ├── main.tscn # 主场景
│ ├── player.tscn # 玩家
│ ├── enemy.tscn # 敌人
│ ├── coin.tscn # 金币
│ └── hud.tscn # UI
├── scripts/
│ ├── main.gd / player.gd / ...
└── assets/
├── images/ (图片)
└── audio/ (音频)依次创建各场景集成
- player.tscn:CharacterBody2D + Sprite2D + CollisionShape2D + player.gd(第 21/26 课代码)
- enemy.tscn:CharacterBody2D + 巡逻 AI + 攻击 Area2D(第 24/26 课)
- coin.tscn:Area2D + CollisionShape2D + 加分逻辑(第 27 课)
- hud.tscn:CanvasLayer + 分数 Label + 命数 Label + 结束面板(第 27/28 课)
- main.tscn:TileMap 地形 + 实例化玩家/敌人/金币/HUD + main.gd 总控
补全游戏总控逻辑代码
main.gd 统一管理游戏流程:
GDSCRIPTextends Node2D
var coin_total: int = 0
var coin_collected: int = 0
@onready var hud = $HUD
@onready var player = $Player
func _ready():
coin_total = get_tree().get_nodes_in_group("coin").size()
player.died.connect(_on_player_died)
func _on_coin_collected():
coin_collected += 1
if coin_collected >= coin_total:
hud.show_win() # 通关
func _on_player_died():
hud.show_game_over()
get_tree().paused = true
金币与敌人加入分组操作
- 金币根节点加入组
coin - 玩家加入组
player - 这样 get_nodes_in_group("coin") 能统计金币数量
测试并调优手感测试
- F5 运行,完整玩一遍:移动 → 跳平台 → 吃金币 → 被敌人碰到 → 重开
- 调手感:speed/gravity/jump_velocity 微调
- 调视觉:背景色、UI 字体、金币大小
- 把所有报错修复(看底部输出面板)
🎉 你完成了人生第一个完整小游戏!
⚠️
金币吃不完/统计不对?
确认所有金币都在 coin 组里,且 main.gd 在 _ready 里统计总数(实例化完成后再统计)。
⚠️
重开后金币又全回来了?
正常!reload_current_scene 会把场景重置为初始状态。这正是「重新开始」的语义。
🧪 动手试一试
🏋️ 课后练习
在游戏里增加一个「计时器」:记录通关用时,通关时显示用时。
main.gd 里 var time=0; _process 里 time+=delta; 通关时显示 str(time) 秒。
💡
做完一版先玩 3 遍,记录不舒服的地方再改。
💡
把报错截图/复制到搜索引擎,是解决 BUG 的好习惯。
🎓 本课小结
完整小游戏 = 玩家 + 敌人 + 金币 + HUD + 主场景总控。分组统计、信号通信、状态管理全部用上,你已经能独立做小游戏了!