2D Sprite animation

Introdução

Nesse tutorial, você aprenderá a criar pesonagens 2D animados com a classe AnimatedSprite e com o AnimationPlayer. Normalmente, quando você cria ou baixa um personagem animado, ele virá em uma de duas formas: como imagens individuais ou como uma única sprite sheet contendo todos os quadros(frames) da animação. Ambos podem ser animados no Godot com a classe AnimatedSprite.

Primeiro, nós usaremos a classe AnimatedSprite para animar a coleção de imagens individuais. Depois nós iremos animar uma sprite sheet usando essa classe. Finalmente, nós iremos aprender outra maneira de animar uma sprite sheet usando AnimationPlayer e a propriedade Animation(Animação) de Sprite.

Nota

Arte para os próximos exemplos por https://opengameart.org/users/ansimuz e por https://opengameart.org/users/tgfcoder

Imagens individuais com AnimatedSprite

Neste cenário, você tem uma coleção de imagens, cada qual contendo um dos seus frames de animação do personagem. Para este exemplo, nós usaremos a seguinte animação:

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

Você pode baixar as imagens aqui: run_animation.zip

Descompacte as imagens e coloque-as na pasta do seu projeto. Configure a árvore da sua cena com os seguintes nós:

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

Nota

O nó raiz também pode ser Area2D ou RigidBody2D. A animação ainda será feita da mesma maneira. Assim que a animação estiver completa, você pode atribuir uma forma ao CollisionShape2D. Veja Introdução à Física para mais informação.

Agora, selecione o nó AnimatedSprite e em sua propriedade SpriteFrames, selecione "New SpriteFrames".

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

Clique no novo recurso SpriteFrames e você verá um novo painel aparecer na parte inferior na janela do editor:

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

Pelo painel de Sistema de Arquivos no lado esquerdo, arraste as 8 imagens individuais para a parte central do painel de SpriteFrames. No lado esquerdo, mude o nome da animação de "default" para "run".

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

De volta ao Inspetor, marque a caixa para a propriedade Playing. Você deverá ver a animação sendo reproduzida na janela de exibição. Entretanto, está um pouco devagar. Para ajeitar isto, mude a configuração Speed (FPS) no painel SpriteFrames para 10.

Você pode adicionar mais animações clicando no botão "New Animation(Nova Animação)" e, então, adicionando novas imagens.

Controlando a animação

Uma vez que a animação estiver completa, você pode controlar a animação por meio do código usando os métodos play() e stop(). Aqui está um breve exemplo para reproduzir a animação enquanto a tecla da seta para direita está sendo pressionada, e para parar a animação quando a tecla é solta.

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();
        }
    }
}

Sprite sheet com AnimatedSprite

Você também pode facilmente animar uma sprite sheet com a classe AnimatedSprite. Nós vamos usar essa sprite sheet de domínio público:

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

Clique com o botão direito do mouse na imagem e selecione "Salvar imagem como" para baixá-la, e logo depois copie a imagem na pasta do seu projeto.

Configure sua árvore de cena da mesma forma que você fez anteriormente quando usou imagens individuais. Selecione a AnimatedSprite e em sua propriedade SpriteFrames, selecione "New SpriteFrames".

Clique no novo recurso SpriteFrames. Dessa vez, quando o painel inferior aparecer, selecione "Add frames from a Sprite Sheet(Adicionar frames de uma Sprite Sheet)".

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

Será pedido que você abra um arquivo. Selecione sua sprite sheet.

Uma nova janela abrirá, mostrando sua sprite sheet. A primeira coisa que você precisará fazer é mudar o número de imagens verticais e horizontais em sua sprite sheet. Nesta sprite sheet, nós temos quatro imagens horizontalmente e duas imagens verticalmente.

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

Em seguida, selecione os frames da sprite sheet que você quer incluir na sua animação. Nós vamos selecionar os quatro de cima, depois clique em "Add 4 frames(Adicionar 4 frame(s))" para criar a animação.

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

Agora você verá sua animação na lista de animações no painel inferior. Clique duas vezes em "default" para mudar o nome da animação para "jump".

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

Finalmente, marque a propriedade Playing no inspetor da AnimatedSprite para ver seu sapo pular!

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

Sprite sheet com AnimationPlayer

Outra maneira de animar quando se usa uma sprite sheet é utilizar um nó Sprite padrão para exibir a textura e, posteriormente, animar a mudança de textura em textura com AnimationPlayer.

Considere esta sprite sheet, a qual contém 6 quadros de animação:

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

Clique com o botão direito na imagem e selecione "Salvar imagem como" para baixá-la. Em seguida, copie a imagem para dentro da pasta do seu projeto.

Nosso objetivo é exibir essas imagens uma após a outra em um ciclo. Começe configurando a árvore da sua cena:

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

Nota

O nó raiz também pode ser Area2D ou RigidBody2D. A animação ainda será feita da mesma maneira. Assim que a animação estiver completa, você pode atribuir uma forma ao CollisionShape2D. Veja Introdução à Física para mais informação.

Arraste a sprite sheet para a propriedade Texture da Sprite, e você verá toda a folha exibida na tela. Para cortá-la em frames individuais, expanda a seção Animação no Inspetor e defina a propriedade Hframes como 6. Hframes e Vframes são o número de quadros horizontais e verticais, respectivamente na sua sprite sheet.

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

Agora tente ir mudando o valor da propriedade Frame. Você verá que ela vai de 0 a 5 e a imagem é exibida pelas mudanças da Sprite adequadamente.

Selecione o AnimationPlayer e clique no botão "Animação" e ,depois, em "Novo". Nomeie a nova animação como "walk". Defina a duração da animação como 0.6 e clique no botão "Loop" para que a nossa animação se repita.

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

Agora selecione o nó Sprite e clique no ícone de chave para adicionar uma nova faixa.

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

Continue adicionando frames a cada ponto da linha do tempo (0.1 segundos por padrão), até que você tenha todos os frames de 0 a 5. Você verá os frames realmente aparecendo na trilha de animação:

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

Pressione "Play" na animação para ver como ela fica.

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

Controlando uma animação do AnimationPlayer

Igual quando se usa AnimatedSprite, você pode controlar a animação por meio de código usando os métodos play() e stop(). Novamente, aqui está um exemplo para reproduzir a animação enquanto a tecla da seta para direita está sendo pressionada, e para parar a animação quando a tecla é solta.

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();
        }
    }
}

Nota

Se atualiza-se tanto uma animação quanto uma propriedade separada de uma vez (por exemplo, um jogo de plataforma pode atualizar as propriedades h_flip/v_flip da sprite quando um personagem vira enquanto começa uma animação de 'virando'), é importante ter em mente que o método``play()`` não é aplicado instantaneamente. Ao invés disso, ele é aplicado no próximo momento em que o AnimationPlayer é processado. Isso pode acabar sendo no próximo frame, causando um 'glitch' de um frame, no qual a mudança na propriedade foi aplicada, porém a animação não foi. Se isso vir a ser um problema, depois de chamar play(), você pode chamar advance(0) para atualizar a animação imediatamente.

Resumo

Esses exemplos ilustram as duas classes que você pode usar no Godor para animações 2D. AnimationPlayer é um pouco mais complexo do que AnimatedSprite, mas ela fornece funcionalidades adicionais, já que você pode animar outras propriedades como posição ou escala. A classe AnimationPlayer também pode ser usada com uma AnimatedSprite. Experimente para ver o que melhor funciona para as suas necessidades.