2D Sprite animation (2D 精灵动画)

简介

在本教程中,你将学习如何使用AnimatedSprite节点和AnimationPlayer节点创建2D动画角色。通常,当你创建或下载动画化的角色时,它将以两种方式出现:作为单独的图像或一个包含所有动画帧的单张sprite sheet(sprite 清单)。两者都可以使用AnimatedSprite节点在Godot中进行动画处理。

首先,我们将使用 AnimatedSprite 动画化单个图像的集合。然后我们将使用此节点为sprite sheet(精灵合集)制作动画。 最后,我们将学习使用 AnimationPlayerSpriteAnimation 属性对一个 sprite sheet 进行动画。

注解

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

各自独立的图像与AnimatedSprite (动画化精灵)

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

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

你可以在此处下载此示例项目: 2D_movement_demo.zip

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

../../_images/2d_animation_tree1.png

注解

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

现在选择 AnimatedSprite ,并在它的 SpriteFrames(精灵帧) 属性中,选择“新建 SpriteFrames”。

../../_images/2d_animation_new_spriteframes.png

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

../../_images/2d_animation_spriteframes.png

从左边的文件系统面板,将这8张独立的图片拖放到SpriteFrames(精灵帧)面板的中间部分。在左边,将动画名称从“默认”更改为“奔跑”。

../../_images/2d_animation_spriteframes_done.png

回到属性面板,在 Playing(播放) 属性的复选框里打勾。您现在应该可以看到在视区中播放的动画。然而,它有点慢。为了解决这个问题,更改SpriteFrames面板中的 速度 (FPS) 为10。

你可以通过点击“新建动画”按钮并添加其他的图像,来添其他的动画。

控制动画

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

extends KinematicBody2D

onready var _animated_sprite = $AnimatedSprite

func _process(delta):
    if Input.is_action_pressed("ui_right"):
        _animated_sprite.play("run")
    else:
        _animated_sprite.stop()
public class Character : KinematicBody2D
{
    private AnimatedSprite _animatedSprite;

    public override void _Ready()
    {
        _animatedSprite = GetNode<AnimatedSprite>("AnimatedSprite");
    }

    public override _Process(float delta)
    {
        if (Input.IsActionPressed("ui_right"))
        {
            _animatedSprite.Play("run");
        }
        else
        {
            _animatedSprite.Stop();
        }
    }
}

带有AnimatedSprite[动画精灵]的精灵表

您还可以使用类“AnimatedSprite”从Sprite sheet (精灵清单)轻松设置动画。我们将使用此公共域精灵表:

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

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

设置场景树的方式与以前使用单个图像时相同。 选择 AnimatedSprite ,并在其 SpriteFrames 属性中,选择“New SpriteFrames”。

点击新建 SpriteFrames 资源,你会看到一个新的面板出现在编辑器窗口的底部,选择“从精灵表中添加帧(Add frames from a Sprite Sheet)”。

../../_images/2d_animation_add_from_spritesheet.png

将提示您打开一个文件。选择您的Sprite sheet (精灵清单)。

一个新的窗口将打开,显示您选择的Sprite sheet (精灵清单)。您需要做的第一件事就是更改精灵表中的垂直和水平方的正确图像数量。在这个Sprite sheet (精灵清单)中,水平有四个图像,垂直有2个图像。

../../_images/2d_animation_spritesheet_select_rows.png

接下来,从要包含在动画中的Sprite sheet (精灵清单)中选择帧。我们将选择前四个,然后单击"Add 4 frames(添加4帧)"来创建动画。

../../_images/2d_animation_spritesheet_selectframes.png

现在,您将在底部面板中的动画列表下看到您的动画。双击default将动画的名称更改为jump。

../../_images/2d_animation_spritesheet_animation.png

最后,在AnimatedSprite(动画精灵)的inspector(检查器面板)勾选Playing(播放)就可以看到你的青蛙跳动画!

../../_images/2d_animation_play_spritesheet_animation.png

Sprite sheet (精灵清单)和 AnimationPlayer(动画播放器)

在使用sprite sheet(精灵清单)时,另一种方法是使用标准的 :ref:`Sprite <class_Sprite>`节点来显示纹理,然后用 :ref:`AnimationPlayer <class_AnimationPlayer>`来实现从纹理到纹理的动画变化。

考虑一下这个sprite sheet,包含6帧动画:

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

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

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

../../_images/2d_animation_tree2.png

注解

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

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

../../_images/2d_animation_setframes.png

现在尝试更改 Frame 属性的值。你可以看到它的范围从 05 ,Sprite 所显示的图像也随之改变。这就是我们想要动画化的属性。

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

../../_images/2d_animation_new_animation.png

现在选中 Sprite 节点,并单击钥匙图标,添加一个新的动画轨道(track)。

../../_images/2d_animation_new_track.png

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

../../_images/2d_animation_full_animation.png

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

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

控制AnimationPlayer动画

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

extends KinematicBody2D

onready var _animation_player = $AnimationPlayer

func _process(delta):
    if Input.is_action_pressed("ui_right"):
        _animation_player.play("walk")
    else:
        _animation_player.stop()
public class Character : KinematicBody2D
{
    private AnimationPlayer _animationPlayer;

    public override void _Ready()
    {
        _animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
    }

    public override void _Process(float delta)
    {
        if (Input.IsActionPressed("ui_right"))
        {
            _animationPlayer.Play("walk");
        }
        else
        {
            _animationPlayer.Stop();
        }
    }
}

注解

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

总结

这些例子展示了你可以在Godot中使用的两个2D动画类。每种方法都有其好处。``AnimationPlayer``比``AnimatedSprite``更复杂一些,但它提供了额外的功能,因为你还可以对其他属性如位置或比例进行动画。试验一下,看看哪种最适合你的需要。