第 21 课 · CharacterBody2D:重力与跳跃
🎯 本课学习目标
- 掌握 CharacterBody2D 的移动规范
- 实现重力、跳跃与落地
- 理解 velocity 与 move_and_slide 机制
CharacterBody2D 是做「角色」的专用物理体。本课实现完整的平台跳跃角色:重力、跳跃、左右移动。
📖 详细教学步骤
准备玩家场景搭建
新建场景,根节点为 CharacterBody2D,命名 Player,保存 player.tscn;子节点:Sprite2D(角色图)+ CollisionShape2D(胶囊形);给根节点挂脚本 player.gd。
💡 CharacterBody2D 的核心是手动维护 velocity 再调用 move_and_slide()。
物理移动核心:velocity + move_and_slide概念
CharacterBody2D 的移动规范:把速度存在内置 velocity 里,每帧调用 move_and_slide() 执行移动+碰撞。
GDSCRIPTextends CharacterBody2D
@export var speed: float = 200.0
@export var gravity: float = 980.0 # 重力加速度
@export var jump_velocity: float = -400.0 # 起跳速度(负=向上)
func _physics_process(delta):
# 1) 始终加重力(在地面时不加)
if not is_on_floor():
velocity.y += gravity * delta
# 2) 水平移动
var dir = Input.get_axis("move_left", "move_right")
velocity.x = dir * speed
# 3) 跳跃:按跳跃键且在地面上
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_velocity
# 4) 执行移动(处理碰撞)
move_and_slide()
创建跳跃输入映射操作
项目设置 → 输入映射中创建动作:
jump:绑定空格键 Spacemove_left:绑定 A / ←move_right:绑定 D / →
💡 Input.get_axis("move_left","move_right") 返回 -1~1:按左=-1、按右=1、都不按=0,斜向也不会有问题。
了解 is_on_floor 等状态检测概念
is_on_floor():是否站在地面上is_on_wall():是否贴着墙is_on_ceiling():是否顶着天花板
这些由 move_and_slide() 每帧自动更新。
搭测试平台并运行集成
- main.tscn 里放 StaticBody2D 地面(矩形碰撞 + 可视化颜色块),把玩家实例放上去
- F5 运行:左右移动、空格跳跃、落地
- 若跳不起来:检查 jump 动作是否创建、是否 is_on_floor
🎉 经典平台跳跃手感达成!
正常,有重力就该掉。需要地面 StaticBody2D + CollisionShape2D 挡住。若穿透,检查地面碰撞形状是否在玩家下方且足够宽。
调 jump_velocity(越负跳越高)和 gravity(越大落得越快)。推荐先试 jump_velocity=-400、gravity=980。
把 CollisionShape2D 适当调小,或调整 floor_max_angle。
🧪 动手试一试
🏋️ 课后练习
实现「二段跳」:在空中再按一次跳跃能再跳一次(最多二段)。
var jump_count=0; 落地时 jump_count=0; 起跳条件为按下跳跃且 (is_on_floor() or jump_count<2),起跳时 jump_count+=1。
velocity 是内置属性,直接赋值即可。
重力 980 是默认值,轻快手感调小、沉重手感调大。
🎓 本课小结
CharacterBody2D 规范:维护 velocity → 加重力 → 设水平速度 → 判断跳跃 → move_and_slide();用 is_on_floor() 判断落地。