Ich habe kürzlich ein Monogame aufgenommen und arbeite an einem einfachen Top-Down-Spiel, um mich anzufangen und die Grundlagen zu lernen.
Ich habe die Bewegung und die Drehung, um der Maus zu folgen, aussortiert, aber ich bin mit den Kollisionen festgefahren.
Was ich im Grunde wissen möchte, sind zwei Dinge:
- Was wäre der beste Weg, um mit Kollisionen umzugehen? Ich weiß, dass
Rectangle.Intersects(Rectangle1, Rectangle2)
das überlappende Rechteck zurückgegeben wird, aber da sich die Bewegung von oben nach unten auf der x / y-Achse befindet, möchte ich wissen, wo die Kollision stattfindet, damit ich eine Art "Wandgleiten" erstellen kann, das der Spieler nicht bekommt an der Wand stecken.
Ist es wirklich der beste Ansatz, die x / y-Koordinaten des Spielers mit den Koordinaten fester Objekte zu vergleichen und den Spieler dann an seine vorherige Position zu bringen, wenn er die Grenzen eines festen Objekts betritt? Was würdest du vorschlagen? - Was wäre der beste Weg, um Kollisionen auf alle Feststoffe, NPCs usw. anzuwenden? Ich denke gerade darüber nach, eine
gameObject
Klasse zu erstellen , von der alle Objekte erben und nur die Kollisionen dort behandeln.
Danke fürs Lesen und hoffe, dass mir jemand ein paar Tipps geben kann.
xna
c#
collision-detection
collision-resolution
monogame
Eliah John
quelle
quelle
Antworten:
Im Allgemeinen behandeln die meisten Physik-Engines dieses Problem, indem sie die sich überschneidenden Objekte trennen .
Wenn Ihre Objekte also durch Rechtecke dargestellt werden (auch als "Axis Aligned Bounding Boxes" bezeichnet) und auf einem bestimmten Rahmen wie folgt kollidieren:
Sie würden dann das Ausmaß der gegenseitigen Durchdringung auf jeder Achse messen. Wählen Sie dann die Achse mit der geringsten Durchdringung aus und trennen Sie die Objekte entlang dieser Achse.
Sie würden dies dann als "Kollision" registrieren und die entsprechende Dynamik anwenden.
Wenn Sie beispielsweise entlang der Wand gleiten möchten, setzen Sie die Geschwindigkeit auf der Achse, auf der Sie getrennt haben (die X-Achse in der obigen Abbildung), auf Null und lassen die Geschwindigkeit auf der anderen Achse allein.
Sie können aber auch Reibung anwenden oder die Objekte auseinander springen lassen.
Hier ist ein exzellentes, interaktives Tutorial , das viel detaillierter zeigt, wie das geht.
Wenn Sie diesen Weg weit gehen möchten (mehr als nur einfache AABB-Kollisionen), sollten Sie eine vorhandene Engine wie Farseer Physics verwenden .
Zum Schluss noch ein Hinweis zur Implementierung (wenn Sie nicht den Farseer-Weg gehen):
Rectangle
Verwendetint
Werte, die in den meisten Fällen für die Physik nicht wirklich geeignet sind. Erwägen Sie, eine eigeneAABB
Klasse zu erstellen, diefloat
stattdessen verwendet.Ihre zweite Frage wird durch meine alte Antwort zur Spielarchitektur hier ziemlich gut beantwortet , daher werde ich sie hier nicht wiederholen.
quelle
1: Ich habe auch an einem relativ einfachen Top-Down-Actionspiel gearbeitet und nach einer Woche (-s?) Kämpfen habe ich eine Art schrittweisen Ansatz zur Erkennung und Reaktion von Kollisionen verwendet. Der Hauptgrund dafür ist, dass die Verwendung der kürzesten Durchdringung in einigen Fällen zu einer "Teleportation" an eine neue Position führen würde, an der sich das sich bewegende Objekt zuvor nicht befand.
Wenn sich ein Objekt bewegen möchte,
Dieser Ansatz stellt sowohl sicher, dass das Objekt zurückspringt, um die vorherige Position zu korrigieren, als auch, dass es gegen die Wände, Objekte usw. gleiten kann.
2: Ich selbst verwende eine statische Kollisionsklasse, die von allem verwendet werden kann. Es enthält Methoden zur Kollisionserkennung und Vektoranpassung, die von so ziemlich allem aufgerufen werden können. Ob diese Methoden von einer "Master" -Spielklasse oder von einer Objektunterklasse aufgerufen werden, spielt in meinem Fall keine Rolle, da die Kollisionsklasse in jedem Frame für alle Rechtecke, mit denen sich das sich bewegende Objekt schneidet, eine neue Liste erstellt. Diese Rechtecke können aus Kacheln, Dekorationen, NPCs stammen, was auch immer Grenzen hat und im Grunde kollidierbar ist. Dies bedeutet, dass die bloße Notwendigkeit für alle Spielobjekte, die kollidierbar sind, darin besteht, ein Begrenzungsrechteck zu haben. Wenn sie das haben, erledigt die Kollisionsklasse den Rest.
hoffe das war verständlich.
quelle
1: Ich habe erfolgreich eine Technik verwendet, um dieses Problem zu lösen: Mithilfe der Geschwindigkeit und Position können Sie die Kollision ermitteln und zurücklaufen, bis die Position sehr nahe am genauen Kollisionspunkt liegt.
Dies ist nicht Teil der Antwort auf Ihre erste Frage. Wenn Sie jedoch viele Objekte haben, die miteinander kollidieren können, sollten Sie Quadtrees verwenden, um die Leistung zu verbessern. Es gibt ein sehr gutes Tutorial mit vielen Beispielen hier .
2: Ich empfehle immer Entity-Systems .
quelle