Manipolazione del movimento delle particelle con il motore a particelle di polvere di terracotta - Parte 2

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.


Anteprima del risultato finale

Dai un'occhiata al risultato finale su cui lavoreremo. È un esempio di effetto pavimento, con particelle che rimbalzano dal pavimento.


deflettori

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).


Come usare i deflettori

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.


Effetto pavimento

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.


Passaggio 1: simbolo cerchio effetto pavimento

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.


Passaggio 2: Effetto piano La classe documento

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

Passaggio 3: Effetto pavimento Aggiungere il deflettore

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

Rettangolo di selezione

In questo esempio, useremo il Rettangolo di selezione deflettore per vincolare le particelle all'interno di un'area rettangolare.


Step 1: Bounding Box La classe Emitter

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 ()); 

Step 2: Bounding Box Aggiungi il Deflector

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);

Step 3: Bounding Box Prova il film

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

Deflettori personalizzati

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); 

Tube Deflector Effect

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.


Step 1: Tube Deflector Effect The Emitter Class

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)); 

Step 2: Tube Deflector Effect The Tube Deflector

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; 

Step 3: Tube Deflector Effect Aggiungi il Deflector

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);

Step 4: Tube Deflector Effect Prova il film

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

Conclusione

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!