MonoGame —Animação de Sprite
Na última publicação que fiz, apresentei algumas funcionalidades do MonoGame, em um tutorial dividido em 6 partes, desenvolvendo um jogo voltado para dispositivos mobile de forma mais simples possível.
Neste artigo vou demonstrar como animar um personagem utilizando sprite sheet, onde o mesmo possuíra a animação de andar, que irá se alternar de acordo com a direção pressionada na tela do dispositivo.
Para desenvolver o jogo de exemplo o seguinte arquivo será utilizado:
Show me the code!
O projeto de exemplo será desenvolvido para plataforma mobile android, mas nada impede de ser replicado em outra plataforma. Então sem mais delongas, vamos ao nosso saudoso ritual “File, New, Project”, selecionando o Template “MonoGame Android Project”.
Após criar o projeto vamos adicionar a classe abstrata AnimacaoSprite, com o seguinte código:
- Método LoadContent(…)
Neste método ocorre o carregamento da textura, cálculo da largura e altura de um frame e definição da primeira região da textura que será renderizada na tela, neste caso a primeira imagem do sprite sheet.
- Método Animacao(…)
É realizado a verificação do tempo para incrementar ou zerar a variável _frameAtualDaColuna a cada 100 milissegundos, em seguida a posição X, Y da variável _regiaoDaTextura, que é do tipo Rectangle, e setada para renderizar uma nova região da textura, que é feito pelo método Draw(…).
Como a animação de cada direção do personagem está separada por linhas foi realizado a multiplicação do frame atual pela largura do frame (linha 50) para setar a posição de X, já a posição de Y é definida por parâmetro (linha 51) uma vez que ela define qual a direção da animação.
Como pode ser observado a animação ocorre alterando a posição X, Y da região do sprite sheet que deverá ser renderizado, para tentar deixar um pouco mais claro fiz o seguinte GIF:
Agora que já possuímos a classe de animação podemos criar a classe Personagem fazendo herança com AnimacaoSprite com o seguinte código:
Nas linhas 9 e 10 foi realizado a implementação das propriedades abstratas herdadas da classe AnimacaoSprite informando a quantidade de linhas e colunas existentes no sprite sheet, e na linha 12 foi criado a variável Velocidade do tipo Vector2 com um valor float de 300 para X e Y.
- Método Mover(…)
Aqui e recuperado a ação de touch na tela do dispositivo e atualizado a posição do personagem com a devida animação.
Na linha 16 é armazenado o tempo decorrido no jogo para ser utilizado no calculo de atualização da posição do personagem, na linha 17 é obtido o touch utilizando o método GetState() da classe Microsoft.Xna.Framework.Input.Touch.TouchPanel.
Na linha 21 é armazenado o primeiro objeto TouchLocation da variável touchCollection que será utilizado para verificar e definir a direção que o personagem deverá se mover.
Na linha 22 é realizado uma validação para saber se o personagem irá se mover na horizontal ou vertical, isto é definido verificando se a posição X do touch menos a posição X do personagem é MAIOR QUE a posição Y do touch menos a posição Y do personagem.
Exemplificando:
Posição X do personagem = 100
Posição Y do personagem = 45
Posição X do toque na tela = 400
Posição Y do toque na tela = 20X = 400 - 100
X = 300Y = 20 - 45
Y = -25Logo X é maior que Y.
Na linha 23 a variável Ativado herdada da classe AnimacaoSprite é alterada para true, assim, ao executar o método Animacao(…) a posição X, Y da região que será renderizada é alterada.
Nas linhas 30, 36, 45 e 51 ocorre a chamada ao método Animacao(…), a única diferença entre estas chamadas é o segundo parâmetro, o regiaoPosY que é responsável por definir qual linha da sprite sheet será utilizada na animação.
Nas linhas 31, 37, 46 e 52 ocorre a atualização da posição do personagem, levando em consideração a velocidade multiplicada pelo tempo decorrido no jogo. Este cálculo e realizado para evitar que o personagem apareça de imediato na posição onde ocorre o touch e também faz com que a velocidade fique correta de acordo com a taxa de FPS do dispositivo.
Na linha 27 a variável Ativado e setada para false parando a animação do personagem quando não existir ação de touch na tela do dispositivo.
Antes de finalizar com o código mais “difícil” será necessário importar o sprite sheet, no Solution Explorer navegue até a pasta Content, clique com o botão direito do mouse no arquivo Content.mgcb é selecione Open With…, procure por MonoGame Pipeline Tool(MGPT) e de um duplo clique, em seguida realize o seguinte procedimento:
Aqui está o código mais “difícil” de todo o exemplo:
Na linha 12 é criado a variável _personagem do tipo Personagem já instanciada.
Na linha 20 é carregada a textura(sprite).
Na linha 28 é realizado a chamada ao método Mover(…).
E na linha 39 o personagem é renderizado de acordo com a sua nova posição e região da sprite sheet.
De tão “difícil” eu não ia nem comentar, mas como sou camarada.. ; )
Finalizado as implementações na classe Game1, ao executar o projeto este é o resultado obtido:
Repositório do Exemplo:
https://github.com/RonildoSouza/MonoGameAnimacaoSprite
Baixe o APK: https://github.com/RonildoSouza/MonoGameAnimacaoSprite/releases/download/1.0/br.com.byrns.monogame_animacaosprite.apk
REFERÊNCIAS:
https://docs.microsoft.com/en-us/xamarin/graphics-games/monogame/introduction/part2
https://openclipart.org/detail/248259/retro-character-sprite-sheet
http://gamerdesconstrutor.blogspot.com/2014/12/sprite-sheets-definicao.html