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.
Bekijk het eindresultaat waar we naartoe zullen werken. Het is een voorbeeld van een vloereffect, waarbij deeltjes van de vloer botsen.
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).
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.
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.
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
.
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 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 In dit voorbeeld gaan we de gebruiken BoundingBox
deflector om deeltjes in een rechthoekig gebied te beperken.
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 ());
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);
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 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);
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.
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));
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;
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);
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 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!