Plus de plaisir avec un ES ...
Actuellement, j'ai quelques systèmes:
- Renderer (attribut Renderable, attribut Transform)
- Mouvement (attribut mobile, attribut de transformation, attribut de rendu [pour les boîtes englobantes, etc.])
- Input (attribut InputReceiver)
- etc.
J'ajoute la détection de collision. Ma première pensée a été d'ajouter un nouveau système qui effectue une collision. Il est logique pour moi de garder cela isolé du Motion
système car toutes les choses qui bougent ou sont animées ne participent pas nécessairement à la détection de collision - caméras, brouillard, etc. - mais cela semble Collision
et Motion
est interdépendant.
Lors du Motion
déplacement d'une entité, la transformation doit être validée Collision
et le mouvement annulé ou ajusté (rebond, arrêt sur un mur, etc.).
Une alternative serait de créer un attribut Collidable qui conserve une référence à un objet de collision - kd-tree, octree, etc. qui est partagé entre des entités qui peuvent entrer en collision les unes avec les autres. Le Motion
système vérifierait alors cet attribut et l'utiliserait pour vérifier ou ajuster le mouvement.
Du point de vue du code, c'est une solution acceptable. Cependant, du point de vue de l'architecture ECS, il semble que cela pousse la logique dans le Motion
système qui ne s'applique pas à toutes les entités qui ont un Movable
attribut.
Je pourrais également stocker un vecteur de mouvement dans l' Movable
attribut et faire Collider
ajuster le système Transform
selon les besoins, mais cela impliquera la duplication des fonctionnalités entre Motion
et Collider
, ou un rappel de Collider
à Motion
avec quelques données sur l'emplacement de la collision et des données de surface pour le rebond / réflexion, etc. .
Cela peut tomber sous le titre de "piratage de cas spécial", mais j'aimerais obtenir des commentaires de ceux qui ont déjà géré cela sans créer une tonne de code de cas de pointe.
La question Quelle est la bonne façon d'éviter un couplage étroit entre les systèmes de mouvement et de collision quand il semble qu'ils nécessitent une connaissance mutuelle?
Réponses:
Vous y pensez trop. Dans mon moteur, qui utilise également un système de composants d'entité, chacun
GameObject
peut avoir un pointeur sur aModuleCollision
.Que se passe-t-il lorsque le jeu est mis à jour:
Update
fonction pour chacunGameObject
.Update
fonction, chacunGameObject
ne met à jour que sa vitesse et sa direction, pas sa position.GameObject
télécharge sa position actuelle, sa vitesse et sa direction sur sonModuleCollision
, le cas échéant.ModuleCollision
base.UpdatePost
fonction sur chacunGameObject
. Si l'objet possède un module de collision, il récupère la position, la vitesse et la direction mises à jour à partir du module de collision. La position est mise à jour avec la vitesse et la direction.GameObject
construit une matrice 3x3 finale à partir de sa position et de son cap.Oui, il y a une certaine duplication d'état, mais ça va. La gestion des collisions sur un
ModuleCollision
est la meilleure façon de procéder, car sinon vous devriez vérifier chacunGameObject
pour voir s'il a uneModuleCollision
poignée.la source
Je le ferais comme ça ...
Ont trois systèmes:
Le système de mouvement applique des vitesses aux positions. Le système d'accélération applique des forces aux vitesses. Le système de collision détecte les collisions et applique les forces dans les bonnes directions ou, si vous voulez des collisions brutes, modifie directement les vitesses.
Par exemple, vous pouvez calculer l'angle entre les collisions en utilisant atan2 , puis l'utiliser pour appliquer les forces / vitesses correctes aux corps.
Demandez également au système de détection de collision de diffuser des messages si nécessaire.
la source