HOME / 第 7 部分 · 完整游戏项目实战 / 第 81 课
MODULE 7 · 完整游戏项目实战

第 81 课 · 像素风游戏实战(二):角色与动画

⏱ 预计时长 50 分钟📊 难度 进阶📚 模块 第 7 部分 · 完整游戏项目实战

🎯 本课学习目标

继续像素勇者:让角色动起来——待机、走路、跳跃三种动画切换。

📖 详细教学步骤

准备角色精灵图素材

像素角色动画通常用「精灵表」(Sprite Sheet):一张图包含多帧动画。

  • 例如:一张 64×16 图,含 4 帧 16×16 的走路动画
  • 用 AnimatedSprite2D 按帧切割播放

创建角色场景搭建

  1. 新建 player.tscn,根 CharacterBody2D
  2. 子节点:AnimatedSprite2D + CollisionShape2D(小矩形)
  3. 子节点 Camera2D
  4. 挂脚本 player.gd

配置 AnimatedSprite2D 动画实操

  1. 选中 AnimatedSprite2D → 检查器 Sprite Frames → 新建
  2. 底部出现「动画帧」面板
  3. 新建动画:idle(1 帧)、walk(4 帧)、jump(1 帧)
  4. 把精灵表的对应帧拖进各动画
  5. walk 动画设置 FPS(如 8,像素动画低帧率更协调)

角色脚本:移动 + 动画切换代码

核心逻辑:

GDSCRIPTextends CharacterBody2D

@export var speed: float = 140.0
@export var jump_velocity: float = -350.0
@export var gravity: float = 900.0
@onready var anim: AnimatedSprite2D = $AnimatedSprite2D

func _physics_process(delta):
    if not is_on_floor():
        velocity.y += gravity * delta
    var dir = Input.get_axis("move_left", "move_right")
    velocity.x = dir * speed
    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = jump_velocity
    move_and_slide()
    update_animation(dir)

func update_animation(dir: float):
    if not is_on_floor():
        anim.play("jump")
    elif dir != 0:
        anim.play("walk")
    else:
        anim.play("idle")
    # 朝向
    if dir != 0:
        anim.flip_h = dir < 0

测试角色测试

  1. 把玩家放入 main.tscn,放在地面上
  2. F5 运行:左右走、跳、动画自动切换、转向翻转
  3. 调速度/重力手感

🎉 像素角色活了!

动画细节打磨进阶

  • 跳跃时用「跳跃帧」而非走路帧,更自然
  • 落地瞬间播放短促「dust」粒子
  • 走路动画 FPS 8-12 适合像素风
  • 把 AnimationPlayer 换 AnimationTree 可做更多状态(进阶)
⚠️
精灵表只显示第一帧?

确认 AnimatedSprite2D 的 Sprite Frames 里各动画帧已添加、正在播放的动画名正确。

⚠️
动画和移动方向不一致?

flip_h 用 dir<0 控制,且要在 update_animation 里每次调用。

🧪 动手试一试

🏋️ 课后练习

给角色加「奔跑」动画:按住 Shift 时播放快跑动画(FPS 更高、速度更快)。

sprint 动作 + speed 乘 1.6 + anim 切 walk_fast。

💡

AnimatedSprite2D 是像素 2D 动画的首选(比 AnimationPlayer 简单)。

💡

像素动画帧数少反而更有味道,别贪多。

🎓 本课小结

像素角色:AnimatedSprite2D 配 Sprite Frames(idle/walk/jump)+ CharacterBody2D 移动 + 状态切动画 + flip_h 转向。