Manipulieren der Bewegung von Partikeln mit Stardust Particle Engine - Teil 2

Dies ist der zweite Teil dieses Tutorials. Ich werde Ihnen zeigen, wie Sie die Partikelbewegung mit Deflektoren beeinflussen können.

Vorkenntnisse zu Bewegungsgrundlagen und Vektorfeldern sind erforderlich. Ich empfehle dringend, dass Sie den ersten Teil dieses Tutorials abschließen, bevor Sie fortfahren.


Endergebnisvorschau

Schauen Sie sich das Endergebnis an, auf das wir hinarbeiten werden. Dies ist ein Beispiel für einen Bodeneffekt, bei dem Partikel vom Boden abprallen.


Deflektoren

Ähnlich wie Schwerkraftfelder nimmt ein Deflektor die aktuellen Bewegungsdaten eines Partikels als Eingabe auf. Danach überschreibt der Deflektor die Bewegung des Partikels mit seiner Ausgabe, nur dass die Ausgabe jetzt zusätzlich zu den Positionsdaten Geschwindigkeitsdaten enthält. Daher ist im 2D-Raum die Ausgabe eines Deflektors ein 4D-Vektor; Die ersten beiden Komponenten des 4D-Vektors repräsentieren die x- und y-Komponente des Positionsvektors (bezeichnet mit x und y) bzw. die letzten beiden Komponenten repräsentieren die x- und y-Komponente des Geschwindigkeitsvektors (bezeichnet mit vx und vy).


Wie man Deflektoren benutzt

Erinnere dich an die Feld Klasse und die Schwere Aktion aus dem ersten Teil dieses Tutorials? Nun, das Verfahren ist ähnlich. Du erschaffst Deflektor Objekte, die Partikelbewegungen manipulieren, und fügen sie dann dem hinzu Ablenken Aktion, genau wie Sie hinzufügen würden Feld Objekte an die Schwere Aktion. Nun ein kurzes Beispiel.


Bodeneffekt

In diesem Beispiel verwenden wir die LineDeflector Klasse, um einen Partikel-Abpraller-Effekt zu erzielen. Ein Liniendeflektor simuliert im Wesentlichen eine unendlich lange Linie im 2D-Raum, wobei eine Seite offen ist und die andere Seite fest ist. Partikel dürfen nur im freien Raum und nicht im festen Raum sein. Wenn Partikel von der offenen Seite kommen und die Linie treffen, springen sie zurück. Das Particle.collisionRadius Eigenschaft, die den Radius eines Partikels darstellt, wird berücksichtigt.

Der Linienablenker verwendet einen Normalenvektor und einen Punkt, den die Linie im 2D-Raum durchläuft, um die Linie zu bestimmen. Hier ist eine Illustration, um Ihnen eine bessere Vorstellung zu geben.


Schritt 1: Floor Effect Circle Symbol

Erstellen Sie ein neues Flash-Dokument, zeichnen Sie einen Kreis mit einem Radius von 10 und konvertieren Sie es in ein Symbol, das für ActionScript mit einem Klassennamen exportiert wird Kreis.


Schritt 2: Bodeneffekt Die Dokumentenklasse

Legen Sie eine AS-Datei für die Dokumentenklasse an. Die Klasse erstellt einen Emitter und einen Renderer. Wenn Sie eine Auffrischung der grundlegenden Verwendung von Stardust wünschen, können Sie dieses Lernprogramm ausprobieren.

 package import flash.display.Sprite; import flash.events.Event; import idv.cjcat.stardust.common.emitters.Emitter; import idv.cjcat.stardust.common.renderers.Renderer; import idv.cjcat.stardust.twoD.renderers.DisplayObjectRenderer; public class FloorEffect erweitert Sprite private var emitter: Emitter; privater var-Renderer: Renderer; öffentliche Funktion FloorEffect () emitter = new CircleEmitter (); Renderer = neuer DisplayObjectRenderer (this); renderer.addEmitter (Sender); addEventListener (Event.ENTER_FRAME, mainLoop);  private Funktion mainLoop (e: Event): void emitter.step (); 

Die Emitterklasse ist unten dargestellt. Es schiebt im Wesentlichen Kreisteilchen aus und die Teilchen werden durch ein gleichmäßiges Schwerefeld beeinflusst, das nach unten zeigt.

 package import idv.cjcat.stardust.common.actions.Age; idv.cjcat.stardust.common.actions.deathLife importieren; import idv.cjcat.stardust.common.actions.ScaleCurve; import idv.cjcat.stardust.common.clocks.SteadyClock; import idv.cjcat.stardust.common.initializers.Life; idv.cjcat.stardust.common.initializers.Scale importieren; import idv.cjcat.stardust.common.math.UniformRandom; idv.cjcat.stardust.twoD.actions.Gravity importieren; import idv.cjcat.stardust.twoD.actions.Move; import idv.cjcat.stardust.twoD.emitters.Emitter2D; import idv.cjcat.stardust.twoD.fields.Field; import idv.cjcat.stardust.twoD.fields.UniformField; import idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; import idv.cjcat.stardust.twoD.initializers.Position; import idv.cjcat.stardust.twoD.initializers.Velocity; import idv.cjcat.stardust.twoD.zones.LazySectorZone; import idv.cjcat.stardust.twoD.zones.SinglePoint; public class CircleEmitter erweitert Emitter2D public function CircleEmitter () super (new SteadyClock (1)); // Initialisierer addInitializer (new DisplayObjectClass (Circle)); addInitializer (neues Leben (neues UniformRandom (60, 10))); addInitializer (neue Position (neuer SinglePoint (320, 100)))); addInitializer (neue Geschwindigkeit (neue LazySectorZone (8, 4))); addInitializer (new Scale (neues UniformRandom (1, 0.4))); addInitializer (neuer CollisionRadius (10)); // Aktionen addAction (neues Zeitalter ()); addAction (neues DeathLife ()); addAction (new Move ()); addAction (neue ScaleCurve (0, 10)); // Schwerkraft var Feld: Feld = neues UniformField (0, 0.5); Var Schwerkraft: Schwerkraft = neue Schwerkraft (); gravity.addField (Feld); addAction (Schwerkraft); 

Jetzt haben Sie einen Effekt erzeugt, bei dem Partikel aus der Bühnenmitte herausgeschossen und durch die Schwerkraft nach unten gezogen werden. So sieht es aus:

Meilenstein Online ansehen

Schritt 3: Bodeneffekt Fügen Sie den Deflector hinzu

Fügen Sie den folgenden Code im Emitterkonstruktor hinzu. Es erzeugt einen Leitungsdeflektor und fügt ihn dem hinzu Deflektor Aktion und fügt die Aktion dann dem Emitter hinzu, wodurch der Ablenkeffekt aktiviert wird. Die ersten beiden Konstruktorparameter für die LineDeflector Klasse ist die Koordinate eines Punktes auf der Linie, und die letzten beiden Parameter sind die X- und Y-Komponenten des Normalenvektors der Linie. Das Deflector.bounce Die Eigenschaft bestimmt die "Bounciness" der Linie, wobei 1 den vollständigen Rebound verursacht und "0" überhaupt keinen Rebound.

 // Erstellen eines Linienablenkers, der durch den Punkt (320, 320) und den normalen (0, -1) var-Abweiser verläuft: Ablenker = new LineDeflector (320, 320, 0, -1); Deflektorsprung = 0,6; var Ablenkung: Ablenkung = neue Ablenkung (); Deflect.addDeflector (Deflektor); addAction (Ablenkung);

Sie können auch eine visuelle Darstellung der Linie auf der Bühne zeichnen, um ein besseres Aussehen zu erzielen.

In Ordnung, wir sind mit diesem Beispiel fertig. Lassen Sie uns nun einen Blick auf unser Endergebnis werfen.

Meilenstein Online ansehen

Begrenzungsbox

In diesem Beispiel verwenden wir die BoundingBox Deflektor, um Partikel in einem rechteckigen Bereich einzuschränken.


Schritt 1: Begrenzungsbox Die Emitter-Klasse

Die Dokumentenklasse bleibt dieselbe wie im vorherigen Beispiel, aber wir werden die Emitterklasse ändern. Dies ist die Basisemitterklasse dieses Beispiels. Verglichen mit der Emitter-Klasse im vorherigen Beispiel wurde die SteadClock wird in a geändert ImpulseClock Um sofort 20 Partikel zu erzeugen, wird die Positionszone von einem einzelnen Punkt in eine rechteckige Zone geändert, die der Bühnengröße entspricht Geschwindigkeit Initialisierung wird etwas verlangsamt, die Leben Der Initialisierer wird entfernt, weil die Partikel dauerhaft auf der Bühne bleiben sollen Alter und Tod Leben Aktionen sind wiederum nicht erforderlich und werden entfernt, und die ScaleCurve wird auch entfernt. Einige Importe werden auch hinzugefügt und entfernt. Sie können den Code unten einfach kopieren.

 package import idv.cjcat.stardust.common.clocks.ImpulseClock; import idv.cjcat.stardust.common.initializers.CollisionRadius; idv.cjcat.stardust.common.initializers.Scale importieren; import idv.cjcat.stardust.common.math.UniformRandom; import idv.cjcat.stardust.twoD.actions.Deflect; import idv.cjcat.stardust.twoD.actions.Move; import idv.cjcat.stardust.twoD.deflectors.BoundingBox; import idv.cjcat.stardust.twoD.deflectors.Deflector; import idv.cjcat.stardust.twoD.emitters.Emitter2D; import idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; import idv.cjcat.stardust.twoD.initializers.Position; import idv.cjcat.stardust.twoD.initializers.Velocity; import idv.cjcat.stardust.twoD.zones.LazySectorZone; import idv.cjcat.stardust.twoD.zones.RectZone; import idv.cjcat.stardust.twoD.zones.SinglePoint; public class CircleEmitter erweitert Emitter2D private var impulseClock: ImpulseClock; öffentliche Funktion CircleEmitter () super (impulseClock = new ImpulseClock (20)); impulseClock.impulse (); // Initialisierer addInitializer (new DisplayObjectClass (Circle)); addInitializer (neue Position (neue RectZone (0, 0, 640, 400))); addInitializer (neue Geschwindigkeit (neue LazySectorZone (3, 2))); addInitializer (new Scale (neues UniformRandom (1, 0.4))); addInitializer (neuer CollisionRadius (10)); // Aktionen addAction (new Move ()); 

Schritt 2: Begrenzungsrahmen Fügen Sie den Ablenker hinzu

Ähnlich wie im vorherigen Beispiel fügen wir nun den folgenden Code im Emitterkonstruktor hinzu, um den Ablenken Aktion, nur dass wir diesmal die BoundingBox Deflektor, um Partikel in einem rechteckigen Bereich einzuschränken, der der Bühnengröße entspricht.

 // Deflektor var Deflektor: Deflector = new BoundingBox (0, 0, 640, 400); var Ablenkung: Ablenkung = neue Ablenkung (); Deflect.addDeflector (Deflektor); addAction (Ablenkung);

Schritt 3: Bounding Box Testen Sie den Film

Das ist es. Es wird nicht viel geändert, und jetzt haben wir Partikel in einem Begrenzungsrahmen eingeschränkt. Testen Sie den Film und Sie werden das Ergebnis sehen.

Meilenstein Online ansehen

Kundenspezifische Deflektoren

Jetzt werden wir selbst maßgeschneiderte Deflektoren erstellen. Lass uns zuerst das verstehen Deflektor Klasse, die wir erweitern wollen.

Das Deflektor Klasse ist die Basisklasse für alle Deflektoren. Um benutzerdefinierte Deflektoren zu erstellen, sollten Sie diese Klasse erweitern und die Option überschreiben berechnungMotionData4D () Methode, und dann zurückgeben a MotionData4D Objekt, das die 4D-Vektorausgabe des Deflektors darstellt. Die Eingabe zu Ihrer Verfügung, genau wie die Feld Klasse, ist in der Particle2D Objekt als Parameter an die Methode übergeben. Sie können dies verwenden Particle2D Objekt, um Ihre Ausgabe zu bestimmen. Übrigens, wenn diese Methode a zurückgibt Null Wert, der Ablenken Eine Aktion würde davon ausgehen, dass Sie die Bewegung des aktuellen Partikels nicht ändern, das Partikel ignorieren und dann das nächste Partikel bearbeiten möchten.

Zum Beispiel würde der nachfolgende Deflektor den Geschwindigkeitsvektor jedes Partikels um einen Grad im Uhrzeigersinn drehen.

 package import idv.cjcat.stardust.twoD.geom.Vec2D; import idv.cjcat.stardust.twoD.particles.Particle2D; import idv.cjcat.stardust.twoD.deflectors.Deflector; import idv.cjcat.stardust.twoD.geom.MotionData4D; public class Rotator erweitert Deflector überschreibe die geschützte Funktion. Geschwindigkeit.RotateThis (1); neue MotionData4D zurückgeben (Partikel.x, Partikel.y, Geschwindigkeit.x, Geschwindigkeit.y); 

Tube Deflector-Effekt

In diesem Beispiel werden wir das erweitern Deflektor Klasse und erstellen Sie unseren eigenen Deflektor, der ein Rohr simuliert, bei dem es sich im Wesentlichen um zwei Leitungsdeflektoren handelt, die einen rohrförmigen Freiraum einschließen.


Schritt 1: Tube Deflector Effect Die Emitter-Klasse

Kopieren Sie das Flash-Dokument zusammen mit dem Kreis Symbol und das Dokument aus dem ersten Beispiel. Hier erstellen wir eine weitere Emitterklasse, die immer noch ihren Namen hat CircleEmitter. Diesmal emittiert der Emitter Partikel aus der Bühnenmitte, und es wird kein Schwerkraftfeld angelegt.

 package import idv.cjcat.stardust.common.actions.Age; idv.cjcat.stardust.common.actions.deathLife importieren; import idv.cjcat.stardust.common.actions.ScaleCurve; import idv.cjcat.stardust.common.clocks.SteadyClock; import idv.cjcat.stardust.common.initializers.CollisionRadius; import idv.cjcat.stardust.common.initializers.Life; idv.cjcat.stardust.common.initializers.Scale importieren; import idv.cjcat.stardust.common.math.UniformRandom; import idv.cjcat.stardust.twoD.actions.Deflect; import idv.cjcat.stardust.twoD.actions.Move; import idv.cjcat.stardust.twoD.deflectors.Deflector; import idv.cjcat.stardust.twoD.emitters.Emitter2D; import idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; import idv.cjcat.stardust.twoD.initializers.Position; import idv.cjcat.stardust.twoD.initializers.Velocity; import idv.cjcat.stardust.twoD.zones.LazySectorZone; import idv.cjcat.stardust.twoD.zones.SinglePoint; public class CircleEmitter erweitert Emitter2D public function CircleEmitter () super (new SteadyClock (1)); // Initialisierer addInitializer (new DisplayObjectClass (Circle)); addInitializer (neues Leben (neues UniformRandom (60, 10))); addInitializer (neue Position (neuer SinglePoint (320, 200)))); // stage center addInitializer (neue Geschwindigkeit (neue LazySectorZone (8, 4))); addInitializer (new Scale (neues UniformRandom (1, 0.4))); addInitializer (neuer CollisionRadius (10)); // Aktionen addAction (neues Zeitalter ()); addAction (neues DeathLife ()); addAction (new Move ()); addAction (neue ScaleCurve (0, 10)); 

Schritt 2: Tube Deflector-Effekt Der Tube Deflector

Jetzt werden wir unsere Rohrleitungsklasse erstellen. Details werden in Kommentaren erläutert.

 package import idv.cjcat.stardust.twoD.particles.Particle2D; import idv.cjcat.stardust.twoD.deflectors.Deflector; import idv.cjcat.stardust.twoD.geom.MotionData4D; öffentliche Klasse TubeDeflector erweitert Deflector private var y1: Number; private var y2: Anzahl; public function TubeDeflector (y1: Number, y2: Number) // y2 sollte größer als y2 sein, wenn (y1> y2) // Swap y1 und y2, wenn y1 größer ist var temp: Number = y1; y1 = y2; y2 = Temp;  this.y1 = y1; this.y2 = y2;  Überschreiben der geschützten Funktion berechneMotionData4D (Partikel: Particle2D): MotionData4D // Ausgabekomponenten, die auf die ursprünglichen Bewegungsdaten des Partikels initialisiert wurden var x: Number = Partikel.x; var y: Anzahl = Teilchen.y; var vx: Anzahl = Partikel.vx; var vy: Anzahl = Partikel.vy; // Berechne den tatsächlichen Kollisionsradius var radius: Number = particle.collisionRadius * particle.scale; // Flag, ob der Deflektor wirksam wird var abgelenkt: Boolean = false; if (partikel.y < (y1 + radius))  //particle y-coordinate is less than lower limit //set proper new y-coordinate y = y1 + radius; //set flag deflected = true;  else if (particle.y > (y2 - Radius)) // Die Partikel-Y-Koordinate ist größer als die obere Grenze. // Richtige neue Y-Koordinate einstellen. y = Y2 - Radius; // gesetztes Flag abgelenkt = true;  if (abgelenkt) return new MotionData4D (x, y, vx, vy);  else // das Teilchen ignorieren und seine Bewegungsdaten nicht aktualisieren, Rückgabe null; 

Schritt 3: Tube Deflector Effect Fügen Sie den Deflector hinzu

Sie sollten jetzt wissen, was wir als nächstes tun werden. Das ist richtig, wir werden den Deflektor zu einem hinzufügen Ablenken Aktion und fügen Sie die Aktion dann dem Emitter hinzu. Fügen Sie dem Emitterkonstruktor den folgenden Code hinzu.

 // Erzeuge einen Rohrleitungsdeflektor var Deflector: Deflector = new TubeDeflector (100, 300); var Ablenkung: Ablenkung = neue Ablenkung (); Deflect.addDeflector (Deflektor); addAction (Ablenkung);

Schritt 4: Tube Deflector Effect Testen Sie den Film

Sie können den Film jetzt testen. Sie können den Deflektor auch auf der Bühne visuell darstellen, um ein besseres Aussehen zu erzielen.

Meilenstein Online ansehen

Fazit

Dies ist das Ende des gesamten Tutorials. Im ersten Teil haben Sie etwas über Gravitationsfelder gelernt. Im zweiten Teil haben Sie das Konzept der Deflektoren und die tatsächliche Verwendung des Deflektors kennen gelernt Ablenken Aktion. Sie haben auch gelernt, das zu erweitern Deflektor Klasse, um benutzerdefinierte Deflektoren zu erstellen. Jetzt können Sie in Stardust eine erweiterte Partikelbewegungsmanipulation durchführen.

Vielen Dank fürs Lesen!