Uma introdução ao modelo de Entidades Componentes em swift

Reutilizando componentes em seu jogo iOS com Gameplay Kit

--

Introdução

Se assim como eu você não é um desenvolvedor de games experiente, talvez essa seja a primeira vez que você tenha escutado o termo Entidade Componente. Nesse post a minha intenção é deixar claro o motivo de usar entidade componente e não utilizar uma abordagem de herança que aprendemos em Programação Orientada a Objetos (POO).

Esse post está dividido em:

  • O problema em usar herança (É importante ler se você não entende bem o motivo de não usar herança, para reaproveitar componentes de um jogo)
  • Primeiros passos com entidades componentes

O problema em usar herança

No mundo da programação há que defenda e quem condene a abordagem de POO, eu particularmente gosto, mas essa não é a questão aqui. Mesmo gostando da metodologia usada em POO, eu percebi que a abordagem se torna ruim quando estamos falando de games.

Um dos motivos para isso acontecer, é que diferente de outros tipos softwares, é muito comum que vários personagens no jogo possuam uma mesma característica, como por exemplo andar, pular, correr. Isso pode levar você a pensar em criar uma classe pai e fazer com que todos herdem deles. Isso ficaria parecido com:

Até aqui tudo bem, O problema começa a surgir quando começarmos a criar mais personagens e quisermos personalizar somente alguns deles, por exemplo, digamos que temos Mario, Luigi e Yoshi herdando de Character, e queremos adicionar uma funcionalidade de correr rápido para o Mario e o Luigi, basicamente temos duas opções:

  • Criar o método no Character e sobrescrever somente no Yoshi, fazendo com que ele não faça nada. (Parece Feio heim!)
  • Criar o método de correr somente no Mario e no Luigi, aí é só copiar e colar. (Isso também não é legal)

Veja que ambas as soluções não parecem ser corretas, pois vai contra as boas práticas que aprendemos. Você pode está dizendo:

— Temos outra forma de resolver, basta usar Protocolos, e fazer a implementação de cada objeto.

Note que isso não é uma boa solução, porque estamos partindo do princípio que o comportamento será idêntico para ambos os personagens, o que irá ocorrer será novamente o copy and paste.

Eu espero ter deixado claro o motivo que trabalhar com herança nesse exemplo, pode trazer uma complexidade e retrabalho no seu projeto. No próximo tópico eu mostrarei como usar o modelo de entidades e componentes para resolver esse problema.

Primeiros passos com entidades componentes

Podemos entender o modelo de entidades componentes como um lego, onde cada componente é uma peça de lego, que tem sua própria cor e forma, e consegue se encaixar com outras para se obter uma nova forma.

Cada componente representa um comportamento da nossa entidade. No nosso exemplo a entidades seriam Mario, Luigi e Yoshi, e os componentes seriam pular, correr, parar e correr rápido.

Vamos criar nosso primeiro componente, o componente responsável por fazer nosso personagem andar.

Veja que é super simples, basta que nossa classe herde de GKComponent para que ela seja considerada um componente. Vamos agora criar nosso segundo componente, o componente de pular.

Para simplificar o exemplo vamos definir a seguinte regra para nosso jogo:

  • Mario: anda e pula
  • Luigi: anda e pula
  • Yoshi: anda.

Como já temos os componentes que de andar e pular, agora basta criar nossos personagem para usar esse componentes de acordo com a regra do nosso jogo.

Note que é muito simples criar nossos personagens, basta que cada um deles seja uma entidade, e em seguida só adicionamos os componentes (comportamentos) a cada um deles, de acordo com nossa regra do jogo.

Usando os componentes

Para usar os componentes é bastante simples, para demostrar vamos fazer o Mario andar e pular, e fazer o Yoshi andar, afinal esse é o único comportamento dele.

Perceba que o metodo component(ofType:) retorna um component opcional, porque pode ser que você solicite um componente que não está disponível. Nada impede de eu chamar o componente JumpComponent no yoshi, mas como não foi adicionado, ele simplesmente não funcionará.

Essa abordagem abre outras possibilidades, imagine que se o Mario comer uma determinada fruta ele poderá voar. Bastariámos criar um outro componente responsável por fazer o personagem voar. Você também pode remover um componente a qualquer momento, basta invocar o método removeComponent(ofType:).

Conclusão

Podemos ver a simplicidade de trabalhar usando o modelo entidade componentes no Swift, o framework Gameplay Kit já trás um ótimo suporte. Se você ainda tiver alguma dúvida ou questionamento sobre a abordagem, compartilhe conosco.

Resources

Durante minhas pesquisas eu encontrei os dois links abaixo, que foram essenciais para meu entendimento sobre o assunto. O primeiro mostra uma introdução e o segundo é um projeto exemplo feito pela própria Apple, o projeto é super simples, mas da pra entender muito claro o poder de usar a anordagem de entidades componentes.

--

--