Controle de Animações

E aê pessoal! Tudo tranquilo?

Hoje vou colocar mais um post técnico falando sobre o controle de animação do jogo Beat the Plague.

Primeiramente, não faço discrição entre sprite estática e animação. Ambas são Sprites para mim! E ambas herdam da classe Sprite.

Elas tem um controle interno diferente, mas ambas são imagens que definem um Ator (personagem).

Sprite Estático e Animado

Ótimo! Um Ator pode simplesmente ser um Sprite em alguns casos, mas na situação atual isso pode ser uma dor de cabeça. Os atores do Beat the Plague tomam formas e tem comportamentos diferentes de acordo com a situação do jogo. Um inseto tem uma animação quando se locomove, mas tem outra animação quando se alimenta ou quando morre.

Para organizar e resolver essa confusão fiz uma classe intermediária entre as funcionalidades do Ator e as Funcionalidades da animação. Essa classe se chama SpriteManager.

Coloquei uma propriedade do SpriteManager na classe dos Atores. Ou seja, cada Ator tem um gerenciador de Sprites.

Sprite Manager

O gerenciador de Sprites (SpriteManager) contém um dicionário de Sprites, uma lista onde cada item da lista contém uma chave, podendo ser um valor numérico ou uma string, e um dado correspondente (no caso um Sprite).

Dicionário de Sprites

Na linguagem C# é possível utilizar a classe Dictionary dessa maneira:

Dictionary<KEY, DATA> sprites;
Ex:
Dictionary<int, Sprite> sprites;
Dictionary<string, Sprite> sprites;

Ou em Java, com a classe HashMap:

HashMap<KEY, DATA> sprites;

Ex:
HashMap<Integer, Sprite> sprites;
HashMap<Integer, Sprite> sprites;

A classe SpriteManager contém alguns métodos para auxiliar no controle das animações. Através dessa classe, o programador poderá adicionar animações e setar as animações através de uma chave (ou id).
Vou colocar aqui um exemplo dessa classe feita em C# pro Xna.

SpriteManager para Xna

Para controlar as chaves das animações criei algumas constantes na própria classe do Ator (no caso o Besouro). Essa lógica pode ser feita de outras maneiras, inclusive com Enumeradores. Mas como Enums são bem “pesadas” (pelo menos no Java), resolvi deixar as constantes.
E aqui está um exemplo disso em C#:

Controle de Animação do Besouro

Agora é só adicionar as animações que o besouro terá e alterar a animação corrente via spriteManager.SetSprite() passando uma chave como parâmetro da maneira que você achar melhor (por Maquina de Estados, Behaviour ou Macumba).

Essa maneira de controlar animações 2D pode não ser a melhor opção. Quem tiver uma ideia diferente (seja ela melhor ou pior) mande! ou comente! Ficarei feliz em fazer um post mostrando novas opções ou até detonando meu próprio post!

E é isso aê!!


IPExtreme – Defesa da Terra

E aê pessoal!
Apareceu um trampo essa semana: fazer um jogo para a empresa IPExtreme.

A IP Extreme ministra treinamentos presenciais/incompany, consultoria, projetos e vendas de soluções de segurança digital. E eles estão com uma promoção!

A pessoa que tiver a maior pontuação no jogo até o dia 01/08/2012 ganhará um curso presencial inteiramente grátis!

JOGUE AGORA!

Defenda a Terra da chuva de meteoros!

E é isso aê!


Cubos e Rastros Psicodélicos

E aê pessoal! Tudo firmeza?

Aqui tá tudo firmeza também. Tá tudo bem. Muito trabalho, pouco dinheiro. A vida que eu sempre sonhei.

Estava um pouco fora do Beat the Plague ( e ainda estou), mas daqui a pouco eu volto pra terminar o jogo. Nesse meio tempo fui convidado para programar algumas coisas no jogo CubIsLand! Pra quem não conhece, é bom dar uma olhada no Invision Comunity (AQUI)!

Ah… mas vamos colocar o poster também! Clique na imagem pra ir pro blog do CubIsLand!

CubIsLand

Bom. Como já dito. Estou programando o CubIsLand e alguns trampos a mais, por isso não tem nenhum post por aqui mais. Mas vamos voltar à ativa!

Hoje eu estava meio viajante na maionese. Então resolvi concretizar essa viagem em forma de código, programando um efeito de rastro.

Apresento a coisa psicodélica:

Efeito de Rastro Luminoso

Efeito de Rastro Luminoso

Na verdade isso é basicamente um sistema de partícula. O programa guarda uma certa quantidade de posições anteriores e desenha na tela em quantidades diferentes de transparência (se alguém quiser saber como funciona, eu faço um post explicando a técnica depois).

E pra deixar a coisa mais legal, fiz um minigame com esse efeito. O Chiptune (caramba, o nome dos meus jogos são muito criativos).

Chiptune

Chiptune

Os dois testes foram feitos em Xna (versão 4.0). Para testar o projeto é preciso instalá-lo na máquina. Segue link pro DOWNLOAD DO XNA 4.

E para vocês testarem, segue o link do PULSE EFFECTS e do CHIPTUNE!

Comentem aê! E testem!! E podem pedir coisas que eu posto aqui!

(Isso me faz lembrar que estou devendo um post sobre o esquema de animação, que será o próximo, prometo)

E é isso aê!!


Inteligência Artificial e Behaviour Trees

E aê pessoal!

Durante a reestruturação da engine do beat the plague eu me peguei pensando sobre o comportamento dos objetos, inimigos, plantas, entre outras coisas. Como eu estava mudando o código referente aos objetos, resolvi pesquisar sobre um jeito melhor de se fazer a inteligência artificial, e acabei descobrindo um tal de behaviour tree.

Primeiro vamos ver como estava a codificação dos inimigos do jogo…
Eles foram programados a partir de um conceito chamado “Maquina de Estados Finita”. Essa estrutura é baseada na escolha das ações a partir do estado atual do objeto, e a partir dessas ações, o estado também é alterado.

Segue um diagrama do comportamento do besouro no jogo a partir da máquina de estados.

Diagrama de Máquina de Estados

O Besouro começa no estado “Escolhendo Alvo”. Quando o alvo é escolhido, o estado muda para “Andando”. O inseto anda em direção ao alvo até que ele seja alcançado, mudando o estado para “Comendo” que será executado até que a planta morra, fazendo o estado mudar para “Escolhendo Alvo” e iniciando o ciclo novamente.

A maquina de estados finita é programada como um único bloco, normalmente estando contida na própria classe do objeto de jogo. Para quem está curioso como fica o código, aqui está um exemplo.

Código da Máquina de estados do Besouro

Código da Máquina de estados do Besouro

Esse código funciona muito bem quando eu já tenho todos os comportamentos definidos e não vou alterar. Mas, e se eu quiser colocar um novo comportamento? Vou ter que adicionar novos blocos de código na classe do Besouro até que ela fique grande demais, desorganizada demais, ou ruim demais para debugar.

Uma solução para esses problemas é a utilização de Behaviour Trees.

Behaviour Tree

Uma Behaviour Tree

A Behaviour tree separa o comportamento de seus Agentes (objetos de jogo), deixando a estrutura mais organizada, mais fácil de se debugar e mais simples caso a inteligência de algum agente tenha que ser alterada.

A Behaviour Tree é uma estrutura de dados formadas por Nós de Comportamento. Existem 3 tipos de Nós:

Nó Folha ou Tarefa

Esse nó sempre está presente nas pontas da árvore, e ela representa um comportamento do Agente.

Tarefa

Tarefa

A tarefa é formada pela combinação de duas variantes: sua condição de execução, e sua ação propriamente dita. Um exemplo de Tarefa pode ser a seguinte: Se o inimigo estiver à minha esquerda (Condição), Correr para a direita (Ação).

Para aumentar as possibilidades sobre a árvore de comportamentos (Behaviour Tree) existem nós auxiliares, onde os mais comuns são o Seletor e o de Sequência.

Nó de Sequência

O nó de sequência permite que cada nó filho seja verificado e executado um após o outro, sendo que seu comportamento só será de sucesso caso todos os filhos obtenham sucesso.

Nó de Sequência

O Nó de Sequência inicia sua tarefa verificando o seu primeiro nó filho (podendo ser ele de qualquer tipo).

Caso o primeiro nó tenha sucesso na sua ação, o nó de sequência executará o filho seguinte.

Caso qualquer um dos nós filhos tenham fracassado ou sua condição não foi alcançada, o nó de sequência retorna ao nível acima com a informação de fracasso.

O nó de sequência terá sucesso apenas quando todos os filhos obtiverem sucesso na sua execução e condição.

Nó Seletor

O nó seletor faz com que APENAS UMA ação filha seja efetuada.

O nó seletor inicia da mesma forma que o de sequência, mas caso um nó filho tenha falhado, ele passa para o próximo até encontrar o primeiro nó filho que tenha sucesso.

Caso o nó filho tenha sucesso em sua execução, o nó seletor retorno para o nível acima com o estado de sucesso e não executa os filhos restantes.

O nó seletor só fracassa quando nenhum de seus filhos obtiverem sucesso.

Exemplo

No caso do jogo Beat the Plague eu posso utilizar a Behaviour Tree para fazer a inteligência do Besouro. Um exemplo com o comportamento atual seria esse:

A árvore teria um nó seletor raíz que selecionaria apenas uma dentre Tarefas filhas.

O seletor iniciará sua busca pelo primeiro nó filho.

Se o besouro não tiver um alvo, o Besouro executa a ação “Escolher Alvo” e retorna sucesso para o seletor, que para a sua busca.

Caso a tarefa 1 não tenha sucesso, o seletor verifica a tarefa 2: se eu não alcancei o alvo, então “Ande” em sua direção e retorne sucesso.

Caso as tarefas 1 e 2 tenham fracassado, verifique a 3. Caso o alvo estiver vivo, “Coma”.

Eu posso alterar a estrutura da árvore sem mexer na classe do besouro já que a mesma está desacoplada do Ator da ação. A estrutura das classes ficou mais ou menos assim:

E caso eu queira mudar a inteligência do Besouro, posso fazer sem nenhum problema. No caso, adiciono uma sequência de ações enquanto o Besouro não é ameaçado pelo jogador. Fazendo um esquema de patrulha (“fique um tempo parado” e “mova-se aleatoriamente”).

E é isso aê!

Caso alguém queira saber mais sobre o assunto pode acessar esses links:

http://aigamedev.com/open/article/bt-overview/

http://www.altdevblogaday.com/2011/02/24/introduction-to-behavior-trees/

(Behaviour Tree no jogo Halo 3)
http://www.bungie.net/images/Inside/publications/presentations/publicationsdes/engineering/nips07.pdf

(Apresentação da Crytek sobre Behaviour Trees. MUITO BOM!)
http://staff.science.uva.nl/~aldersho/GameProgramming/Papers/Coordinating_Agents_with_Behaviour_Trees.pdf

(Call Tree – Implementação de BT – A imagem (primeiro link) mostra uma behaviour tree pra um hadouken, e  o segundo é um link pro projeto)
https://a248.e.akamai.net/camo.github.com/40da00b92e85ff9ff990c8b077a62fcc6a48c3f7/687474703a2f2f6a6a61636f6273736f6e2e6769746875622e636f6d2f63616c6c747265652f63747373732e706e67
https://github.com/jjacobsson/calltree

Comentem, xinguem, e deem sugestões entre outras coisas! Valeu!

 

 


Férias, que nada…

E aê pessoal!

Depois de não sei quantos dias sem postar nada, eis que estou de volta. Não estava de férias nem nada do gênero. Estava fazendo um simples ajuste na arquitetura do jogo. E como esse ajuste se encontrava na base da pirâmide, tive que refazer (e ainda estou refazendo) a maior parte do sistema.

Antigamente todos os objetos do jogo se encontravam com a seguinte arquitettura:

Estrutura Antiga

Estrutura Antiga e Porca

Como o Beat the Plage começou como um projeto rápido e despretensioso, eu o programei o mais rápido possível, e, consequentemente, o mais porcamente possível. Não que isso seja uma coisa ruim. Se eu não tivesse feito dessa maneira eu estaria planejando o jogo até agora.

Mas voltemos ao assunto. O que há de errado com essa estrutura? A resposta é: NADA. Muitos jogos que fiz funcionam bem nessa estrutura. Nesse caso, todo objeto de cena é um sprite ou um sprite animado (pra quem  não sabe, Sprite é um objeto gráfico que compõem a cena de um jogo). Não há nada de errado nessa arquitetura se cada objeto de seu jogo é representado por um sprite ou animação imutável. Mas, como quero adicionar efeitos, ter um controle melhor das animações e dos sprites, resolvi mudar para isso…

nova estrutura

Nova Estrutura (óóóóóóóohhhhh)

Qualquer objeto do jogo não é mais um Sprite. Agora todo objeto é um Ator. Isso faz com que eu possa criar objetos que não possui necessariamente uma imagem. Posso criar um comportamento que controla algo na cena que não seja visível. Mas a coisa mais legal nessa estrutura é a separação do Sprite (animado ou não) da estrutura hierárquica dos objetos. Um Inseto, como no exemplo, é um Ator que pode conter um ou mais Sprites. O Inseto terá uma lista de Sprites (contendo animações como as de andando, comendo, morrendo, etc.) onde é possível selecionar o Sprite corrente a ser exibido. Dessa forma eu não preciso mudar a estrutura da animação (Sprite) toda vez que o Inseto mudar de comportamento, eu apenas seleciono a animação pertinente para ser exibida.

De lambuja, o sistema ganhou mais duas características: O objeto de Transformação e o Aninhamento de Atores. O objeto de transformação guarda informações da posição, rotação(NOVO) e tamanho do Ator(NOVO). E o aninhamento permite que qualquer ator tenha atores filhos, herdando a transformação do pai. Um exemplo disso é o seguinte:

Imagine que eu tenha um tabuleiro de xadrez e suas peças. Cada objeto é tratado individualmente. Se por algum motivo eu tenha que rotacionar o tabuleiro, eu terei que rotacionar cada peça individualmente. Se eu colocar as peças como Atores filhos do tabuleiro, ao rotacionar o tabuleiro, todas as suas peças rotacionarão, apenas acompanhando a transformação do tabuleiro.

Vai falar que eu fiquei de férias agora…

 


Loja e Upgrade disponível para testes!

E aê, galerinha!

Essa semana não foi muito produtiva. A correria com TCC me fez parar um pouco com o desenvolvimento do jogo. Mas ainda bem que acabou!

Como  estou a um tempo sem lançar coisas sobre o jogo, resolvi disponibilizar o próprio para vocês experimentarem (com musicas xupinhadas do Sonic, por enquanto).

ESSE É O LINK PARA VOCÊS BAIXAREM!

Lembre-se que é necessário ter um dispositivo com Android para rodar.

Os desenvolvimentos feitos nessa semana foram a criação da loja e do inventário em geral. Foi desenvolvida a utilização do item de fertilização, que transforma sua planta em outra. Essas plantas têm características específicas: ser mais forte, ser uma planta armadilha, entre outras coisas. No caso, só existe a plantinha (padrão), a planta média (plantinha regada) e o girassol (planta média com fertilizante de girassol).

Level com Inventário

Itens e upgrade!

Testem! Xinguem! Comentem! Reclamem! E tudo mais!

E é isso aê!


Scrum no Desenvolvimento de Jogos

E aê, galerinha!

Pra quem acha que estou em pleno domingo curtindo um sol, praia e água de coco, venho aqui para mostrar-lhes a realidade e apagar esse sonho a tanto procurado.

Como um ato repetido de quase masoquismo fiz um curso de pós graduação, que, infelizmente, resultou na confecção de mais um TCC. E como um ato desesperado, misturado ao desânimo e à preguiça, resolvi deixar esse trabalho o mais simples e divertido possível.

O curso que fiz é de gestão de tecnologia da informação, mas, como já era de se esperar, fiz um trabalho sobre jogos. No caso, sobre metodologias ágeis para o desenvolvimento deles. E acompanhando o desenvolvimento do jogo Space Cowboy! (yeeeeeeeeehaaaa) desenvolvido pelo grupo Forja (no qual também faço parte).

Cowballs! As vacas mais carismáticas do espaço!

Pra quem quiser ver as boas novas e velhas do grupo forja, podem acompanhar pelo:

Blog – http://forjaentertainment.blogspot.com.br/
Facebook – http://www.facebook.com/pages/Forja-Entertainment/183388851729266
E Jogar o jogo Space Cowboy! (yeeeeeehaaaaa novamente) – http://www.kongregate.com/games/forjaent/space-cowboy

Quem quiser saber sobre esse tal de Scrum, metodologias ágeis, e sobre desenvolvimento de jogos, segue link pro meu TCC.

Utilização de Scrum no Desenvolvimento de Jogos Eletrônicos

Leiam, critiquem, xinguem, falem mal, reclamem sobre os erros sobre as normas da ABNT e JOGUEM SPACE COWBOY!

E é isso aê!