Mais diversão com um ES ...
Atualmente, tenho alguns sistemas:
- Renderizador (atributo Renderizável, atributo Transformar)
- Movimento (atributo Movable, atributo Transform, atributo Renderable [para caixas delimitadoras, etc])
- Entrada (atributo InputReceiver)
- etc.
Estou adicionando detecção de colisão. Meu primeiro pensamento foi adicionar um novo sistema que realiza colisão. Faz sentido para mim manter isso isolado do Motion
sistema, pois nem todas as coisas que se movem ou são animadas necessariamente participam da detecção de colisão - câmeras, neblina etc. -, mas parece que são Collision
e Motion
são interdependentes.
Quando Motion
move uma entidade, a transformação precisa ser validada Collision
e o movimento cancelado ou ajustado (saltando, parando em uma parede, etc.).
Uma alternativa seria criar um atributo Collidable que mantenha uma referência a um objeto de colisão - kd-tree, octree, etc. compartilhado entre entidades que podem colidir entre si. O Motion
sistema verificaria esse atributo e o usaria para verificar ou ajustar o movimento.
De uma perspectiva de código, essa é uma solução aceitável. No entanto, do ponto de vista da arquitetura do ECS, parece que ele está empurrando a lógica para o Motion
sistema que não se aplica a todas as entidades que possuem um Movable
atributo.
Eu também poderia armazenar um vetor de movimento no Movable
atributo e Collider
ajustar o sistema Transform
conforme necessário, mas isso envolverá a duplicação da funcionalidade entre Motion
e Collider
, ou um retorno de chamada de Collider
para Motion
alguns dados sobre o local da colisão e os dados da superfície para rejeição / reflexão, etc. .
Isso pode se enquadrar no título "caso especial hack", mas eu gostaria de obter algumas informações daqueles que lidaram com isso antes sem criar uma tonelada de código de caso de borda.
A pergunta Qual é uma boa maneira de evitar um acoplamento rígido entre os sistemas de movimento e colisão quando parece que eles exigem conhecimento um do outro?
Respostas:
Você está pensando demais. No meu mecanismo, que também usa um sistema de componente de entidade, todos
GameObject
podem ter um ponteiro para aModuleCollision
.O que acontece quando o jogo é atualizado:
Update
função para cada umGameObject
.Update
função, cada umGameObject
apenas atualiza sua velocidade e direção, não sua posição.GameObject
carrega sua posição atual, velocidade e direção para suaModuleCollision
, se houver uma disponível.ModuleCollision
base.UpdatePost
função em cada umGameObject
. Se o objeto tiver um módulo de colisão, ele buscará a posição, velocidade e direção atualizadas do módulo de colisão. A posição é atualizada com a velocidade e direção.GameObject
constrói uma matriz 3x3 final fora de sua posição e posição.Sim, há alguma duplicação de estado, mas tudo bem. Fazer o manuseio de colisões a
ModuleCollision
é a melhor maneira de fazer isso, porque, caso contrário, você teria que verificar cada umGameObject
para ver se ele possui umModuleCollision
identificador.fonte
Eu faria assim ...
Tem três sistemas:
O sistema de movimento aplica velocidades às posições. O sistema de aceleração aplica forças às velocidades. O sistema de colisão detecta colisões e aplica as forças nas direções corretas ou, se você quiser colisões brutas, altera diretamente as velocidades.
Por exemplo, você pode calcular o ângulo entre as colisões usando atan2 e, em seguida, usá-lo para aplicar as forças / velocidades corretas dos corpos.
Faça com que o sistema de detecção de colisão transmita mensagens, se necessário também.
fonte