Het manipuleren van deeltjesbeweging met Stineust deeltjesmotor - deel 2

Dit is het tweede deel van deze tutorial. Ik ga je laten zien hoe je deeltjesbeweging manipuleert met deflectors.

Voorkennis van bewegingsbeginselen en vectorvelden is vereist. Ik beveel ten zeerste aan dat je het eerste deel van deze tutorial voltooit voordat je verdergaat.


Eindresultaat voorbeeld

Bekijk het eindresultaat waar we naartoe zullen werken. Het is een voorbeeld van een vloereffect, waarbij deeltjes van de vloer botsen.


deflectors

Net zoals zwaartekrachtvelden neemt een deflector de actuele bewegingsgegevens van een deeltje als input. Nadien overschrijft de deflector de beweging van het deeltje met zijn uitvoer, alleen dat de uitvoer nu naast de positiegegevens ook snelheidsgegevens bevat. In een 2D-ruimte is de uitvoer van een deflector dus een 4D-vector; de eerste twee componenten van de 4D-vector vertegenwoordigen de x- en y-component van de positievector (aangeduid met X en Y), respectievelijk, en de laatste twee componenten vertegenwoordigen de x- en y-component van de snelheidsvector (aangegeven met vx en vy).


Hoe Deflectors te gebruiken

Herinner de Veld klasse en de Zwaartekracht actie vanaf het eerste deel van deze tutorial? Nou, de procedure is vergelijkbaar. Jij maakt deflector objecten die deeltjesbewegingen manipuleren en vervolgens toevoegen aan de buigen actie, net zoals u zou toevoegen Veld objecten voor de Zwaartekracht actie. Laten we nu een snel voorbeeld bekijken.


Floor Effect

In dit voorbeeld gaan we de gebruiken LineDeflector class om een ​​particle-bouncing-off-floor effect te creëren. Een lijndeflector simuleert in essentie een oneindig lange lijn in 2D-ruimte, waarbij één zijde open ruimte is, en de andere kant vast; deeltjes mogen alleen in de open ruimte staan ​​en mogen niet in de vaste ruimte. Wanneer deeltjes uit de open ruimte komen en de lijn raken, stuiteren ze terug. De Particle.collisionRadius eigenschap, die de straal van een deeltje weergeeft, wordt in aanmerking genomen.

De lijndeflector gebruikt een normale vector en een punt dat de lijn passeert in de 2D-ruimte om de lijn te bepalen. Hier is een illustratie om u een beter idee te geven.


Stap 1: Floor Effect Circle-symbool

Maak een nieuw Flash-document, teken een straal met een straal van 10 en converteer het naar een symbool, geëxporteerd naar ActionScript met een klassenaam Cirkel.


Stap 2: Floor Effect De documentklasse

Maak een AS-bestand voor de documentklasse. De klasse maakt een emitter en een renderer. Als je een herhaling van het standaardgebruik van Stardust nodig hebt, kun je deze tutorial bekijken.

 pakket 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; openbare klasse FloorEffect breidt Sprite uit private var emitter: Emitter; private var renderer: Renderer; public function FloorEffect () emitter = new CircleEmitter (); renderer = nieuw DisplayObjectRenderer (this); renderer.addEmitter (emitter); addEventListener (Event.ENTER_FRAME, mainLoop);  private function mainLoop (e: Event): void emitter.step (); 

De emitterklasse wordt hieronder weergegeven. Het schiet in feite cirkeldeeltjes uit en de deeltjes worden beïnvloed door een uniform zwaartekrachtveld, dat naar beneden wijst.

 pakket 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 breidt Emitter2D uit public function CircleEmitter () super (new SteadyClock (1)); // initializers addInitializer (nieuwe DisplayObjectClass (Circle)); addInitializer (nieuw leven (nieuwe UniformRandom (60, 10))); addInitializer (nieuwe positie (nieuwe singlePoint (320, 100))); addInitializer (nieuwe Velocity (nieuwe LazySectorZone (8, 4))); addInitializer (nieuwe schaal (nieuwe UniformRandom (1, 0.4))); addInitializer (nieuwe CollisionRadius (10)); // actions addAction (new Age ()); addAction (nieuwe DeathLife ()); addAction (nieuwe verplaatsing ()); addAction (nieuwe ScaleCurve (0, 10)); // zwaartekrachtvareveld: veld = nieuw UniformField (0, 0,5); var zwaartekracht: zwaartekracht = nieuwe zwaartekracht (); gravity.addField (veld); Addaction (zwaartekracht); 

Je hebt nu een effect gecreëerd met deeltjes die vanuit het midden van het podium naar buiten schieten en door de zwaartekracht naar beneden worden getrokken. Dit is hoe het eruit ziet:

Mijlpaal Bekijk het online

Stap 3: Floor Effect Voeg de deflector toe

Voeg de volgende code toe aan de emitterconstructor. Het creëert een lijndeflector, voegt het toe aan de deflector actie en voegt vervolgens de actie aan de emitter toe, waardoor het deflectoreffect wordt geactiveerd. De eerste twee constructorparameters voor de LineDeflector klasse is de coördinaat van een punt op de lijn en de laatste twee parameters zijn de x- en y-componenten van de normale vector van de lijn. De Deflector.bounce property bepaalt de "bounciness" van de regel, 1 veroorzaakt volledige rebound en 0 betekent helemaal geen rebound.

 // maak een lijndeflector door punt (320, 320) en normaal (0, -1) var deflector: deflector = new LineDeflector (320, 320, 0, -1); deflector.bounce = 0.6; var deflect: Deflect = new Deflect (); deflect.addDeflector (deflector); Addaction (Deflect);

Je kunt ook een visuele weergave van de lijn op het podium tekenen om er beter uit te zien.

Oke, we zijn klaar met dit voorbeeld. Laten we nu eens kijken naar onze uiteindelijke uitkomst.

Mijlpaal Bekijk het online

Begrenzende Box

In dit voorbeeld gaan we de gebruiken BoundingBox deflector om deeltjes in een rechthoekig gebied te beperken.


Stap 1: Begrenzingsbox De emitterklasse

De documentklasse blijft hetzelfde als in het vorige voorbeeld, maar we gaan de emmerklasse wijzigen. Dit is de basis emitterklasse van dit voorbeeld. Vergeleken met de emitterklasse in het vorige voorbeeld, is de SteadClock is gewijzigd in a ImpulseClock om meteen 20 deeltjes aan het begin te maken, wordt de positiezone veranderd van een enkel punt in een rechthoekige zone die overeenkomt met de stage-afmeting, de Snelheid initializer is een beetje vertraagd, de Leven initializer is verwijderd omdat we willen dat deeltjes permanent op het podium blijven, de Leeftijd en Dood leven acties zijn op hun beurt niet vereist en verwijderd, en de ScaleCurve is ook verwijderd. Sommige invoer is ook toegevoegd en verwijderd; u kunt de code hieronder eenvoudig kopiëren voor uw gemak.

 pakket 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 breidt Emitter2D uit private var impulseClock: ImpulseClock; public function CircleEmitter () super (impulseClock = new ImpulseClock (20)); impulseClock.impulse (); // initializers addInitializer (nieuwe DisplayObjectClass (Circle)); addInitializer (nieuwe positie (nieuwe RectZone (0, 0, 640, 400))); addInitializer (nieuwe Velocity (nieuwe LazySectorZone (3, 2))); addInitializer (nieuwe schaal (nieuwe UniformRandom (1, 0.4))); addInitializer (nieuwe CollisionRadius (10)); // acties addAction (nieuwe verplaatsing ()); 

Stap 2: Begrenzende box Voeg de deflector toe

Ongeveer zoals het vorige voorbeeld, voegen we nu de volgende code toe aan de emitterconstructor om de buigen actie, alleen dat we deze keer de BoundingBox deflector om deeltjes te beperken binnen een rechthoekig gebied dat overeenkomt met de grootte van de stage.

 // deflector var deflector: deflector = nieuwe BoundingBox (0, 0, 640, 400); var deflect: Deflect = new Deflect (); deflect.addDeflector (deflector); Addaction (Deflect);

Stap 3: Begrenzende box Test de film

Dat is het. Er is niet veel veranderd en nu hebben we ingesloten deeltjes in een begrenzingsvak. Test de film en u zult het resultaat zien.

Mijlpaal Bekijk het online

Aangepaste deflectors

Nu gaan we zelf aangepaste deflectors maken. Laten we eerst het begrijpen deflector klas die we gaan uitbreiden.

De deflector klasse is de basisklasse voor alle deflectors. Om aangepaste deflectors te maken, moet u deze klasse uitbreiden en de calculateMotionData4D () methode en geef a MotionData4D object dat de 4D vectoruitvoer van de deflector voorstelt. De input tot uw beschikking, net als de Veld klasse, is opgenomen in de Particle2D object als parameter doorgegeven aan de methode. Je mag dit gebruiken Particle2D object om uw uitvoer te bepalen. By the way, als deze methode een a retourneert nul waarde, de buigen actie zou veronderstellen dat je de beweging van het huidige deeltje niet wilt veranderen, het deeltje wilt negeren en dan door wilt gaan met het verwerken van het volgende deeltje.

De volgende deflector zou bijvoorbeeld de snelheidsvector van elke deeltje met één graad kloksgewijs roteren.

 pakket 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 breidt Deflector uit override beschermde functie calculationMotionData4D (particle: Particle2D): MotionData4D var velocity: Vec2D = new Vec2D (particle.vx, particle.vy); velocity.rotateThis (1); retourneer nieuwe MotionData4D (particle.x, particle.y, velocity.x, velocity.y); 

Buisdeflectoreffect

In dit voorbeeld gaan we het deflector klasse en maak onze eigen deflector, simuleren een buis, dat is in wezen twee lijn deflectors sandwich een buisvormige vrije ruimte.


Stap 1: Tube Deflector Effect De emitterklasse

Kopieer het Flash-document, samen met de Cirkel symbool en het document uit het eerste voorbeeld. Hier gaan we een andere emmerklasse maken, nog steeds genoemd CircleEmitter. Deze keer zendt de emitter deeltjes uit het midden van het podium en wordt er geen zwaartekrachtveld toegepast.

 pakket 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 breidt Emitter2D uit public function CircleEmitter () super (new SteadyClock (1)); // initializers addInitializer (nieuwe DisplayObjectClass (Circle)); addInitializer (nieuw leven (nieuwe UniformRandom (60, 10))); addInitializer (nieuwe positie (nieuwe singlePoint (320, 200))); // fasecentrum addInitializer (nieuwe Velocity (nieuwe LazySectorZone (8, 4))); addInitializer (nieuwe schaal (nieuwe UniformRandom (1, 0.4))); addInitializer (nieuwe CollisionRadius (10)); // actions addAction (new Age ()); addAction (nieuwe DeathLife ()); addAction (nieuwe verplaatsing ()); addAction (nieuwe ScaleCurve (0, 10)); 

Stap 2: Buisdeflectoreffect De buisdeflector

Nu gaan we onze buisdeflectorklasse maken. Details worden in opmerkingen uitgelegd.

 pakket import idv.cjcat.stardust.twoD.particles.Particle2D; import idv.cjcat.stardust.twoD.deflectors.Deflector; import idv.cjcat.stardust.twoD.geom.MotionData4D; public class TubeDeflector breidt Deflector uit private var y1: Number; privévar y2: Number; openbare functie TubeDeflector (y1: Number, y2: Number) // y2 moet groter zijn dan y2 als (y1> y2) // y1 en y2 verwisselen als y1 groter is var temp: Number = y1; y1 = y2; y2 = temp;  this.y1 = y1; this.y2 = y2;  override-beschermde functie calculationMotionData4D (particle: Particle2D): MotionData4D // uitvoercomponenten, geïnitialiseerd naar de oorspronkelijke bewegingsgegevens van het deeltje var x: Number = particle.x; var y: Number = particle.y; var vx: Number = particle.vx; var vy: Number = particle.vy; // caluculeer werkelijke coliusradius var radius: Number = particle.collisionRadius * particle.scale; // flag of de deflector in werking treedt var deflected: Boolean = false; if (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 - straal)) // deeltje y-coördinaat is groter dan bovengrens // stel juiste nieuwe y-coördinaat in y = y2 - straal; // set vlag afgebogen = true;  if (afgebogen) return new MotionData4D (x, y, vx, vy);  else // negeer het deeltje en update zijn bewegingsgegevens niet terug nul; 

Stap 3: Buisdeflectoreffect Voeg de deflector toe

Je zou nu wel moeten weten wat we de volgende keer goed gaan doen. Dat klopt, we gaan de deflector toevoegen aan a buigen actie en voeg vervolgens de actie toe aan de zender. Voeg de volgende code toe aan de emitterconstructor.

 // maak een buisdeflector var deflector: deflector = nieuwe TubeDeflector (100, 300); var deflect: Deflect = new Deflect (); deflect.addDeflector (deflector); Addaction (Deflect);

Stap 4: Tube Deflector-effect Test de film

U kunt de film nu testen. Nogmaals, je mag ook een visuele representatie van de deflector op het podium tekenen voor een beter uiterlijk.

Mijlpaal Bekijk het online

Conclusie

Dit is het einde van de hele tutorial. In het eerste deel heb je geleerd over zwaartekrachtvelden. In het tweede deel heb je het concept van deflectors en het daadwerkelijke gebruik van de buigen actie. Ook heb je geleerd hoe je het kunt uitbreiden deflector klasse om aangepaste deflectors te maken. Nu kunt u geavanceerde deeltjesbewegingsmanipulatie uitvoeren in Stardust.

Heel erg bedankt voor het lezen!