Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

2D 精灵动画

前言

在本教程中,你将学习如何使用 AnimatedSprite2D 类和 AnimationPlayer 创建 2D 动画角色。 通常,当你创建或下载动画角色时,它将以两种方式之一出现:作为单独的图像或作为包含所有动画帧的单个精灵表。 两者都可以在 Godot 中使用 AnimatedSprite2D 类进行动画处理。

首先,我们将使用 AnimatedSprite2D 对单个图像集合进行动画处理。 然后我们将使用此类对精灵表进行动画处理。 最后,我们将学习另一种使用 AnimationPlayerSprite2DAnimation 属性来制作精灵表动画的方法。

备注

以下示例的美术资产由 https://opengameart.org/users/ansimuzhttps://opengameart.org/users/tgfcoder 共同提供。

AnimateSprite2D 与若干单独的图片

在这个情况下, 你有一组图像, 每一个都包含你角色的动画的一帧. 对于这个例子, 我们将使用以下动画:

../../_images/2d_animation_run_preview.gif

你可以在这里下载图片:2d_sprite_animation_assets.zip

解压缩这些图像并将它们放在项目文件夹中. 使用以下节点布置场景树:

../../_images/2d_animation_tree1.webp

备注

根节点也可以是 Area2DRigidBody2D。动画仍然会以同样的方式制作。一旦动画完成,你就可以为 CollisionShape2D 形状分配一个形状。更多信息请参见物理介绍

现在选中 AnimatedSprite2D ,并在它的 SpriteFrames 属性中,选择“新建 SpriteFrames”。

../../_images/2d_animation_new_spriteframes.webp

点击新的 SpriteFrames 资源,你会看到一个新的面板出现在编辑器窗口的底部:

../../_images/2d_animation_spriteframes.webp

将这 8 张独立的图片从左边的“文件系统”面板拖放到“动画帧”面板的中间部分。在左边,将动画名称从“default”更改为“run”。

../../_images/2d_animation_spriteframes_done.webp

使用 过滤动画(Filter Animations) 输入右上角的“播放(Play)”按钮预览动画。 你现在应该可以看到动画在视口中播放。 然而,它有点慢。 要解决此问题,请将 SpriteFrames 面板中的 Speed (FPS) 设置更改为 10。

你可以通过单击“添加动画”按钮并添加其他图像来添加其他动画。

控制动画

动画完成后, 你可以通过代码中的 play()stop() 方法控制动画. 这里有一个简单的例子, 按住右方向键播放动画, 松开后就停下.

extends CharacterBody2D

@onready var _animated_sprite = $AnimatedSprite2D

func _process(_delta):
    if Input.is_action_pressed("ui_right"):
        _animated_sprite.play("run")
    else:
        _animated_sprite.stop()

AnimateSprite2D 与精灵表

你还可以很方便地使用 AnimatedSprite2D 把精灵表做成动画。我们会用到这张公共领域的精灵表:

../../_images/2d_animation_frog_spritesheet.png

右键单击图片,选择“图片另存为”来下载图片,然后将图片复制到项目文件夹中。

设置场景树的方法与之前使用单独图片的时候相同。选中 AnimatedSprite2D 后在 SpriteFrames 属性里选择“新建 SpriteFrames”。

点击创建出来的 SpriteFrames 资源。底部面板出现后,这次我们选择“从精灵表中添加帧”。

../../_images/2d_animation_add_from_spritesheet.webp

在弹出的打开文件对话框中,选择你的精灵表。

接下来会打开一个新的窗口,里面会显示刚才的精灵表。你首先需要修改精灵表中纵向和横向的图片数量,我们的这张精灵表里横向有四张图片、纵向有两张。

../../_images/2d_animation_spritesheet_select_rows.webp

然后,在精灵表中选择动画中想要包含的帧。这里我们选中上面的四个,然后点击“添加 4 帧”来创建动画。

../../_images/2d_animation_spritesheet_selectframes.webp

现在你就可以看到在底部面板的动画列表里看到这个动画了。双击 default(默认),然后把动画的名称改成 jump(跳跃)。

../../_images/2d_animation_spritesheet_animation.webp

最后,点击 SpriteFrames 编辑器上的播放按钮,你的青蛙就能跳起来了!

../../_images/2d_animation_play_spritesheet_animation.webp

AnimationPlayer 与精灵表

使用 Sprite Sheet 时制作动画的另一种方法是使用标准 Sprite2D 节点来显示纹理,然后使用 AnimationPlayer 对纹理之间的变化进行动画处理 。

考虑一下这个包含 6 帧动画的精灵表:

../../_images/2d_animation_player-run.png

右键单击图片,选择“图片另存为”下载图片,然后将图片复制到项目文件夹中。

我们的目的是, 循环着一个接一个地显示这些图像. 首先布置你的场景树:

../../_images/2d_animation_tree2.webp

备注

根节点也可以是 Area2DRigidBody2D。动画仍然会以同样的方式制作。一旦动画完成,你就可以为 CollisionShape2D 形状分配一个形状。更多信息请参见物理介绍

将精灵表拖拽到 Sprite 的 Texture 属性里,你会看到整个清单显示在屏幕上。要把它分割成单独的帧,请在“检查器”中展开 Animation 部分,将 Hframes 设置为 6HframesVframes 是精灵表中水平和垂直帧的数量。

../../_images/2d_animation_setframes.webp

现在尝试更改 Frame 属性的值。 你会看到它的范围从 05 ,Sprite2D 显示的图像也会相应变化。 这是我们要设置动画的属性。

选中 AnimationPlayer , 然后点击 "动画" 按钮, 然后点击 "新建" 按钮. 将新动画命名为 "walk". 将动画长度设置为 0.6 , 点击 "Loop" 按钮, 让动画重复播放.

../../_images/2d_animation_new_animation.webp

现在选中 Sprite2D 节点,然后单击钥匙图标,添加一个新轨道。

../../_images/2d_animation_new_track.webp

继续在时间轴的每一点添加帧(默认为 0.1 秒),直到你得到了从 0 到 5 的所有帧。你会看到这些帧出现在动画轨道上:

../../_images/2d_animation_full_animation.webp

按下动画上的“播放”键,看看效果如何。

../../_images/2d_animation_running.gif

控制 AnimationPlayer 动画

与 AnimatedSprite2D 一样,你可以使用 play()stop() 方法通过代码控制动画。 同样,这里是一个在按住右箭头键时播放动画的示例,并在释放该键时停止动画。

extends CharacterBody2D

@onready var _animation_player = $AnimationPlayer

func _process(_delta):
    if Input.is_action_pressed("ui_right"):
        _animation_player.play("walk")
    else:
        _animation_player.stop()

备注

如果同时更新一个动画和一个其他的属性(比如说,平台跳跃游戏可能会更新精灵的 h_flip/v_flip 属性然后同时开始一个转身动画“turning”),要记住 play() 不是即时生效的。它会在下次 AnimationPlayer 被处理时生效。也就是说可能要到下一帧才行,导致现在这一帧变成“问题”帧——应用了属性的变化,但动画还没有开始。如果这会造成麻烦的话,在调用 play() 后,你可以调用 advance(0) 来立即开始播放动画。

总结

这些示例说明了可在 Godot 中用于 2D 动画的两个类。 AnimationPlayerAnimatedSprite2D 稍微复杂一些,但它提供了额外的功能,因为你还可以为其他属性(如位置或比例)设置动画。 类 AnimationPlayer 也可以与 AnimatedSprite2D 一起使用。 尝试看看什么最适合你的需求。