Detta är den andra delen av denna handledning. Jag ska visa dig hur man kan manipulera partikelrörelse med deflektorer.
Förkunskaper om rörelseunderlag och vektorfält krävs. Jag rekommenderar starkt att du slutför den första delen av denna handledning innan du går vidare.
Ta en titt på det slutliga resultatet vi kommer att arbeta för. Det är ett exempel på en golv effekt, med partiklar studsar från golvet.
Ganska mycket som gravitation fält, en deflector tar en partikelns nuvarande rörelse data som input. Efteråt överskrider deflektor partikelns rörelse med sin utgång, endast att utmatningen nu innehåller hastighetsdata utöver positionsdata. I 2D-utrymme är således en deflektorens utgång en 4D-vektor; De första två komponenterna i 4D-vektorn representerar x- och y-komponenten i positionsvektorn (betecknad x och y), och de två sista komponenterna representerar hastighetsvektorns x- och y-komponent (betecknad vx och vy).
Kom ihåg det Fält
klass och Allvar
åtgärder från den första delen av denna handledning? Tja, proceduren är liknande. Du skapar deflektor
objekt som manipulerar partikelrörelser och lägg sedan till dem i Avleda, avvika, avlänka
åtgärd, precis som du skulle lägga till Fält
objekt till Allvar
verkan. Låt oss nu titta på ett snabbt exempel.
I det här exemplet ska vi använda LineDeflector
klass för att skapa en partikel-studsande golv effekt. En linjeavledare simulerar väsentligen en oändligt lång linje i 2D-utrymme, med ena sidan öppet utrymme och den andra sidan fast; partiklar får endast vara i det öppna utrymmet och inte tillåtas i det fria utrymmet. När partiklar kommer från den öppna rymdsidan och slår på linjen kommer de att studsa tillbaka. De Particle.collisionRadius
egendom, som representerar partikelns radie, beaktas.
Linjeavledaren använder en normal vektor och en punkt som linjen passerar genom i 2D-utrymme för att bestämma linjen. Här är en illustration som ger dig en bättre idé.
Skapa ett nytt Flash-dokument, dra en cirkel med en radie av 10 och konvertera den sedan till en symbol som exporteras för ActionScript med ett klassnamn Cirkel
.
Skapa en AS-fil för dokumentklassen. Klassen skapar en emitter och en renderer. Om du tycker om att behöva uppdatera Stardusts grundläggande användning, kan du kolla in den här handledningen.
paket import flash.display.Sprite; importera flash.events.Event; importera idv.cjcat.stardust.common.emitters.Emitter; importera idv.cjcat.stardust.common.renderers.Renderer; importera idv.cjcat.stardust.twoD.renderers.DisplayObjectRenderer; public class FloorEffect utökar Sprite private var emitter: Emitter; privat var renderer: Renderer; offentlig funktion FloorEffect () emitter = new CircleEmitter (); renderer = ny DisplayObjectRenderer (this); renderer.addEmitter (emitter); addEventListener (Event.ENTER_FRAME, mainLoop); privat funktion mainLoop (e: Event): void emitter.step ();
Emitterklassen visas nedan. Det skjuter i princip ut cirkelpartiklar och partiklarna påverkas av ett enhetligt tyngdfält, som pekar nedåt.
paket import idv.cjcat.stardust.common.actions.Age; importera idv.cjcat.stardust.common.actions.DeathLife; importera idv.cjcat.stardust.common.actions.ScaleCurve; importera idv.cjcat.stardust.common.clocks.SteadyClock; importera idv.cjcat.stardust.common.initializers.Life; importera idv.cjcat.stardust.common.initializers.Scale; importera idv.cjcat.stardust.common.math.UniformRandom; importera idv.cjcat.stardust.twoD.actions.Gravity; importera idv.cjcat.stardust.twoD.actions.Move; importera idv.cjcat.stardust.twoD.emitters.Emitter2D; importera idv.cjcat.stardust.twoD.fields.Field; importera idv.cjcat.stardust.twoD.fields.UniformField; importera idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; importera idv.cjcat.stardust.twoD.initializers.Position; importera idv.cjcat.stardust.twoD.initializers.Velocity; importera idv.cjcat.stardust.twoD.zones.LazySectorZone; importera idv.cjcat.stardust.twoD.zones.SinglePoint; public class CircleEmitter utökar Emitter2D offentlig funktion CircleEmitter () super (new SteadyClock (1)); // initialisatorer addInitializer (nya DisplayObjectClass (Circle)); addInitializer (new Life (new UniformRandom (60, 10))); addInitializer (new Position (new SinglePoint (320, 100))); addInitializer (new Velocity (new LazySectorZone (8, 4))); addInitializer (new Scale (new UniformRandom (1, 0.4))); addInitializer (new CollisionRadius (10)); // åtgärder addAction (new Age ()); addAction (new DeathLife ()); addAction (new Move ()); addAction (ny ScaleCurve (0, 10)); // gravitation var fält: Fält = nytt UniformField (0, 0,5); var gravitation: Gravity = new Gravity (); gravity.addField (fält); addAction (gravitation);
Nu har du skapat en effekt med partiklar som skjuter ut från mitten av scenen, dras ner av gravitationen. Så här ser det ut:
Milstolpe Visa det på nätet Lägg till folloingskoden i emitterkonstruktorn. Det skapar en linje deflector, lägger den till deflektor
åtgärd, och lägger sedan åtgärden till emitteren och därigenom aktiverar deflektor-effekten. De två första konstruktörparametrarna för LineDeflector
klassen är koordinaten för en punkt på linjen, och de två sista parametrarna är x- och y-komponenterna i linjens normala vektor. De Deflector.bounce
egenskapen bestämmer linjens "bounciness", 1 som orsakar fullständig rebound, och 0 betyder ingen rebound alls.
// skapa en linje deflektor som passerar genom punkten (320, 320) och normal (0, -1) var deflektor: Deflector = ny LineDeflector (320, 320, 0, -1); deflector.bounce = 0,6; var avböj: Deflect = new Deflect (); deflect.addDeflector (deflektor); addAction (avleda);
Du kan också dra en visuell representation av linjen på scenen för att få en bättre titt.
Okej, vi är färdiga med det här exemplet. Låt oss nu ta en titt på vårt slutliga resultat.
Milstolpe Visa det på nätet I det här exemplet ska vi använda BoundingBox
deflektor för att begränsa partiklar i en rektangulär yta.
Dokumentklassen förblir densamma som föregående exempel, men vi kommer att ändra emitterklassen. Detta är basemittersklassen i detta exempel. Jämfört med emitterklassen i det föregående exemplet SteadClock
ändras till a ImpulseClock
för att omedelbart skapa 20 partiklar i början, ändras positionszonen från en enda punkt till en rektangulär zon som matchar scenstorleken, Hastighet
initieraren är långsammare lite, den Liv
initieraren avlägsnas eftersom vi vill att partiklar ska stanna permanent på scenen, Ålder
och DeathLife
Åtgärder är i sin tur inte nödvändiga och borttagna, och ScaleCurve
tas också bort. Vissa importeringar läggs också till och tas bort; Du kan bara kopiera koden nedan för att göra det lättare.
paket import idv.cjcat.stardust.common.clocks.ImpulseClock; importera idv.cjcat.stardust.common.initializers.CollisionRadius; importera idv.cjcat.stardust.common.initializers.Scale; importera idv.cjcat.stardust.common.math.UniformRandom; importera idv.cjcat.stardust.twoD.actions.Deflect; importera idv.cjcat.stardust.twoD.actions.Move; importera idv.cjcat.stardust.twoD.deflectors.BoundingBox; importera idv.cjcat.stardust.twoD.deflectors.Deflector; importera idv.cjcat.stardust.twoD.emitters.Emitter2D; importera idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; importera idv.cjcat.stardust.twoD.initializers.Position; importera idv.cjcat.stardust.twoD.initializers.Velocity; importera idv.cjcat.stardust.twoD.zones.LazySectorZone; importera idv.cjcat.stardust.twoD.zones.RectZone; importera idv.cjcat.stardust.twoD.zones.SinglePoint; public class CircleEmitter utökar Emitter2D private var impulsClock: ImpulseClock; offentlig funktion CircleEmitter () super (impulseClock = nytt impulsklocka (20)); impulseClock.impulse (); // initialisatorer addInitializer (nya DisplayObjectClass (Circle)); addInitializer (ny position (ny RectZone (0, 0, 640, 400))); addInitializer (new Velocity (new LazySectorZone (3, 2))); addInitializer (new Scale (new UniformRandom (1, 0.4))); addInitializer (new CollisionRadius (10)); // åtgärder addAction (new Move ());
Nästan som föregående exempel lägger vi nu till följande kod i emitterkonstruktorn för att använda Avleda, avvika, avlänka
åtgärd, bara den här gången använder vi BoundingBox
deflektor för att begränsa partiklar i en rektangulär region som matchar scenstorleken.
// deflektorvarv deflektor: Deflector = ny BoundingBox (0, 0, 640, 400); var avböj: Deflect = new Deflect (); deflect.addDeflector (deflektor); addAction (avleda);
Det är allt. Ingenting mycket förändras, och nu har vi begränsat partiklar i en avgränsningslåda. Testa filmen och du ska se resultatet.
Milstolpe Visa det på nätet Nu ska vi skapa egna deflektor på egen hand. Låt oss först förstå deflektor
klass vi håller på att utöka.
De deflektor
klassen är basklassen för alla deflektorer. För att skapa anpassade deflectorer ska du förlänga den här klassen och åsidosätta calculateMotionData4D ()
metod, och returnera sedan a MotionData4D
objekt som representerar 4D-vektorutgången hos deflektorn. Ingången till ditt förfogande, precis som Fält
klass, ingår i Particle2D
objektet passerade in i metoden som parameter. Du kan använda det här Particle2D
objekt för att bestämma din produktion. Förresten, om denna metod returnerar a null
värde, den Avleda, avvika, avlänka
åtgärd antar att du inte vill ändra den aktuella partikelns rörelse, ignorera partikeln och fortsätt sedan bearbeta nästa partikel.
Till exempel skulle följande deflektor rotera varje partikelhastighetsvektor med en grad klockvis.
paket import idv.cjcat.stardust.twoD.geom.Vec2D; importera idv.cjcat.stardust.twoD.particles.Particle2D; importera idv.cjcat.stardust.twoD.deflectors.Deflector; importera idv.cjcat.stardust.twoD.geom.MotionData4D; allmän klass Rotator sträcker Deflector överstyr skyddad funktion calculateMotionData4D (partikel: Particle2D): MotionData4D varhastighet: Vec2D = ny Vec2D (particle.vx, particle.vy); velocity.rotateThis (1); returnera nya MotionData4D (partikel.x, partikel.y, hastighet.x, hastighet.y);
I det här exemplet kommer vi att förlänga deflektor
klass och skapa vår egen deflector, simulera ett rör, som i huvudsak är två linjedämpare som smälter i ett rörformat ledigt utrymme.
Kopiera Flash-dokumentet, tillsammans med Cirkel
symbol och dokumentet från det första exemplet. Här kommer vi att skapa en annan emittersklass, som fortfarande heter CircleEmitter
. Den här gången sänder emitteren partiklar från centrum av scenen och ingen gravitation fält appliceras.
paket import idv.cjcat.stardust.common.actions.Age; importera idv.cjcat.stardust.common.actions.DeathLife; importera idv.cjcat.stardust.common.actions.ScaleCurve; importera idv.cjcat.stardust.common.clocks.SteadyClock; importera idv.cjcat.stardust.common.initializers.CollisionRadius; importera idv.cjcat.stardust.common.initializers.Life; importera idv.cjcat.stardust.common.initializers.Scale; importera idv.cjcat.stardust.common.math.UniformRandom; importera idv.cjcat.stardust.twoD.actions.Deflect; importera idv.cjcat.stardust.twoD.actions.Move; importera idv.cjcat.stardust.twoD.deflectors.Deflector; importera idv.cjcat.stardust.twoD.emitters.Emitter2D; importera idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; importera idv.cjcat.stardust.twoD.initializers.Position; importera idv.cjcat.stardust.twoD.initializers.Velocity; importera idv.cjcat.stardust.twoD.zones.LazySectorZone; importera idv.cjcat.stardust.twoD.zones.SinglePoint; public class CircleEmitter utökar Emitter2D offentlig funktion CircleEmitter () super (new SteadyClock (1)); // initialisatorer addInitializer (nya DisplayObjectClass (Circle)); addInitializer (new Life (new UniformRandom (60, 10))); addInitializer (new Position (new SinglePoint (320, 200))); // stadium center addInitializer (ny hastighet (nya LazySectorZone (8, 4))); addInitializer (new Scale (new UniformRandom (1, 0.4))); addInitializer (new CollisionRadius (10)); // åtgärder addAction (new Age ()); addAction (new DeathLife ()); addAction (new Move ()); addAction (ny ScaleCurve (0, 10));
Nu ska vi skapa vår tube deflector klass. Detaljerna förklaras i kommentarer.
paket import idv.cjcat.stardust.twoD.particles.Particle2D; importera idv.cjcat.stardust.twoD.deflectors.Deflector; importera idv.cjcat.stardust.twoD.geom.MotionData4D; public class TubeDeflector sträcker Deflector private var y1: Number; privat var y2: nummer; offentlig funktion TubeDeflector (y1: Number, y2: Number) // y2 bör vara större än y2 om (y1> y2) // byt y1 och y2 om y1 är större var temp: Number = y1; y1 = y2; y2 = temp; this.y1 = y1; this.y2 = y2; åsidosätta skyddad funktion calculateMotionData4D (partikel: Particle2D): MotionData4D // utgångskomponenter, initialiserade till partikelns ursprungliga rörelsesdata var x: Number = particle.x; var y: Number = particle.y; var vx: Number = particle.vx; var vy: Number = particle.vy; // kaluculera den faktiska kollisionsradien var radie: Number = particle.collisionRadius * particle.scale; // flagga för huruvida deflektorn träder i kraft var avböjt: Booleskt = false; om (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-radie)) // partikel y-koordinat är större än övre gräns // Ange korrekt ny y-koordinat y = y2-radie; // set flaggböjde = true; om (avböjt) returnera nya MotionData4D (x, y, vx, vy); annars // ignorerar partikeln och uppdaterar inte sin rörelsedata retur null;
Du borde veta vad vi ska göra nu mycket bra nu. Det är rätt, vi ska lägga till deflektorn till en Avleda, avvika, avlänka
åtgärd och lägg sedan till åtgärden till emitern. Lägg till följande kod i emitterkonstruktorn.
// skapa en rör deflektor var deflector: Deflector = ny TubeDeflector (100, 300); var avböj: Deflect = new Deflect (); deflect.addDeflector (deflektor); addAction (avleda);
Nu kan du testa filmen. Återigen kan du också dra en viss visuell representation av deflektorn på scenen för en bättre utseende.
Milstolpe Visa det på nätet Detta är slutet på hela handledningen. I den första delen har du lärt dig om gravitationsfält. I den andra delen har du lärt dig begreppet deflectorer och den faktiska användningen av Avleda, avvika, avlänka
verkan. Du har också lärt dig hur du förlänger deflektor
klass för att skapa anpassade deflectorer. Nu kan du utföra avancerad partikelrörelsesmanipulation i Stardust.
Tack så mycket för att du läser!