Questa è la seconda parte di questo tutorial. Ti mostrerò come manipolare il movimento delle particelle con i deflettori.
È richiesta una conoscenza pregressa delle basi del movimento e dei campi vettoriali. Consiglio vivamente di completare la prima parte di questo tutorial prima di proseguire.
Dai un'occhiata al risultato finale su cui lavoreremo. È un esempio di effetto pavimento, con particelle che rimbalzano dal pavimento.
Praticamente come i campi gravitazionali, un deflettore prende i dati di movimento attuali di una particella come input. Successivamente, il deflettore sovrascrive il movimento della particella con la sua uscita, solo che l'uscita ora contiene dati di velocità oltre ai dati di posizione. Quindi, nello spazio 2D, l'uscita di un deflettore è un vettore 4D; le prime due componenti del vettore 4D rappresentano il componente x ed y del vettore di posizione (denotato X e y), rispettivamente, e le ultime due componenti rappresentano la componente xey del vettore di velocità (denotata) vx e vy).
Ricorda il Campo
classe e il Gravità
azione dalla prima parte di questo tutorial? Bene, la procedura è simile. Tu crei Deflettore
oggetti che manipolano i movimenti delle particelle e quindi li aggiungono al Deviare
azione, proprio come si aggiungerebbe Campo
oggetti al Gravità
azione. Ora diamo un'occhiata ad un rapido esempio.
In questo esempio, useremo il LineDeflector
classe per creare un effetto di rimbalzo delle particelle. Un deflettore di linea simula essenzialmente una linea infinitamente lunga nello spazio 2D, con un lato che è spazio aperto e l'altro lato solido; le particelle possono essere solo nello spazio aperto e non sono permesse nello spazio solido. Quando le particelle provengono dal lato dello spazio aperto, colpendo la linea, si riprenderanno. Il Particle.collisionRadius
la proprietà, che rappresenta il raggio di una particella, viene presa in considerazione.
Il deflettore di linea utilizza un vettore normale e un punto attraversato dalla linea nello spazio 2D per determinare la linea. Ecco un'illustrazione per darti un'idea migliore.
Crea un nuovo documento Flash, disegna un cerchio di raggio di 10, quindi convertilo in un simbolo, esportato per ActionScript con un nome di classe Cerchio
.
Creare un file AS per la classe del documento. La classe crea un emettitore e un renderer. Se hai bisogno di un aggiornamento sull'uso di base di Stardust, puoi consultare questo tutorial.
pacchetto 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 estende Sprite emettitore private var: Emitter; renderer var privato: Renderer; funzione pubblica FloorEffect () emitter = new CircleEmitter (); renderer = new DisplayObjectRenderer (this); renderer.addEmitter (emettitore); addEventListener (Event.ENTER_FRAME, mainLoop); private function mainLoop (e: Event): void emitter.step ();
La classe emettitore è mostrata di seguito. Fondamentalmente spara particelle circolari e le particelle sono interessate da un campo di gravità uniforme, rivolto verso il basso.
package import idv.cjcat.stardust.common.actions.Age; import idv.cjcat.stardust.common.actions.DeathLife; import idv.cjcat.stardust.common.actions.ScaleCurve; import idv.cjcat.stardust.common.clocks.SteadyClock; import idv.cjcat.stardust.common.initializers.Life; import idv.cjcat.stardust.common.initializers.Scale; import idv.cjcat.stardust.common.math.UniformRandom; import idv.cjcat.stardust.twoD.actions.Gravity; 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 estende Emitter2D public function CircleEmitter () super (new SteadyClock (1)); // inizializzatori addInitializer (new DisplayObjectClass (Circle)); addInitializer (new Life (new UniformRandom (60, 10))); addInitializer (new Position (new SinglePoint (320, 100))); addInitializer (nuovo Velocity (nuovo LazySectorZone (8, 4))); addInitializer (new Scale (new UniformRandom (1, 0.4))); addInitializer (new CollisionRadius (10)); // azioni addAction (new Age ()); addAction (new DeathLife ()); addAction (new Move ()); addAction (new ScaleCurve (0, 10)); // campo gravity var: Field = new UniformField (0, 0.5); gravità variabile: gravità = nuova gravità (); gravity.addField (campo); addAction (gravità);
Ora hai creato un effetto con le particelle che escono dal centro del palcoscenico, che vengono abbassate per gravità. Questo è quello che sembra:
Pietra miliare Visualizza online Aggiungi il codice di distribuzione nel costruttore di emitter. Crea un deflettore di linea, lo aggiunge al Deflettore
azione, quindi aggiunge l'azione all'emettitore, attivando così l'effetto deflettore. I primi due parametri parametrici per il LineDeflector
class è la coordinata di un punto sulla linea e gli ultimi due parametri sono le componenti xey del vettore normale della linea. Il Deflector.bounce
la proprietà determina il "rimbalzo" della linea, 1 provoca un rimbalzo completo e 0 non significa alcun rimbalzo.
// crea un deflettore di linea che passa attraverso il punto (320, 320) e il deflettore normale (0, -1) var: Deflector = new LineDeflector (320, 320, 0, -1); deflector.bounce = 0.6; var defect: Deflect = new Deflect (); deflect.addDeflector (deflettore); addAction (deflect);
Puoi anche disegnare una rappresentazione visiva della linea sul palco per avere un aspetto migliore.
Bene, abbiamo finito con questo esempio. Ora diamo un'occhiata al nostro risultato finale.
Pietra miliare Visualizza online In questo esempio, useremo il Rettangolo di selezione
deflettore per vincolare le particelle all'interno di un'area rettangolare.
La classe del documento rimane la stessa dell'esempio precedente, ma stiamo per cambiare la classe dell'emettitore. Questa è la classe dell'emettitore di base di questo esempio. Rispetto alla classe emitter nell'esempio precedente, il SteadClock
è cambiato in a ImpulseClock
per creare istantaneamente 20 particelle all'inizio, la zona di posizione viene cambiata da un singolo punto a una zona rettangolare che corrisponde alla dimensione dello stage, il Velocità
l'inizializzatore è rallentato un po ', il Vita
l'inizializzatore è rimosso perché vogliamo che le particelle rimangano permanentemente sul palco, il Età
e DeathLife
le azioni a loro volta non sono richieste e rimosse, e il ScaleCurve
è anche rimosso. Alcune importazioni sono anche aggiunte e rimosse; puoi semplicemente copiare il codice qui sotto per comodità.
package import idv.cjcat.stardust.common.clocks.ImpulseClock; import idv.cjcat.stardust.common.initializers.CollisionRadius; import idv.cjcat.stardust.common.initializers.Scale; 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 estende Emitter2D private var pulsseClock: ImpulseClock; funzione pubblica CircleEmitter () super (impulsseClock = new ImpulseClock (20)); impulseClock.impulse (); // inizializzatori addInitializer (new DisplayObjectClass (Circle)); addInitializer (new Position (new RectZone (0, 0, 640, 400))); addInitializer (nuovo Velocity (nuovo LazySectorZone (3, 2))); addInitializer (new Scale (new UniformRandom (1, 0.4))); addInitializer (new CollisionRadius (10)); // azioni addAction (new Move ());
Praticamente come nell'esempio precedente, ora aggiungiamo il seguente codice nel costruttore di emitter per usare il Deviare
azione, solo che questa volta usiamo il Rettangolo di selezione
deflettore per vincolare le particelle all'interno di una regione rettangolare che corrisponde alle dimensioni dello stage.
// deflettore var deflector: Deflector = new BoundingBox (0, 0, 640, 400); var defect: Deflect = new Deflect (); deflect.addDeflector (deflettore); addAction (deflect);
Questo è tutto. Non è cambiato molto, e ora abbiamo particelle vincolate in un riquadro di delimitazione. Prova il film e vedrai il risultato.
Pietra miliare Visualizza online Ora, creeremo dei deflettori personalizzati da soli. Iniziamo a capire il Deflettore
classe che stiamo per estendere.
Il Deflettore
la classe è la classe base per tutti i deflettori. Per creare deflettori personalizzati, devi estendere questa classe e sovrascrivere il calculateMotionData4D ()
metodo, quindi restituire a MotionData4D
oggetto che rappresenta l'uscita vettoriale 4D del deflettore. L'input a tua disposizione, proprio come il Campo
classe, è incluso nel Particle2D
oggetto passato nel metodo come parametro. Puoi usare questo Particle2D
oggetto per determinare l'output. A proposito, se questo metodo restituisce a nullo
valore, il Deviare
l'azione presuppone che tu non voglia cambiare il movimento della particella corrente, ignorare la particella e poi passare all'elaborazione della particella successiva.
Ad esempio, il seguente deflettore ruoterebbe il vettore di velocità di ogni particella di un grado in senso orario.
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 estende Deflector override protected function calculateMotionData4D (particle: Particle2D): MotionData4D var velocity: Vec2D = new Vec2D (particle.vx, particle.vy); velocity.rotateThis (1); restituisce nuovo MotionData4D (particle.x, particle.y, velocity.x, velocity.y);
In questo esempio, estenderemo il Deflettore
classe e creare il nostro deflettore, simulando un tubo, che è essenzialmente un deflettore a due linee che racchiude uno spazio libero a forma di tubo.
Copia il documento Flash, insieme a Cerchio
simbolo e il documento del primo esempio. Qui creeremo un'altra classe di emettitore, ancora chiamata CircleEmitter
. Questa volta l'emettitore emette particelle dal centro dello stage e non viene applicato il campo di gravità.
package import idv.cjcat.stardust.common.actions.Age; import idv.cjcat.stardust.common.actions.DeathLife; 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; import idv.cjcat.stardust.common.initializers.Scale; 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 estende Emitter2D public function CircleEmitter () super (new SteadyClock (1)); // inizializzatori addInitializer (new DisplayObjectClass (Circle)); addInitializer (new Life (new UniformRandom (60, 10))); addInitializer (new Position (new SinglePoint (320, 200))); // stage center addInitializer (nuovo Velocity (nuovo LazySectorZone (8, 4))); addInitializer (new Scale (new UniformRandom (1, 0.4))); addInitializer (new CollisionRadius (10)); // azioni addAction (new Age ()); addAction (new DeathLife ()); addAction (new Move ()); addAction (new ScaleCurve (0, 10));
Ora creeremo la nostra classe di deflettori tubolari. I dettagli sono spiegati nei commenti.
package import idv.cjcat.stardust.twoD.particles.Particle2D; import idv.cjcat.stardust.twoD.deflectors.Deflector; import idv.cjcat.stardust.twoD.geom.MotionData4D; public class TubeDeflector estende Deflector private var y1: Number; private var y2: Number; public function TubeDeflector (y1: Number, y2: Number) // y2 deve essere maggiore di y2 if (y1> y2) // swap y1 e y2 se y1 è maggiore var temp: Number = y1; y1 = y2; y2 = temp; this.y1 = y1; this.y2 = y2; override protected function calculateMotionData4D (particle: Particle2D): MotionData4D // componenti di output, inizializzati per i dati di movimento originali della particella var x: Number = particle.x; var y: Number = particle.y; var vx: Number = particle.vx; var vy: Number = particle.vy; // calucula raggio di collsione effettivo var raggio: Number = particle.collisionRadius * particle.scale; // indica se il deflettore ha effetto var defected: Boolean = false; se (particle.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 - raggio)) // la coordinata y della particella è maggiore del limite superiore // imposta la nuova nuova coordinata y y = y2 - raggio; // imposta flag defected = true; if (defected) return new MotionData4D (x, y, vx, vy); else // ignora la particella e non aggiorna i suoi dati di movimento return null;
Dovresti sapere cosa faremo ora molto bene. Esatto, aggiungeremo il deflettore a a Deviare
azione e quindi aggiungere l'azione all'emettitore. Aggiungi il seguente codice nel costruttore di emitter.
// crea un deflettore valvolare var deflettore: Deflector = new TubeDeflector (100, 300); var defect: Deflect = new Deflect (); deflect.addDeflector (deflettore); addAction (deflect);
Ora puoi testare il film. Ancora una volta, puoi anche disegnare una rappresentazione visiva del deflettore sul palco per un aspetto migliore.
Pietra miliare Visualizza online Questa è la fine dell'intero tutorial. Nella prima parte hai imparato a conoscere i campi gravitazionali. Nella seconda parte, hai imparato il concetto di deflettori e l'uso effettivo di Deviare
azione. Inoltre, hai imparato come estendere il Deflettore
classe per creare deflettori personalizzati. Ora sei in grado di eseguire la manipolazione avanzata del movimento delle particelle in Stardust.
Grazie mille per la lettura!