Wie erstelle ich Partikel, die auf den Spieler und die Feinde reagieren?

38

Ich mache gerade ein Spiel mit meiner eigenen Game-Engine, die ich in C ++ geschrieben habe, und verwende das neueste DirectX-SDK.

Das Spiel ist ein Top-Down-Weltraum-Shooter (mit einer ziemlich interessanten Wendung) und ich versuche, eine Art Nebeleffekt zu erzielen, durch den der Spieler fliegen wird. Ich möchte wirklich versuchen, das schöne taktile Gefühl von Hunderten von Partikeln festzuhalten, die sich aus dem Weg des Spielerschiffs bewegen, während es in sie hineinfliegt. In Geomtry Wars auf XBLA würde sich ein bisschen wie Partikel aus dem Weg des Spielers bewegen.

Ich bin ein erfahrener Programmierer, wenn es um C ++ geht. Ich weiß jedoch nicht, wie ich mit der Implementierung dieses Effekts beginnen soll. Hat jemand irgendwelche coolen Ideen oder Designentscheidungen, die ich prüfen möchte? Fühlen Sie sich frei, auf jeden Grad an Tiefe zu antworten, den Sie sich vorstellen.

Matt McDonald
quelle

Antworten:

65

Das ist eine coole Idee. Sie brauchen eine Art Diffusionsgradient um Ihr Schiff. Es gibt drei physikalische Modelle, die ich mir vorstellen kann:

  1. Sie möchten, dass es fast so aussieht, als wäre es ein flüssiges Medium, in dem sich der Druckgradient wieder ausgleicht, dh wenn Sie einige Partikel passiert haben, wandern diese zurück in Ihre Spur (wie Wasser hinter einem Boot). In diesem Fall sind die Positionen der Partikel absolut, und nur ihre Beziehung zum Player ändert vorübergehend ihre Renderposition . Dies ist ein bisschen so, als würde man ein dickes Vergrößerungsglas über Dinge halten und die Beugung scheint sie in Bewegung zu versetzen - aber nur, bis man das Glas wegbewegt. In diesem Fall ist Ihr Schiff das Glas.

  2. Wenn Sie möchten, dass sie sich vom Schiff entfernen und sich weiterbewegen, sobald sie sich bewegt haben. Dies entspricht der Standardphysik in einem im Allgemeinen leeren Raum, in dem es keine (oder nur sehr geringe) Druckgradienten gibt.

  3. Sie möchten die Partikel wie in (1) und (2) bei Annäherung schnell vom Schiff wegbewegen, aber sobald das Schiff verschwunden ist, gleichen sich die Partikel langsam aus, um in gleichem Abstand zu Ihnen zu sein.

Allen drei Lösungen gemeinsam ist, dass Sie ein Diffusionsfeld benötigen, das sich mit Ihrem Schiff bewegt. In diesem Beispiel machen wir es kreisförmig. Sie erkennen dann den Vektor v1 zwischen dem Schiff und jedem Partikel in dieser Region. Schieben Sie Ihr Partikel entlang dieses Vektors weg. Wie stark Sie es wegdrücken, hängt von der Entfernung zum Schiff ab: Verwenden Sie 1 - v1.magnitude. Mit dieser Formel erhalten Sie eine lineare Stärke. Sie können sie jedoch ändern, um eine kreisförmige Stärkekurve zu verwenden, deren Stärke in Richtung der Kanten abnimmt. Dies würde den Eindruck erwecken, als gäbe es eher einen kugelförmigen als einen kreisförmigen Druckgradienten um das Schiff.

Für Lösung 1 : Alles , was Sie jetzt tun ist , die ändern machen Position des Teilchens (das heißt, die Sprite - Position) auf jeder machen zu aktualisieren, die von diesem Vektor. Da Sie dies auf diese Weise tun, handelt es sich lediglich um einen Rendering-Effekt, der sich nicht auf die tatsächliche Weltposition des Partikels auswirkt. Sie addieren also die Weltposition zum Renderversatz (v1) und haben jetzt hübsch verschobene Partikel, wenn Sie sich an ihnen vorbei oder daneben bewegen, und kehren Partikel sanft zurück, wenn Sie (hinter Ihnen) vorbeigehen.

Für Lösung 2 : Anstatt nur Anwendung auf die Ansichtsposition v1, gilt es auf jeder Logik zu aktualisieren, um die Position des Teilchens. Also p1.position += v1. Sie üben also eine Beschleunigungskraft auf das Partikel aus, die sich in Geschwindigkeit umsetzt. Wahrscheinlich möchten Sie, dass die Geschwindigkeit jedes Partikels gedämpft wird, damit sie allmählich langsamer wird und zum Stillstand kommt, sobald Sie vorbeigekommen sind. Sie können sehen, wie diese Lösung zu Ansammlungen von Partikeln in Ihrem Nebel führt, da sie sich niemals neu ausbreiten. Ich bin mir sicher, dass dies nicht sehr realistisch ist, da Nebel Druckverläufe aufweisen, egal wie schwach sie in der Realität sind.

Für Lösung 3: Wie (2), aber in diesem Fall müssen Sie Ihre Partikel rediffundieren. Dies einfach zu tun ist eine Art Brute-Force-Ansatz, aber da es sich nur um Partikel und damit um eine Augenweide handelt, müssen Sie wahrscheinlich keinen großen Interessenbereich abdecken (wahrscheinlich nur einen Radius von playerPosition + maxPlayerSpeedPerTick oder was auch immer) rechteckige Fläche umschreibt dies aus logischen Gründen. Jedes Partikel übt innerhalb des interessierenden Bereichs eine Kraft auf jedes andere Partikel aus. Sie werden Kräfte anwenden, die wiederum auf ihren Abständen voneinander beruhen. Berechnen Sie alle Interpartikelkräfte in einem einzigen Durchlauf über den interessierenden Bereich und wenden Sie dann alle Kräfte in einem einzigen Durchlauf an. Stellen Sie schließlich sicher, dass Sie diese Zwischenteilchen-Kraftverarbeitung nur für Teilchen ausführen, die keine Geschwindigkeit haben. Und sobald ein bestimmtes Teilchen eine Mindestgeschwindigkeit erreicht,

Es gibt alle Arten von Diffusionsformeln usw., aber ich denke, in diesem Fall funktioniert eine einfache Lösung am besten.

Ingenieur
quelle
Leider habe ich derzeit nicht den Ruf, Ihre Antwort zu unterstützen (und ich würde es nur einmal tun können, was weniger ist, als es verdient). Sie haben mit Ihrer ersten Lösung genau das erreicht, wonach ich gesucht habe. Fantastische Antwort. Ehrlich. Vielen Dank!
Matt McDonald
Totale Freude Matt, es ist eine gute Frage und es lohnt sich, das Gehirn dafür zu biegen!
Ingenieur
Ich habe auch entschieden, dass ich dies mit sehr geringen Änderungen im Code auf kleinere Asteroiden innerhalb eines Gürtels anwenden könnte. Danke noch einmal.
Matt McDonald