7. 角色移动与输入
2026/4/13大约 4 分钟
角色移动与输入
玩家移动是 2D 游戏最核心的交互。本章覆盖最常见的两种移动方式:横版平台跳跃和俯视角移动。
角色节点结构
不管哪种移动方式,角色的节点结构基本一致:
Player (CharacterBody2D) ← 物理角色体,自带碰撞和移动功能
├── AnimatedSprite2D ← 角色图片和动画
├── CollisionShape2D ← 碰撞形状(决定角色体积)
└── Camera2D ← 相机跟随(可选)- CharacterBody2D:Godot 专门为角色设计的节点,自带
move_and_slide()方法处理移动和碰撞 - CollisionShape2D:决定角色的"体积"——玩家能碰到多大范围
横版平台跳跃
角色受重力影响,可以左右移动和跳跃。这是 2D 游戏中最常见的移动方式。
C
using Godot;
// 玩家移动基本代码(平台跳跃)
public partial class Player : CharacterBody2D
{
private const float Speed = 300.0f; // 移动速度(像素/秒)
private const float JumpVelocity = -400.0f; // 跳跃力度(负数=向上)
// 获取全局重力设置
private float _gravity = (float)ProjectSettings.GetSetting("physics/2d/default_gravity");
public override void _PhysicsProcess(double delta)
{
// 不在地面上时,持续受到重力
if (!IsOnFloor())
Velocity = new Vector2(Velocity.X, Velocity.Y + (float)(_gravity * delta));
// 按跳跃键且在地面上时跳跃
if (Input.IsActionJustPressed("jump") && IsOnFloor())
Velocity = new Vector2(Velocity.X, JumpVelocity);
// 左右移动
float direction = Input.GetAxis("move_left", "move_right");
if (direction != 0f)
Velocity = new Vector2(direction * Speed, Velocity.Y);
else
// 松开按键时逐渐停下
Velocity = new Vector2(Mathf.MoveToward(Velocity.X, 0, Speed), Velocity.Y);
MoveAndSlide(); // 执行移动并处理碰撞
}
}GDScript
# 玩家移动基本代码(平台跳跃)
extends CharacterBody2D
const SPEED = 300.0 # 移动速度(像素/秒)
const JUMP_VELOCITY = -400.0 # 跳跃力度(负数=向上)
# 获取全局重力设置
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
func _physics_process(delta):
# 不在地面上时,持续受到重力
if not is_on_floor():
velocity.y += gravity * delta
# 按跳跃键且在地面上时跳跃
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
# 左右移动
var direction = Input.get_axis("move_left", "move_right")
if direction:
velocity.x = direction * SPEED
else:
# 松开按键时逐渐停下
velocity.x = move_toward(velocity.x, 0, SPEED)
move_and_slide() # 执行移动并处理碰撞关键函数解释
| 函数/属性 | 说明 |
|---|---|
velocity | 角色的速度向量,x 是水平方向,y 是垂直方向 |
is_on_floor() | 角色是否站在地面上 |
move_and_slide() | 根据 velocity 移动角色,并自动处理碰撞(撞墙会停) |
Input.get_axis() | 获取两个按键合并后的方向值(-1、0、1) |
俯视角 8 方向移动
角色可以在屏幕上自由向上、下、左、右及四个对角线方向移动,不受重力影响。
C
using Godot;
// 俯视角移动代码
public partial class Player : CharacterBody2D
{
private const float Speed = 200.0f;
public override void _PhysicsProcess(double _delta)
{
Vector2 input = Vector2.Zero;
input.X = Input.GetAxis("move_left", "move_right");
input.Y = Input.GetAxis("move_up", "move_down");
Velocity = input.Normalized() * Speed;
MoveAndSlide();
}
}GDScript
# 俯视角移动代码
extends CharacterBody2D
const SPEED = 200.0
func _physics_process(_delta):
var input = Vector2.ZERO
input.x = Input.get_axis("move_left", "move_right")
input.y = Input.get_axis("move_up", "move_down")
velocity = input.normalized() * SPEED
move_and_slide()归一化(normalized)
对角线移动时,x 和 y 方向同时为 1,合成速度会比单方向快 √2 倍(约 1.41 倍)。normalized() 会把向量长度缩放到 1,再乘以速度,保证各方向移动速度一致。
根据移动方向切换动画
C
using Godot;
// 根据移动方向切换动画
public partial class Player : CharacterBody2D
{
private AnimatedSprite2D _animatedSprite2D;
public override void _Ready()
{
_animatedSprite2D = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
}
public void UpdateAnimation()
{
if (Velocity.X > 0)
{
_animatedSprite2D.Play("walk");
_animatedSprite2D.FlipH = false; // 面朝右
}
else if (Velocity.X < 0)
{
_animatedSprite2D.Play("walk");
_animatedSprite2D.FlipH = true; // 面朝左(水平翻转图片)
}
else
{
_animatedSprite2D.Play("idle"); // 站立不动
}
}
public override void _PhysicsProcess(double delta)
{
// ... 移动代码 ...
UpdateAnimation();
MoveAndSlide();
}
}GDScript
func update_animation():
if velocity.x > 0:
$AnimatedSprite2D.play("walk")
$AnimatedSprite2D.flip_h = false # 面朝右
elif velocity.x < 0:
$AnimatedSprite2D.play("walk")
$AnimatedSprite2D.flip_h = true # 面朝左(水平翻转图片)
else:
$AnimatedSprite2D.play("idle") # 站立不动
func _physics_process(delta):
# ... 移动代码 ...
update_animation()
move_and_slide()flip_h = true 是水平翻转图片,这样你只需要画一个朝右的角色,朝左时自动翻转,不用画两套图。
相机跟随
让镜头跟着玩家移动,这样玩家走到哪里画面就跟到哪里:
- 给玩家添加子节点
Camera2D - 选中 Camera2D → 属性面板:
- Smoothing → Enabled:勾选(开启平滑跟随)
- Smoothing → Speed:设为
5.0(跟随速度)
- 如果想限制相机不超出地图范围,设置 Limit 下的左右上下边界
卡牌/棋牌游戏的交互
如果你的游戏是卡牌或棋类,核心不是"角色移动",而是:
- 页面绘制:用 Godot 的 Control 节点(UI 控件)搭建界面
- 元素交互:拖拽卡牌、点击按钮、选择目标
常用 UI 节点:
| 节点 | 用途 |
|---|---|
Panel | 卡牌、棋盘格子的背景框 |
TextureRect | 显示卡牌图片 |
Button | 可点击的按钮 |
Label | 显示文字(生命值、费用等) |
GridContainer | 自动排列网格布局(如手牌区) |
提示
卡牌游戏的拖拽操作可以通过 Control 节点的 gui_input 信号和 _get_drag_data() / _can_drop_data() / _drop_data() 虚方法实现。
下一章
角色能动了,接下来学习 2D 摄像机控制,让镜头跟着玩家走。
