Design und Architektur von Kollisionserkennungsspielen


8

Ich habe einige Artikel über die Kollisionserkennung gelesen. Meine Frage hier betrifft Ideen zum Design dafür.

Grundsätzlich habe ich ein C ++ - Spiel, das eine Hauptschleife mit Entitäten mit einer Aktualisierungsmethode hat. Basierend auf der Tastatureingabe aktualisieren diese Zeichen ihre Positionen.

Bei meiner Frage geht es nicht darum, wie Kollisionen erkannt werden können, sondern darum, Ideen zu erhalten, wie dies am besten umgesetzt werden kann. Das Spiel hat einen Hauptcharakter, aber auch Feinde, die zwischen ihnen kollidieren müssen. Daher bin ich mir nicht sicher, wo ich alle Iterationen durchführen soll, um Kollisionen zu überprüfen, und ob der richtige Weg darin besteht, alles gegen alles zu überprüfen.

Danke im Voraus.


Es gibt viele Ansätze. Eine besteht darin, jede Entität mit jeder anderen Entität zu vergleichen und statt zu berechnen, ob sie bereits kollidiert sind, zu berechnen, wann sie kollidieren (wenn überhaupt), und das Kollisionsereignis einem Array hinzuzufügen. Sortieren Sie das Array als Nächstes nach der Kollisionszeit, nehmen Sie das erste Element, wenden Sie Nachkollisionseffekte an (ändern Sie ihre Positionen und Geschwindigkeiten) und berechnen Sie entweder den Rest des Arrays neu oder berechnen Sie, welche Objekte von dieser Kollisionsauflösung betroffen sein können und Kollisionszeiten nur für sie neu berechnen.
Markus von Broady

Antworten:


9

Kommt ein bisschen darauf an, wie tief du gehen willst. Der Einfachheit halber würde ich entweder ein Observer-Muster für eine CollisionDetector-Klasse oder eine einfache Aggregation vorschlagen (der CollisionDetector hat einen Verweis auf die Welt, die alles enthält).

Grundsätzlich müsste man alles gegen alles prüfen. Bei einer Optimierung können Sie einen Sweep and Prune- Ansatz verwenden, um den Rechenaufwand zu reduzieren. Wenn Ihr Spiel einfach ist und nicht zu viele Schauspieler hat, können Sie dies jedoch überspringen.

Eine einfache Implementierung würde ungefähr so ​​aussehen:

class CollisionDetector:
  void Update():
    for gameobject in world:
      for otherGameobject in world:
        if gameobject == otherGameobject: continue

        collision = GetCollision(gameobject, otherGameobject)
        if collision:
          gameobject.Collide(collision)
          otherGameobject.Collide(collision)

Natürlich müssen die verschiedenen Kollisionserkennungsansätze und die Kollisionsreaktion von den kollidierenden Spielobjekten abhängen.


1

Gut. Es geht darum herauszufinden, ob:

  1. Es besteht keine Chance, dass diese beiden Objekte kollidierten
  2. Du musst es nicht wissen.

Für 1 ist es meistens eine Frage der Entfernung. Sie müssen immer noch die Positionen zweier Objekte vergleichen, aber wenn sie weit voneinander entfernt sind, können Sie davon ausgehen, dass sie nicht kollidieren, wodurch einige Berechnungen gespart werden.

2 hängt von Ihrem Spiel ab. Wenn Sie beispielsweise nur die Kollision zwischen Feinden berechnen, um sie nicht übereinander zu rendern, ist Ihnen die Kollision zwischen Feinden außerhalb des Bildschirms wahrscheinlich egal.

Möglicherweise können Sie auch bestimmte Gruppen von Objekten vollständig ignorieren. Wenn Sie beispielsweise wissen, dass sich eine ganze, angesehene Gruppe von Feinden am anderen Ende der Spielwelt befindet, können Sie diese einfach ignorieren, bis der Spieler näher kommt - und vielleicht sogar gehen sie aus Ihrer Update-Schleife, weil sie sehr weit weg sind.


0

Dadurch wird jedes Objekt einmal gegeneinander verglichen:

Object objects[];
for(i=0;i<objects.length;i++)
{
    for(j=i+1;j<objects.length;j++)
    { 
        //check for collision between objects[i] and objects[j]
    }
}

Danke für deine Antwort. Meine Hauptfrage betraf die architektonische Gestaltung.
Chompas
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.