Manipulation du mouvement des particules avec le moteur à particules Stardust - Partie 2

Ceci est la deuxième partie de ce tutoriel. Je vais vous montrer comment manipuler le mouvement des particules avec des déflecteurs.

Une connaissance préalable des bases du mouvement et des champs de vecteurs est requise. Je vous recommande vivement de compléter la première partie de ce didacticiel avant de poursuivre..


Aperçu du résultat final

Jetez un coup d'œil au résultat final sur lequel nous allons travailler. C'est un exemple d'effet de sol, avec des particules qui rebondissent sur le sol.


Déflecteurs

À peu près comme les champs de gravité, un déflecteur prend en entrée les données de mouvement actuelles d'une particule. Ensuite, le déflecteur écrase le mouvement de la particule avec sa sortie, sauf que la sortie contient maintenant des données de vélocité en plus des données de position. Ainsi, dans l’espace 2D, la sortie d’un déflecteur est un vecteur 4D; les deux premières composantes du vecteur 4D représentent les composantes x et y du vecteur de position (notées X et y), respectivement, et les deux dernières composantes représentent les composantes x et y du vecteur vitesse (noté vx et vy).


Comment utiliser les déflecteurs

Se souvenir du Champ la classe et la La gravité action de la première partie de ce tutoriel? Eh bien, la procédure est similaire. Tu crées Déflecteur objets qui manipulent les mouvements de particules, puis les ajoutent à la Dévier action, comme vous le feriez ajouter Champ objets à la La gravité action. Maintenant, regardons un exemple rapide.


Effet de sol

Dans cet exemple, nous allons utiliser le LineDeflector classe pour créer un effet de particules-rebond sur le sol. Un déflecteur de ligne simule essentiellement une ligne infiniment longue dans un espace 2D, avec un côté espace libre et l’autre côté plein; les particules sont uniquement autorisées dans l'espace ouvert et non autorisées dans l'espace solide. Lorsque des particules viennent du côté de l'espace libre, frappant la ligne, elles rebondissent. le Particle.collisionRadius propriété, représentant le rayon d'une particule, est prise en compte.

Le déflecteur de ligne utilise un vecteur normal et un point traversé par la ligne dans un espace 2D pour déterminer la ligne. Voici une illustration pour vous donner une meilleure idée.


Étape 1: Symbole du cercle d'effet de sol

Créez un document Flash, tracez un cercle de rayon 10, puis convertissez-le en symbole exporté pour ActionScript avec un nom de classe. Cercle.


Étape 2: Effet de sol La classe de document

Créez un fichier AS pour la classe de document. La classe crée un émetteur et un moteur de rendu. Si vous avez besoin d'un rappel sur l'utilisation de base de Stardust, vous pouvez consulter ce didacticiel..

 package import flash.display.Sprite; import flash.events.Event; import idv.cjcat.stardust.common.emitters.Emitter; import idv.cjcat.stardust.common.renderers.Renderer; importer idv.cjcat.stardust.twoD.renderers.DisplayObjectRenderer; public class FloorEffect étend Sprite private var emitter: Emitter; convertisseur de rendu privé: Renderer; fonction publique FloorEffect () emitter = new CircleEmitter (); renderer = new DisplayObjectRenderer (this); renderer.addEmitter (émetteur); addEventListener (Event.ENTER_FRAME, mainLoop);  fonction privée mainLoop (e: Event): void emitter.step (); 

La classe d'émetteur est indiquée ci-dessous. Il jaillit essentiellement des particules de cercle et les particules sont affectées par un champ de gravité uniforme, pointant vers le bas.

 package import idv.cjcat.stardust.common.actions.Age; import idv.cjcat.stardust.common.actions.DeathLife; import idv.cjcat.stardust.common.actions.ScaleCurve; importer 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; importer 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; importer idv.cjcat.stardust.twoD.initializers.Position; importer idv.cjcat.stardust.twoD.initializers.Velocity; import idv.cjcat.stardust.twoD.zones.LazySectorZone; import idv.cjcat.stardust.twoD.zones.SinglePoint; Classe publique CircleEmitter étend Emitter2D fonction publique CircleEmitter () super (new SteadyClock (1)); // initializer addInitializer (new DisplayObjectClass (Circle)); addInitializer (nouvelle vie (nouvelle UniformRandom (60, 10))); addInitializer (nouvelle position (nouveau SinglePoint (320, 100))); addInitializer (nouvelle Velocity (nouvelle LazySectorZone (8, 4))); addInitializer (nouvelle échelle (nouvelle UniformRandom (1, 0,4))); addInitializer (nouveau CollisionRadius (10)); // actions addAction (new Age ()); addAction (new DeathLife ()); addAction (new Move ()); addAction (nouvelle ScaleCurve (0, 10)); // champ de gravité var: Champ = nouveau UniformField (0, 0.5); var gravité: Gravity = new Gravity (); gravité.addField (champ); addAction (gravité); 

Vous avez maintenant créé un effet avec des particules projetées du centre de la scène et entraînées par la gravité. Voici à quoi ça ressemble:

Étape importante Voir en ligne

Étape 3: Effet de plancher Ajouter le déflecteur

Ajoutez le code suivant dans le constructeur de l'émetteur. Il crée un déflecteur de ligne, l'ajoute au Déflecteur action, puis ajoute l'action à l'émetteur, activant ainsi l'effet de déflecteur. Les deux premiers paramètres du constructeur pour LineDeflector class est la coordonnée d'un point sur la ligne et les deux derniers paramètres sont les composantes x et y du vecteur normal de la ligne. le Deflector.bounce propriété détermine le "rebondissement" de la ligne, 1 provoquant un rebond complet et 0 signifiant aucun rebond du tout.

 // crée un déflecteur de ligne passant par le point (320, 320) et le déflecteur normal (0, -1): Déflecteur = new LineDeflector (320, 320, 0, -1); deflector.bounce = 0,6; var deflect: Deflect = new Deflect (); deflect.addDeflector (déflecteur); addAction (dévier);

Vous pouvez également dessiner une représentation visuelle de la ligne sur la scène pour avoir une meilleure apparence.

Bon, nous en avons fini avec cet exemple. Regardons maintenant notre résultat final.

Étape importante Voir en ligne

Bounding Box

Dans cet exemple, nous allons utiliser le BoundingBox déflecteur pour contraindre les particules à l'intérieur d'une zone rectangulaire.


Étape 1: Boîte englobante de la classe d'émetteur

La classe de document reste la même que dans l'exemple précédent, mais nous allons changer la classe d'émetteur. C'est la classe d'émetteur de base de cet exemple. Par rapport à la classe emitter de l'exemple précédent, le SteadClock est changé en ImpulseClock pour créer instantanément 20 particules au début, la zone de position passe d’un point unique à une zone rectangulaire qui correspond à la taille de la Rapidité l'initialiseur est un peu ralenti, la La vie l’initialiseur est supprimé car nous voulons que les particules restent en permanence sur la scène, la Âge et DeathLife les actions sont à leur tour non requises et supprimées, et le ScaleCurve est également supprimé. Certaines importations sont également ajoutées et supprimées. vous pouvez simplement copier le code ci-dessous pour plus de commodité.

 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; importer 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; importer idv.cjcat.stardust.twoD.initializers.Position; importer 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; Classe publique CircleEmitter étend Emitter2D private var impulseClock: ImpulseClock; fonction publique CircleEmitter () super (impulseClock = new ImpulseClock (20)); impulseClock.impulse (); // initializer addInitializer (new DisplayObjectClass (Circle)); addInitializer (nouvelle position (nouvelle RectZone (0, 0, 640, 400))); addInitializer (new Velocity (new LazySectorZone (3, 2))); addInitializer (nouvelle échelle (nouvelle UniformRandom (1, 0,4))); addInitializer (nouveau CollisionRadius (10)); // actions addAction (new Move ()); 

Étape 2: Boîte englobante Ajouter le déflecteur

Comme dans l'exemple précédent, nous ajoutons maintenant le code suivant dans le constructeur de l'émetteur pour utiliser le Dévier action, seulement que cette fois nous utilisons la BoundingBox déflecteur pour contraindre les particules dans une région rectangulaire qui correspond à la taille de la scène.

 // deflector var deflector: Deflector = new BoundingBox (0, 0, 640, 400); var deflect: Deflect = new Deflect (); deflect.addDeflector (déflecteur); addAction (dévier);

Étape 3: Bounding Box Testez le film

C'est tout. Rien n'a beaucoup changé, et maintenant nous avons des particules contraintes dans une boîte englobante. Testez le film et vous verrez le résultat.

Étape importante Voir en ligne

Déflecteurs personnalisés

Nous allons maintenant créer nous-mêmes des déflecteurs personnalisés. Comprenons d'abord le Déflecteur classe nous sommes sur le point d'étendre.

le Déflecteur classe est la classe de base pour tous les déflecteurs. Pour créer des déflecteurs personnalisés, vous devez étendre cette classe et remplacer le CalculateMotionData4D () méthode, puis retourne un MotionData4D objet représentant la sortie vectorielle 4D du déflecteur. L’entrée à votre disposition, tout comme la Champ classe, est inclus dans le Particle2D objet passé dans la méthode en tant que paramètre. Vous pouvez utiliser ceci Particle2D objet pour déterminer votre sortie. À propos, si cette méthode retourne un nul la valeur, la Dévier l'action suppose que vous ne voulez pas changer le mouvement de la particule actuelle, ignorez la particule, puis passez au traitement de la particule suivante.

Par exemple, le déflecteur suivant ferait pivoter le vecteur vitesse de chaque particule d'un degré dans le sens des aiguilles d'une montre.

 package import idv.cjcat.stardust.twoD.geom.Vec2D; import idv.cjcat.stardust.twoD.particles.Particle2D; import idv.cjcat.stardust.twoD.deflectors.Deflector; importer idv.cjcat.stardust.twoD.geom.MotionData4D; Classe publique Rotator extended Deflector fonction protégée override CalculateMotionData4D (particule: Particle2D): MotionData4D var vitesse: Vec2D = new Vec2D (particule.vx, particule.vy); velocity.rotateThis (1); retourne un nouveau MotionData4D (particule.x, particule.y, vélocité.x, vélocité.y); 

Effet Deflecteur De Tube

Dans cet exemple, nous allons étendre la Déflecteur classer et créer notre propre déflecteur, simulant un tube, qui est essentiellement constitué de deux déflecteurs de ligne prenant en sandwich un espace libre en forme de tube.


Étape 1: Effet de déflecteur de tube de la classe d'émetteur

Copiez le document Flash, ainsi que le Cercle symbole et le document du premier exemple. Ici, nous allons créer une autre classe d'émetteur, toujours nommée Cercle émetteur. Cette fois, l'émetteur émet des particules du centre de la scène et aucun champ de gravité n'est appliqué.

 package import idv.cjcat.stardust.common.actions.Age; import idv.cjcat.stardust.common.actions.DeathLife; import idv.cjcat.stardust.common.actions.ScaleCurve; importer 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; importer 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; importer idv.cjcat.stardust.twoD.initializers.Position; importer idv.cjcat.stardust.twoD.initializers.Velocity; import idv.cjcat.stardust.twoD.zones.LazySectorZone; import idv.cjcat.stardust.twoD.zones.SinglePoint; Classe publique CircleEmitter étend Emitter2D fonction publique CircleEmitter () super (new SteadyClock (1)); // initializer addInitializer (new DisplayObjectClass (Circle)); addInitializer (nouvelle vie (nouvelle UniformRandom (60, 10))); addInitializer (nouvelle position (nouveau SinglePoint (320, 200))); // stage center addInitializer (new Velocity (new LazySectorZone (8, 4))); addInitializer (nouvelle échelle (nouvelle UniformRandom (1, 0,4))); addInitializer (nouveau CollisionRadius (10)); // actions addAction (new Age ()); addAction (new DeathLife ()); addAction (new Move ()); addAction (nouvelle ScaleCurve (0, 10)); 

Étape 2: Effet du déflecteur de tube Le déflecteur de tube

Nous allons maintenant créer notre classe de déflecteurs de tubes. Les détails sont expliqués dans les commentaires.

 package import idv.cjcat.stardust.twoD.particles.Particle2D; import idv.cjcat.stardust.twoD.deflectors.Deflector; importer idv.cjcat.stardust.twoD.geom.MotionData4D; Classe publique TubeDeflector. Deflector private var y1: Number; private var y2: Number; fonction publique TubeDeflector (y1: Number, y2: Number) // y2 devrait être plus grand que y2 si (y1> y2) // échange y1 et y2 si y1 est plus grand var temp: Number = y1; y1 = y2; y2 = temp;  this.y1 = y1; this.y2 = y2;  écrasement de la fonction protégée CalculateMotionData4D (particule: Particle2D): MotionData4D // composants de sortie, initialisée aux données de mouvement d'origine de la particule var x: Number = particule.x; var y: nombre = particule.y; var vx: Nombre = particule.vx; var vy: Number = particule.vy; // calcule le rayon réel de la collection var radius: Number = particle.collisionRadius * particle.scale; // indicateur indiquant si le déflecteur prend effet var var deflected: Boolean = false; si (particule.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 - rayon)) // la coordonnée y de la particule est supérieure à la limite supérieure // définissez la nouvelle coordonnée y appropriée y = y2 - rayon; // set flag deflected = true;  if (dévié) retourne un nouveau MotionData4D (x, y, vx, vy);  else // ignore la particule et ne met pas à jour ses données de mouvement return null; 

Étape 3: Effet du déflecteur de tube Ajouter le déflecteur

Vous devriez savoir ce que nous allons faire très bien maintenant. C'est vrai, nous allons ajouter le déflecteur à un Dévier action et ensuite ajouter l'action à l'émetteur. Ajoutez le code suivant dans le constructeur de l'émetteur.

 // crée un déflecteur de tube var déflecteur: Deflector = new TubeDeflector (100, 300); var deflect: Deflect = new Deflect (); deflect.addDeflector (déflecteur); addAction (dévier);

Étape 4: Effet du déflecteur de tube Testez le film

Vous pouvez maintenant tester le film. Encore une fois, vous pouvez également dessiner une représentation visuelle du déflecteur sur la scène pour une meilleure apparence.

Étape importante Voir en ligne

Conclusion

C'est la fin du tutoriel complet. Dans la première partie, vous avez appris sur les champs gravitationnels. Dans la deuxième partie, vous avez appris le concept de déflecteur et l’utilisation réelle du Dévier action. En outre, vous avez appris comment étendre la Déflecteur classe pour créer des déflecteurs personnalisés. Vous pouvez maintenant effectuer une manipulation avancée du mouvement des particules dans Stardust..

Merci beaucoup d'avoir lu!