HOME / 第 3 部分 · 2D 游戏开发实战 / 第 19 课
MODULE 3 · 2D 游戏开发实战
第 19 课 · 玩家角色移动(脚本控制)
🎯 本课学习目标
- 综合运用输入映射与位移实现角色移动
- 学会让角色朝向移动方向翻转
- 理解速度与加速度的平滑感
本课做一个真正能「操作」的玩家角色:用键盘控制它在屏幕上移动,并让精灵跟随方向翻转。
📖 详细教学步骤
准备场景结构搭建
- 新建场景,根节点用
Node2D,命名为Player,保存为 player.tscn - 添加子节点
Sprite2D,放入一张角色图片(第 17 课) - 选中 Player 根节点 → 附加脚本 player.gd
定义移动参数代码
在脚本顶部定义速度变量(可直接在检查器调):
GDSCRIPTextends Node2D
@export var speed: float = 300.0 # 导出变量:可在检查器调整
@onready var sprite: Sprite2D = $Sprite2D
读取方向输入代码
先确保项目设置有 move_up/down/left/right 四个动作(第 18 课)。读取方向:
GDSCRIPTfunc get_input_dir() -> Vector2:
var dir = Vector2.ZERO
if Input.is_action_pressed("move_up"):
dir.y -= 1
if Input.is_action_pressed("move_down"):
dir.y += 1
if Input.is_action_pressed("move_left"):
dir.x -= 1
if Input.is_action_pressed("move_right"):
dir.x += 1
return dir.normalized()
移动并翻转朝向代码
在 _physics_process 里移动,根据方向翻转精灵:
GDSCRIPTfunc _physics_process(delta):
var dir = get_input_dir()
position += dir * speed * delta
# 左右翻转朝向(向左时水平镜像)
if dir.x < 0:
sprite.flip_h = true
elif dir.x > 0:
sprite.flip_h = false
用加速度让移动更顺滑(进阶)进阶
直接赋值会「瞬移式」移动,加加速度更真实:
GDSCRIPTvar velocity = Vector2.ZERO
@export var accel: float = 1200.0
@export var friction: float = 800.0
func _physics_process(delta):
var dir = get_input_dir()
if dir != Vector2.ZERO:
# 朝输入方向加速
velocity = velocity.move_toward(dir * speed, accel * delta)
else:
# 无输入时减速
velocity = velocity.move_toward(Vector2.ZERO, friction * delta)
position += velocity * delta
让主场景调用玩家场景集成
- 回到 main.tscn,把 player.tscn 拖入场景(实例化)
- F5 运行,用 WASD/方向键控制角色移动
- 角色朝左时图片会镜像翻转
🎉 第一个可操作角色完成!
⚠️
角色不动?
检查:①输入映射是否创建且拼写一致;②速度是否太小;③脚本是否挂在了 Player 根节点上。
⚠️
角色移动有残影/抖动?
在 _process 里移动偶尔会抖动,物理移动建议用 _physics_process。
🧪 动手试一试
🏋️ 课后练习
为角色添加「按 Shift 加速跑」功能:按住 Shift 时速度乘 1.5。
新增动作 sprint,绑定 Shift;速度 = speed * (1.5 if sprint else 1.0)。
💡
@export 让变量在检查器可见可调,不用改代码试参数,超好用。
💡
get_input_dir 这种「把输入封装成函数」的写法,会让主逻辑很干净。
🎓 本课小结
玩家移动 = 输入映射读取方向 + position 位移 + 精灵翻转 + 速度控制;加加速度 move_toward 让手感更顺滑。