Sollte ich wegen der Netzwerkintegration meine eigene Physik-Engine schreiben?

11

Ich entwickle gerade einen Top-Down-Echtzeit-Zombie-Shooter. Ich codiere dies in Java und verwende JBox2D als meine Physik-Engine. Ich habe diese Woche das Netzwerk codiert und bin jetzt mit der Synchronisation der Physik beschäftigt.

Ich plane, das Predictive Client / Authoritative Server-Modell zu verwenden, bei dem sich der Client frei bewegen kann, solange der Server dies später genehmigt. Dies beinhaltet, dass der Client Pakete mit Bewegungsdaten an den Server sendet und der Server die Latenz berechnet und die Welt aus einem älteren Zustand neu simuliert.

Mein Problem ist, dass meine aktuelle Physik-Engine, JBox2D (im Grunde ein Port von Box2D), das Zurückrollen der Welt nicht unterstützt und es anscheinend nicht so einfach ist, die Weltdaten zu serialisieren. Ich habe 2 Lösungen, ich könnte entweder meine aktuelle Physik-Engine modifizieren / erweitern oder meine eigene schreiben.

Gründe für das Schreiben meiner eigenen Physik-Engine -

  • Ich kann unnötige Funktionen entfernen. In einem Top-Down-Spiel brauche ich nur Kollisionsmechanik und Handhabungskräfte. Es ist keine Schwerkraft beteiligt.
  • Ich kann den Code besser verstehen und es wäre [höchstwahrscheinlich] einfacher, Rollback-Funktionen zu implementieren

Gründe für die Erweiterung / Änderung von JBox2D

  • Das Schreiben meiner eigenen Physik-Engine wäre ein erheblicher Arbeitsaufwand, der umständlich sein könnte
  • JBox2D hat eine breite unterstützende Community, die mir bei meinem Entwickler helfen kann
  • JBox2D verfügt über spezifische Optimierungen für Dinge wie die Kollisionserkennung, die es nützlich machen
  • Einige Arbeiten wurden bereits durchgeführt, aber es wurde nur wenig Code freigegeben

Also, was sind deine Meinungen. Dies ist mein erstes Spiel und ich bin kein professioneller Spieleentwickler. Wenn jemand einige Links zu Arbeiten bereitstellen könnte, die bereits in der Region ausgeführt wurden (vorzugsweise mit JBox2D / Box2D / Java).

Liamzebedee
quelle
Beachten Sie auch, dass Sie JBox2D strictfpüberall verwenden müssen, da dies die Leistung erheblich beeinträchtigt. Andernfalls erhalten der Server und der Client möglicherweise nicht genau die gleichen Ergebnisse. Ich würde empfehlen, stattdessen einen festen Punkt zu verwenden.
Sam Hocevar

Antworten:

7

Die Kollisionserkennung in 2D ist so verdammt einfach, dass ich nicht weiß, warum Sie sich überhaupt die Mühe machen würden, eine Physik-Engine zu verwenden. Und da alle Handhabungskräfte direkt oder in einer Kurve sind (kein Sturz, keine Änderung der Diagnosen usw.), ist es für mich persönlich ein Kinderspiel, das Sie auswählen sollten. Eigenes zu machen ist einfach. Kollision:

Berücksichtigen Sie die 3 möglichen Kollisionen, die in 2 Rechtecken auftreten können:

  1. Kante an Kante: Ganz einfach, Sie erhalten die Achse einer einzelnen Kante und einer anderen und Sie entscheiden, ob sie entweder denselben Raum oder nahe genug daran einnehmen.
  2. Kante zu Ecke: Dies ist am häufigsten der Fall, wenn Sie rotierende Formen haben. Zum Glück ist es auch recht einfach zu implementieren.
  3. Ecke zu Ecke: Dies wird so selten vorkommen, dass es sich nicht einmal lohnt, es umzusetzen. Der Grund dafür ist, dass sich zwei Dinge in genau entgegengesetzten Richtungen auf derselben exakten Achse bis zur zuletzt berechneten Dezimalstelle Ihres Motors bewegen müssten. Wenn sich nun alles um 45 oder 90 Grad dreht, kann es sich lohnen, dies (auch noch wahrscheinlich nicht) einzuschließen

EDIT: Wie kommentiert, bin ich mit dieser Angelegenheit weit weniger vertraut und sollte nicht über die Kugel- / Projektilkollision konsultiert werden.

Wenn ich mit Kugeln im 2D-Raum gearbeitet habe, habe ich eine Art Pfad verwendet, der sowohl in gerader als auch in gekrümmter Richtung funktioniert, wobei ich das Projektil mit der Physik-Engine (die ich nicht von Grund auf neu erstellt habe) geworfen und eine Standardkollision verwendet habe.

Lesen Sie in den Kommentaren, wie Sie dies von Grund auf neu erstellen.


BEARBEITEN: * Vertrau mir, * unabhängig davon, welche du brauchst, wird in deiner Spiele-Engine eine Form der toten Rechnung benötigt, wegen der Projektile und wie viele Projektile zu einem bestimmten Zeitpunkt auf dem Bildschirm sein könnten. Sie möchten ABSOLUT nicht jede einzelne Kugel auf dem Bildschirm pro Frame an der angegebenen Position aktualisieren. Aber es ist eine großartige Möglichkeit, ein Spiel unspielbar langsam zu machen: D! Sie sollten immer nur diese Dinge aktualisieren:

  • Ein Projektil wird geworfen
  • Die Richtung, in die es geworfen wird
  • Ob es gebogen ist oder nicht
    • Und wenn ja, welche Funktion hat die Kurve?
  • Was für ein Projektil es ist (Dies erklärt die Grafik, Effekte, Schäden, alles)

Aktualisieren Sie nun die Daten in der Engine entsprechend diesen Daten und nicht auf dem Server für jedes verdammte Projektil und senden Sie Paketdaten für jede einzelne Kugel aus. (Stellen Sie sich vor, Sie machen das mit nur 2 Maschinengewehren auf dem Bildschirm! Jesus!)

Joshua Hedges
quelle
Natürlich ist es relativ einfach zu implementieren, aber ich interessiere mich auch für die Optimierung der Kollisionserkennung, von der ich keine Ahnung habe, wie sie implementiert werden soll.
Liamzebedee
Die von mir beschriebene Methode erfordert keine Optimierung, wenn Sie sie wie beschrieben ausführen. Die einzige Optimierung, die möglicherweise erforderlich ist, ist die Zeit, in der Sie die Überprüfungen durchführen, und wie oft Kollisionen tatsächlich aktualisiert werden. Beispiel: Sie müssen WIRKLICH nur aktualisiert werden, wenn die Möglichkeit einer Kollision besteht.
Joshua Hedges
Um das zu erweitern, was ich zuletzt gesagt habe. Sie müssen nur dann wirklich nach Gebäudekollisionen suchen, wenn sich Ihr Charakter überhaupt bewegt. Sie müssen immer nur nach Einheitenkollisionen suchen, wenn Sie sogar Einheiten im Blick haben, die nicht Ihr Charakter sind. Sie müssen nur dann nach Projektilkollisionen suchen, wenn sie (in diesem Moment) überhaupt existieren. Sie können jede Form der Kollisionstyperkennung überspringen (ist es Kante an Kante? Ecke an Kante? Usw.), nachdem Sie wissen, dass etwas sogar etwas anderes berührt oder sich in der Nähe davon befindet. Andernfalls überspringen Sie es insgesamt.
Joshua Hedges
Außer wenn ich Kollisionen serverseitig verarbeite, bei denen ich Kollisionen für mehrere Spieler usw. erkennen muss
Liamzebedee
4
@ MadPumpkin: Ihr übermäßiges Vertrauen spiegelt Ihre Antwort schlecht wider. Sie sprechen von der Erkennung von Kollisionen, erwähnen jedoch nicht die Erkennung von Sweep-Kollisionen, die den absoluten Kern der ordnungsgemäßen Handhabung von Kugeln in einem 2D-Shooter darstellt. Auch beim Sweeping ist die Auflösung ungefähr so ​​wichtig wie die Erkennung, da Sie entscheiden müssen, welche Kollision zuerst aufgetreten ist, potenzielle Konflikte lösen und möglicherweise die gesamte Auflösung bei entfernten Entitäten erneut starten müssen. Sicherlich nicht die triviale Angelegenheit, die Sie zu implizieren scheinen.
Sam Hocevar