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.
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.
Ä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).
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.
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.
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
.
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 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 In diesem Beispiel verwenden wir die BoundingBox
Deflektor, um Partikel in einem rechteckigen Bereich einzuschränken.
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 ());
Ä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);
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 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);
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.
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));
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;
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);
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 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!