零基础也能照做:10 分钟做出“可左右移动+跳跃+收集金币”的 2D 小场景。文章给出节点树、资源占位、脚本模板和导出检查项,直接照抄即可跑通。
目标与准备
- 目标:角色可左右移动、跳跃,碰到金币会消失并计数,掉出平台会重生。
- 引擎版本:Godot 4.x。
- 素材:可用纯色方块代替(不需要美术),在 Inspector 设置
Texture为 ColorRect 或导入占位 PNG。
可运行的Demo项目在绑定资源中,可自行下载学习。
场景与节点结构
Level.tscn
└── Node2D (root)
├── TileMap # 地形/平台
├── Player (CharacterBody2D)
│ ├── Sprite2D
│ └── CollisionShape2D
├── CoinContainer (Node2D)
│ ├── Coin (Area2D)
│ │ ├── Sprite2D
│ │ └── CollisionShape2D
└── UI (CanvasLayer)
└── Label
说明:用
CanvasLayer做 UI,避免跟场景相机联动;金币用Area2D捕获进入事件。
快速搭建步骤
- 创建场景:新建
Level.tscn,Root 选Node2D。 - TileMap:
- 添加 TileMap,创建新 TileSet,添加一张占位方块纹理,定义碰撞形状。
- 在 2D 视图绘制平台(至少地面和几个台阶)。
- Player:
- 添加
CharacterBody2D命名 Player,子节点Sprite2D和CollisionShape2D(矩形即可)。 - 在 Inspector 设置
CollisionShape2D尺寸覆盖角色。
- 添加
- Coin:
- 在 CoinContainer 下添加
Area2D命名 Coin,子节点Sprite2D、CollisionShape2D(小圆形)。 - 复制 Coin 多个,放在平台上方。
- 在 CoinContainer 下添加
- UI:
- 添加
CanvasLayer→Label,锚点设为左上,文本初始金币:0。
- 添加
- 脚本:为 Player 和 Level 分别创建脚本,见下文。
- 运行:按 F6 运行当前场景,确认可操作。
Player.gd:可直接粘贴
extends CharacterBody2D
@export var move_speed := 220.0
@export var jump_speed := 420.0
@export var gravity := 1200.0
var velocity_y := 0.0
func _physics_process(delta: float) -> void:
var input_dir = Input.get_axis("ui_left", "ui_right")
velocity.x = input_dir * move_speed
# 重力
if not is_on_floor():
velocity_y += gravity * delta
else:
velocity_y = 0
if Input.is_action_just_pressed("ui_accept"):
velocity_y = -jump_speed
velocity.y = velocity_y
move_and_slide()
动作映射:默认
ui_left/ui_right/ui_accept对应左右方向键和空格,无需额外配置。若要手柄支持,可在 Project Settings → Input Map 再添加。
Level.gd:收集金币与重生
extends Node2D
@onready var player := $Player
@onready var coin_container := $CoinContainer
@onready var ui_label := $UI/Label
var coin_count := 0
var spawn_position := Vector2.ZERO
func _ready():
spawn_position = player.global_position
for coin in coin_container.get_children():
coin.body_entered.connect(_on_coin_collected.bind(coin))
func _on_coin_collected(body: Node, coin):
if body == player:
coin.queue_free()
coin_count += 1
ui_label.text = "金币:%d" % coin_count
func _process(_delta):
if player.global_position.y > 1200:
player.global_position = spawn_position
player.velocity = Vector2.ZERO
- 连接思路:遍历 Coin 容器统一绑定信号,避免逐个手动连。
- 重生逻辑:检测 y 坐标超界,重置位置与速度。
让 10 分钟更稳:3 个验证点
- 碰撞正常:在 2D 视图打开 “Visible Collision Shapes” 查看碰撞,确保 TileMap 与角色/金币都有形状。
- Input Map:若移动/跳跃无响应,检查 Project Settings → Input Map 的键位,或是否选中了非英文输入法。
- 节点引用:脚本路径
$UI/Label等必须匹配 Scene 树命名,改名后记得同步。
扩展:下一步怎么改成自己的 Demo
- 换美术:替换 Sprite2D 的纹理即可,碰撞尺寸记得调整。
- 相机跟随:给 Player 加
Camera2D设为 Current,限制边界防止露底色。 - 简单敌人:用
Area2D或CharacterBody2D做巡逻,碰撞玩家后重生。 - 存档分数:使用
FileAccess保存最高分,或ConfigFile简化结构。
导出前检查清单
- Project Settings → Display → Window 设置分辨率(如 1280×720),勾选
resizable取决于需求。 - Project → Export 添加目标平台模板(官方模板即可),测试打包后输入是否正常。
- Assets 命名与路径保持英文,避免打包路径问题。
可运行的Demo项目在绑定资源中,可自行下载学习。
结语
- 以上节点结构+脚本即是“最小可玩”2D Demo。关键在于:
CharacterBody2D控制、Area2D收集、CanvasLayerUI、Input Map 默认动作。 - 跑通一次后可迭代:加动画(AnimationPlayer/AnimatedSprite2D)、音效(AudioStreamPlayer)、相机(Camera2D)、更多关卡(多 TileMap 或加载 PackedScene)。

2135

被折叠的 条评论
为什么被折叠?



