J'ai récemment choisi le jeu monogame et je travaille sur un simple jeu descendant pour me lancer et apprendre les bases.
J'ai réglé le mouvement et la rotation pour suivre la souris, mais je suis coincé avec les collisions.
Ce que je veux savoir, en gros, ce sont deux choses:
- Quelle serait la meilleure façon de gérer les collisions? Je sais que cela
Rectangle.Intersects(Rectangle1, Rectangle2)
renvoie le rectangle qui se chevauchent, mais, comme le mouvement de haut en bas est sur l'axe x / y, je voudrais savoir où la collision se produit afin que je puisse créer une sorte de "glissement de mur" où le joueur n'obtient pas collé au mur.
Vérifier les coordonnées x / y du joueur par rapport aux coordonnées des objets solides, puis lancer le joueur à sa position précédente s'il entre dans les limites d'un objet solide est-il vraiment la meilleure approche? Que suggérerais-tu? - Quelle serait la meilleure façon d'appliquer des collisions à tous les solides, aux PNJ, etc.? Je pense actuellement à créer une
gameObject
classe dont tous les objets hériteront et géreront simplement les collisions.
Merci d'avoir lu et j'espère que quelqu'un pourra me donner quelques conseils.
xna
c#
collision-detection
collision-resolution
monogame
Eliah John
la source
la source
Réponses:
En règle générale, la plupart des moteurs physiques gèrent ce problème en séparant les objets qui se croisent .
Donc, si vos objets sont représentés par des rectangles (également appelés "boîtes de délimitation alignées sur les axes"), et qu'ils entrent en collision sur un cadre donné comme suit:
Vous mesureriez alors la quantité d'interpénétration sur chaque axe. Sélectionnez ensuite l'axe avec la plus petite interpénétration et séparez les objets le long de cet axe.
Vous enregistreriez alors cela comme une "collision" et appliqueriez la dynamique appropriée.
Par exemple, si vous voulez glisser le long du mur, vous devez simplement mettre à zéro la vitesse sur l'axe sur lequel vous vous êtes séparé (l'axe X, dans l'illustration ci-dessus), en laissant la vitesse sur l'autre axe seul.
Mais vous pouvez également appliquer une friction ou faire rebondir les objets.
Voici un excellent didacticiel interactif qui montre comment procéder de manière beaucoup plus détaillée.
Bien que, si vous allez loin dans cette voie (autre chose que de simples collisions AABB), vous voudrez peut-être envisager d'utiliser un moteur existant comme Farseer Physics .
Enfin, une note sur l'implémentation (si vous ne suivez pas la voie Farseer):
Rectangle
utilise desint
valeurs, qui ne sont pas vraiment appropriées pour faire de la physique dans la plupart des cas. Pensez à créer votre propreAABB
classe qui utilise à lafloat
place.Votre deuxième question est assez bien répondue par mon ancienne réponse sur l'architecture de jeu ici , donc je ne la répéterai pas ici.
la source
1: J'ai également travaillé sur un jeu d'action descendant relativement simple, et après une semaine (-s?) De lutte, j'ai fini par utiliser une sorte d'approche pas à pas pour la détection et la réponse aux collisions. La raison principale étant que l'utilisation de l'interpénétration la plus courte entraînerait dans certains cas une "téléportation" vers une nouvelle position dans laquelle l'objet en mouvement ne se trouvait pas auparavant.
donc, quand un objet veut bouger,
cette approche garantit à la fois que l'objet "rebondit" dans sa position précédente correcte et permet de glisser contre les murs, les objets, etc.
2: J'utilise moi-même une classe de collision statique qui peut être utilisée par n'importe quoi. il contient des méthodes de détection de collision et d'ajustement vectoriel, qui peuvent être appelées par à peu près n'importe quoi. que ces méthodes soient appelées à partir d'une classe de jeu "maître" ou par une sous-classe d'objets n'a pas vraiment d'importance dans mon cas, car la classe de collision crée une nouvelle liste à chaque trame pour tous les rectangles avec lesquels l'objet en mouvement se croise. ces rectangles peuvent provenir de tuiles, de décorations, de PNJ, tout ce qui a des limites et est collable, en gros. cela signifie que la simple nécessité pour tous les objets de jeu qui sont en collision est d'avoir un rectangle de délimitation. s'ils l'ont, la classe de collision gérera le reste.
espérons que cela était compréhensible.
la source
1: J'ai réussi à utiliser une technique pour résoudre ce problème: en utilisant la vitesse et la position, vous pouvez découvrir la collision et recommencer jusqu'à ce que la position soit très proche du point de collision exact.
Cela ne fait pas partie de la réponse à votre première question, mais si vous avez beaucoup d'objets qui peuvent entrer en collision les uns avec les autres, vous devez utiliser des arbres quadruples pour améliorer les performances. Il y a un très bon tutoriel avec beaucoup d'exemples ici .
2: Je recommande toujours Entity-Systems .
la source