Ich mache ein einfaches Shooter-Spiel, ähnlich wie "Galaga" , als Teil einer Präsentation, die ich mache. Ich frage mich, welche Strategien und Datenstrukturen die Leute verwenden würden, um Projektile wie vom Raumschiff abgefeuerte Laser zu verfolgen. Eine supereinfache Implementierung, die ich bisher verwendet habe, besteht darin, jedes Projektil als Punkt darzustellen und auf Kollisionen mit allen Objekten in der Szene zu prüfen.
Dies scheint jedoch in großen Szenen mit vielen Projektilen kostspielig zu sein. Ich frage mich, welche anderen Arten von Strategien oder Implementierungen für diese Art von Anwendungsfall verwendet werden. Was verwenden Spiele wie FPS zum Verfolgen von Projektilen (Kugeln, Panzergranaten usw.)?
game-design
design-patterns
Polaris878
quelle
quelle
Antworten:
Für sehr schnelle Projektile (wie Laser oder Kugeln) können Sie einen Strahl verwenden .
Ein Strahl hat einen Startpunkt und einen Endpunkt. Eine (sehr minimale) Datenstruktur für einen Strahl ist:
Sieht aus wie das:
(Sie könnten auch den Richtungsvektor und die Länge zwischenspeichern, aber ich habe oben eine sehr einfache Definition verwendet).
Wenn es sich bei dem Strahl um einen Laserstrahl handelt, der sich mit Lichtgeschwindigkeit ausbreitet, müssen Sie den Strahl nur für ein paar Frames beibehalten (beginnend an der Pistolendüse und endend an einer Wand). Alles, was den Strahl schneidet, erleidet Schaden.
Wenn der Strahl ein langsameres Projektil ist (z. B. eine Kugel), wird die Entfernung, die die Kugel über einen Zeitschritt zurückgelegt hat, durch den Strahl modelliert. Der Startpunkt ist der Punkt, an dem sich der Strahl am Anfang des Rahmens befindet, und der Endpunkt ist der Punkt, an dem sich der Strahl befindet, nachdem der Rahmen fertig ist. Alles, was dem Strahl der Kugel im Weg steht, wird durch die Kugel beschädigt.
Strahlen können effizient mit Kugeln, Aabbs, konvexen Hüllen usw. kollidiert werden. Ein aktuelles Programm finden Sie in meinem Hullinator- Projekt (STRG + Klicken, um Strahlen abzufeuern ).
quelle
Die Verwendung eines Strahls eignet sich gut zum sofortigen Bewegen von Projektilen wie Kugeln. Bei Projektilen mit geringerer Geschwindigkeit, wie sie für Ihr Weltraumspiel verwendet werden, ist es sinnvoll, ihre Position in der Spielwelt einfach wie bei jeder anderen Entität zu verfolgen. Was ich oft tue, ist eine Basisklasse namens Entity, die Eigenschaften eines dauerhaften Spielobjekts enthält - Position, Rotation, Kollisionsbox usw. Meine vom Spieler angetriebenen und Projektile erben dies und meine Spielwelt muss nur wissen, wie sie damit umgeht die Superklasse Entity, nicht jeder einzelne Entitätstyp.
Um die Leistung zu steigern, wird häufig ein Pool für alle Objekte angelegt, die Sie häufig erstellen und zerstören. Wenn Sie ein neues Projektil benötigen, das Sie aus diesem Pool ziehen möchten, ändern Sie das neue Projektil nach Bedarf und legen Sie es nach Ablauf wieder in den Pool zurück.
quelle
Wenn Sie die Kollisionserkennung optimieren möchten, können Sie alle Spielobjekte in einem zwei- oder dreidimensionalen Baum speichern . Diese Datenstruktur macht es sehr effizient, alle Objekte in einem bestimmten Bereich abzurufen.
Binäre Bäume haben jedoch den Nachteil, dass sie leicht verfallen, wenn Objekte hinzugefügt, entfernt und ihre Position geändert werden. Sie müssen sie daher automatisch ausgleichen .
Ein Kompromiss, der einfacher umzusetzen, aber nicht ganz so effizient wäre, wäre ein Block-basierter Ansatz. Teilen Sie das Spielfeld in Würfel und verfolgen Sie, welche Objekte die einzelnen Würfel berühren. Wenn Sie nach Kollisionen mit einem Objekt suchen, müssen Sie es nur mit den Objektlisten der Würfel vergleichen, die es berührt (ersetzen Sie "Würfel" durch "Rechteck" für ein 2D-Spiel).
quelle