Estou trabalhando em um jogo simples baseado em blocos.
O jogo consiste basicamente em mover blocos na área de jogo, por isso é uma simulação física trivial. Minha implementação, no entanto, está longe de ser ideal e estou pensando se você pode me dar alguma dica sobre como fazê-lo melhor.
Dividi o código em duas áreas: lógica do jogo e interface do usuário, como fiz com muitos jogos de quebra-cabeça:
- A lógica do jogo é responsável pelas regras gerais do jogo (por exemplo, o sistema formal de regras no xadrez)
- A interface do usuário exibe a área e as peças do jogo (por exemplo, tabuleiro e peças de xadrez) e é responsável pelas animações (por exemplo, movimento animado das peças de xadrez)
A lógica do jogo representa o estado do jogo como uma grade lógica, onde cada unidade tem a largura / altura de uma célula na grade. Portanto, para uma grade de largura 6, você pode mover um bloco de largura 2 quatro vezes até que ele colide com o limite.
A interface do usuário pega essa grade e a desenha convertendo tamanhos lógicos em pixels (ou seja, multiplica por uma constante). No entanto, como o jogo praticamente não tem lógica de jogo, minha camada de lógica de jogo [1] não tem muito o que fazer, exceto a detecção de colisão. Veja como funciona:
- O jogador começa a arrastar uma peça
- A interface do usuário solicita à lógica do jogo a área de movimento legal dessa peça e permite que o jogador a arraste para dentro dessa área
- Jogador solta um pedaço
- A interface do usuário encaixa a peça na grade (para que fique em uma posição lógica válida)
- A interface do usuário informa à lógica do jogo a nova posição lógica (por meio de métodos mutadores, que eu prefiro evitar)
Não estou muito feliz com isso:
- Estou escrevendo testes de unidade para a minha camada de lógica do jogo, mas não a interface do usuário, e acabou que todo o código complicado está na interface do usuário: impedindo a peça de colidir com outras pessoas ou o limite e encaixando-a na grade.
- Não gosto do fato de a interface do usuário informar a lógica do jogo sobre o novo estado; prefiro chamar um
movePieceLeft()
método ou algo parecido, como nos outros jogos, mas não fui muito longe com essa abordagem, porque a lógica do jogo não sabe nada sobre o arrastar e ajustar possível na interface do usuário.
Eu acho que a melhor coisa a fazer seria me livrar da camada de lógica do jogo e implementar uma camada de física. Eu tenho algumas perguntas sobre isso:
- Essa camada de física é comum ou é mais típico que a camada de lógica do jogo faça isso?
- O encaixe na grade e o código de arrasto da peça pertenceriam à interface do usuário ou à camada física?
- Essa camada de física normalmente funcionaria com tamanhos de pixel ou com algum tipo de unidade lógica, como minha camada de lógica de jogo?
- Já vi uma detecção de colisão baseada em eventos na base de código de um jogo, ou seja, o jogador apenas arrastava a peça, a interface do usuário renderizava isso obedientemente e notificava o sistema de física, e o sistema físico chamava um método onCollision () na peça uma vez que uma colisão é detectada. O que é mais comum? Esta abordagem ou pedindo a área de movimento legal primeiro?
[1] camada provavelmente não é a palavra certa para o que quero dizer, mas o subsistema parece exagerado e a classe é equivocada, porque cada camada pode consistir em várias classes.