Introdução Este artigo vai mostrar como animar Sprites(Sprite Sheet) utilizando o XNA Game Studio 3. A animação mostrada aqui consiste na leitura de arquivo de imagem, .PNG por exemplo, contendo vários Sprites(frames) aonde cada frame compõe um estado de um Sprite. Exemplos de estados de Sprites: Idle(Ocioso), Run(Correr), Celebrate(Celebrar), Die(Morrer), Jump(Pular). Esses estados podem ser compostos por no mínimo 1 frame e todos os estados aparecem comumente em 2 situações: - dispostos no mesmo arquivo de Imagem;
- em arquivos de imagem separados.
Este artigo vai mostrar a animação de Sprites utilizando arquivos de imagem separados, ou seja, cada estado do Sprite estará em um único arquivo de imagem, como mostra as imagens abaixo: Imagem 1 – Estado: Idle
Imagem 2 – Estado: Run Imagem 3 – Estado: Celebrate Imagem 4 – Estado: Die Imagem 5 – Estado: Jump Lembre-se que você terá plenas condições para também animar Sprites com diferentes estados no mesmo arquivo de Imagem! Início da Programação Iniciando uma breve apresentação do “Demo” que estará disponível para download ao final deste artigo, precisamos definir quais serão os estados do Sprite do nosso jogo, abaixo os estados serão enumerados: ///<summary> /// Sprite State, i.e, Animation´s Type of a Sprite ///</summary> enum SpriteState { Celebrate, Die, Idle, Jump, Run } Precisamos também de uma estrutura de dado que represente os elementos necessários para a execução da animação, então será definida uma Struct de nome AnimationElement,que vai ter estes campos: ///<summary> /// Animation´s Type of a Sprite ///</summary> private SpriteState spriteState; ///<summary> /// Image of this Animation ///</summary> private Texture2D image; ///<summary> /// Indicates how many frames will be drawn at Each 1 second ///</summary> private int framesPerSecond; ///<summary> /// Count of rows of frames of the Animation´s Image ///</summary> private int rows; ///<summary> /// Count of Columns of frames of the Animation´s Image ///</summary> private int columns; ///<summary> /// Regions(rectangles) of the Frames ///</summary> private List<Rectangle> rectangles; ///<summary> /// Width of the Frame ///</summary> private int frameWidth; ///<summary> /// Height of the Frame ///</summary> private int frameHeight; Para este artigo, utilizaremos uma simples arquitetura aonde teremos a entidade Sprite, útil para os Sprites estáticos – aqueles que não serão animados. Conseqüentemente, teremos uma entidade chamada AnimatedSprite, que servirá para os Sprites animados. Temos o seguinte: class AnimatedSprite : Sprite A classe AnimatedSprite herdando de Sprite. O membro de maior relevância dessa classe(AnimatedSprite) é o método AddAnimationque recebe como parâmetro um AnimationElement. A assinatura do método AddAnimation ficou assim: ///<summary> /// Adds one animation to this Sprite. ///</summary> ///<param name="animationElement">Indicates the elments of the animation.</param> public void AddAnimation(AnimationElement animationElement) Então, para que um Sprite Animado(AnimatedSprite)tenha alguma animação, chamadas ao método AddAnimationdeverão ser feitas! Um exemplo de uso Imagine o seguinte cenário: O meu jogo precisa ter um sprite animado, e ele precisará executar uma animação de celebração(Imagem 3 – Estado: Celebrate). Antes de qualquer coisa, precisamos instanciá-lo: AnimatedSprite mySprite = new AnimatedSprite(); E de posse de uma instância, agora podemos “preparar” o nosso elemento de Animação, assim: AnimationElement element = new AnimationElement(SpriteState.Celebrate, this.Content.Load<Texture2D>("Celebrate"), 1, 11, 12);
As demais tarefas, como por exemplo, obtenção de todos os frames da animação, fica a cargo do AnimationElement obtê-los! Com um elemento de animação em mão, nós já podemos adicioná-lo à nossa instância “mySprite”: mySprite.AddAnimation(element); Você precisará modificar o estado do sprite(tipo da animação): mySprite.SetState(SpriteState.Celebrate); Por fim, basta efetuar as chamadas aos métodos Update e Draw do Sprite Animado em seus respectivos métodos na classe Game. Entendendo o construtor de um AnimationElement Observe novamente como um AnimationElement foi instanciado: AnimationElement element = new AnimationElement(SpriteState.Celebrate, this.Content.Load<Texture2D>("Celebrate"), 1, 11, 12); No 1º parâmetro, nós informamos o estado do Sprite, ou seja, o tipo da animação, neste exemplo escolhemos a de celebração, a seguir, no 2º parâmetro, foi a imagem com os frames da animação de celebração foi lida. Agora volte para a (Imagem 3 – Estado: Celebrate), abra-a e observe que ela possue 1 linha e 11 colunas, no 3º e 4º parâmetro, e por último, a quantidade de frames por segundo que será desenhada – escolhemos 12 frames por secundo. Considerações Finais O “demo” de animação deste artigo apresenta uma animação de Sprite feita em “Looping infinito”, ou seja, o sprite sempre executará a mesma animação. Entretanto, tenha em mento que existirão momentos em que a animação não precisará executar em “looping”. AnimationElement. Com isso, seria melhor guardar os AnimationElement numa coleção e deixar de utilizar as coleção da classe AnimatedSprite. Ao final você pode “baixar” um simples “Demo” mostrando tudo o que foi abordado acima. O “Demo” possui uma simples intarface aonde você poderá executar/vizualizar várias animações. O “demo” está rodando(testado) em Windows, Xbox 360 e Zune. Concluindo, este artigo teve como objetivo apresentar uma simples visão de como animar um sprite no XNA. Fique a vontade em incrementar/modificar os algoritmos deste “demo”. Imagem 6 – Uma foto do “Demo” disponível para download
As imagens 1, 2, 3, 4 e 5 foram retiradas do "Starter Kit" chamado Platformer(starter kit que vem no XNA Game Studio 3).
Após a leitura deste artigo, eu sugiro você baixar o "demo" que eu libero ao final deste artigo. Estude-o e publique suas dúvidas aqui no SharpGames!
Dúvidas, críticas ou sugestões são bem-vindas. Obrigado por sua leitura!
|