学习空间/输入与移动:让角色可控
玩家与交互 / LESSON 13

输入与移动:让角色可控

把按键映射为动作,再把方向变成速度。

基础约 8 分钟阅读,实作另计7 节现在学
CONCEPT MAP先看一眼知识之间的联系
先看一眼知识之间的联系01输入动作02方向意图03速度与锁定04碰撞处理05实际位移
按键、期望速度与实际移动不是同一件事;在空地、墙边和对话锁定时分别观察。

01不要直接把键位写死进玩法

Input Map 把“物理按键”与“游戏意图”分开。move_left 可以绑定 A 和左方向键;interact 可以之后再调整。代码只依赖动作名,这样键位变化不会迫使你修改每个交互脚本。这里采用八向移动作为教学实验,不替项目锁定四向或八向操作。

02准备节点与动作

  1. 沿用 CharacterBody2D 根节点及 Sprite2D、CollisionShape2D 子节点;确认 Shape 已设置。
  2. 在 Project Settings → Input Map 新建 move_left、move_right、move_up、move_down,分别绑定 A/D/W/S 与方向键。动作名必须完全一致。
  3. 把下面脚本挂到 CharacterBody2D,设置 motion_mode 为 Floating,适合本例无地面概念的俯视移动。
  4. F6 后先单方向,再斜向,最后松开全部键观察停止。

03最小移动脚本

movement_practice.gd gdscript
extends CharacterBody2D

@export var move_speed: float = 120.0
var input_locked: bool = false

func _ready() -> void:
    motion_mode = CharacterBody2D.MOTION_MODE_FLOATING

func _physics_process(_delta: float) -> void:
    var direction: Vector2 = Vector2.ZERO
    if not input_locked:
        direction = Input.get_vector(
            "move_left", "move_right", "move_up", "move_down"
        )
    velocity = direction * move_speed
    move_and_slide()

Input.get_vector() 会限制向量长度,避免数字键盘斜向输入让速度变为约 1.414 倍。velocity 的单位是每秒像素;不要再把它乘 delta 后交给 move_and_slide()。

04交互实验与失败路径

不移动时先检查 Input Map、运行窗口焦点、脚本挂载位置和节点类型。停止不干净时检查是否还存在另一个脚本修改 position 或 velocity。这个教学脚本未处理角色朝向、动画和暂停;这些应该分步加入,不是一开始全部揉进移动函数。

05把移动拆成输入、意图与实际结果

按下右键是输入;得到向右的方向向量是意图;角色最终是否向右移动,还取决于输入锁、速度和墙壁阻挡。三者不能混成一个值。角色靠着墙继续按右键时,玩家仍然有向右的意图,但实际位置可能不再变化。如果动画只根据按键播放,你可能看到角色原地走;是否接受这种表现需要单独决定,不能把它当成碰撞失效。

做一张四行记录表:空地按右、靠墙按右、锁定时按右、松开所有键。每行分别预测输入方向、期望速度和实际位置变化。先运行观察,再解释不一致之处。这个练习会让你看懂为什么移动脚本不能只是“按键就加坐标”,也为之后接入站立、行走与交互模式打下基础。

06用一条固定距离的路线比较参数

在空白练习房间放两条明显标记,保持它们之间距离固定。选一个容易观察的速度作为版本甲,再只提高速度得到版本乙。分别从同一位置开始,记录抵达另一条标记的大致时间和操作感受。数值只是练习参数,不是正式角色速度;比较的重点是更快以后是否更难停在调查范围内,以及窄通道是否更容易来回修正方向。

再加入斜向移动,比较相同持续时间内的移动距离。数字按键输入经过 Input.get_vector 处理,不应因为同时按两个方向就无条件获得更快速度。对手柄而言,较小摇杆偏移还可能产生较短向量,因此“限制长度”和“永远归一化到一”不是同一回事。解释实验时要写明使用键盘还是摇杆,别把一种输入结果推到所有设备上。

07把停止和重新获得控制当作正式测试

初学者往往只测试能不能走,却忽略能不能在正确时机停。请依次测试松键、打开对话、窗口失焦后返回、结束对话后重新移动。尤其注意锁定输入时是否仍保留上一帧 velocity:示例每个物理步先从零方向开始,就是为了在禁止输入时不继续沿旧方向滑动。不要只把读取按键那一行跳过,却留下旧速度继续交给移动函数。

如果出现移动忽快忽慢,查看是否还有另一个脚本、动画轨道或临时测试代码同时改 position。给同一个位置安排两个控制者,经常会产生像抖动一样的结果。完成记录应包括使用的动作名、速度参数、空地与墙边观察、锁定与解锁结果。网页中的向量演示只能帮助理解长度,不代替 Godot 对这些实际输入路径的验证。

动手后,再勾选

不是“我看懂了”,而是你在独立练习里做出并检查过。

CHECK YOUR UNDERSTANDING

换一个情景,你会怎么判断?

给 move_and_slide() 使用的 velocity 应是什么?

用自己的话,留一条笔记

可以写“我之前以为……,现在发现……”,或者记录还没解决的问题。

仅保存在此浏览器0 / 20000

回到资料核对

本课是解释与练习,不替代对应版本的官方手册。网页实验不运行 Godot;未标明实机验证的代码,仍需在独立工程中检查。

把这课收进你的理解里。

标记已读不会自动勾选实作,也不代表游戏功能已经完成。

输入一个你想弄明白的问题。

按 Esc 关闭 · 标题、关键词和正文一起搜索