fundo
Faço o desenvolvimento de jogos como um hobby e estou procurando uma maneira melhor de projetá-los. Atualmente, estou usando uma abordagem padrão de POO (desenvolvo empresas há 8 anos, por isso é necessária a cada ano). Tomemos, por exemplo, um "vilão"
public class Baddie:AnimatedSprite //(or StaticSprite if needed, which inherit Sprite)
{
//sprite base will have things like what texture to use,
//what the current position is, the base Update/Draw/GetInput methods, etc..
//an AnimatedSprite contains helpers to animated the player while
//a StaticSprite is just one that will draw whatever texture is there
}
O problema
Digamos que eu estou fazendo um jogo de plataformas 2D e preciso do vilão para poder pular. Normalmente, o que faço é adicionar o código apropriado nos métodos Update / GetInput. Então, se eu precisar fazer o jogador engatinhar, pular, subir, etc ... o código vai para lá.
Se eu não tomar cuidado, esses métodos ficam desordenados, então acabo criando pares de métodos como este
CheckForJumpAction(Input input)
e DoJump()
CheckforDuckAction(Input input)
e DoDuck()
então GetInput parece
public void DoInput(Input input)
{
CheckForJumpAction(input);
CheckForDuckAction(input);
}
e atualização parece
public void Update()
{
DoJump();
DoDuck();
}
Se eu for criar outro jogo em que o jogador precise pular e pular, geralmente entro em um jogo que tem a funcionalidade e o copio. Bagunçado, eu sei. É por isso que estou procurando algo melhor.
Solução?
Eu realmente gosto de como o Blend tem comportamentos que posso anexar a um elemento. Eu tenho pensado em usar o mesmo conceito nos meus jogos. Então, vamos olhar para os mesmos exemplos.
Eu criaria um objeto Behavior básico
public class Behavior
{
public void Update()
Public void GetInput()
}
E eu posso criar comportamentos usando isso. JumpBehavior:Behavior
eDuckBehavior:Behavior
Posso adicionar uma coleção de comportamentos à base do Sprite e adicionar o que preciso para cada entidade.
public class Baddie:AnimatedSprite
{
public Baddie()
{
this.behaviors = new Behavior[2];
this.behaviors[0] = new JumpBehavior();
//etc...
}
public void Update()
{
//behaviors.update
}
public GetInput()
{
//behaviors.getinput
}
}
Então agora, se eu quisesse usar o Jump and Duck em muitos jogos, posso apenas trazer os comportamentos. Eu poderia até criar uma biblioteca para os comuns.
Funciona?
O que não consigo descobrir é como compartilhar o estado entre eles. Olhando Jump e Duck, ambos afetam não apenas a parte atual da textura que está sendo desenhada, mas também o estado do jogador. (O salto aplicará uma quantidade decrescente de força para cima ao longo do tempo, enquanto o duck apenas interromperá o movimento, mudará a textura e o tamanho da colisão do bandido.
Como posso amarrar isso para que funcione? Devo criar propriedades de dependência entre os comportamentos? Devo que cada comportamento conheça o pai e o modifique diretamente? Uma coisa que pensei foi poder passar um delegado em cada comportamento para ser executado quando ele é acionado.
Estou certo de que estou analisando mais problemas, mas o objetivo é poder reutilizar facilmente esses comportamentos entre jogos e entidades no mesmo jogo.
Então eu entrego a você. Importa-se de explicar como / se isso pode ser feito? Você tem uma ideia melhor? Sou todo ouvidos.