Shoot Out Stars avec le moteur Stardust Particle

Dans ce tutoriel, je vais vous présenter le moteur de particules Stardust. Tout d'abord, je vais vous montrer comment configurer Stardust, puis je traiterai des responsabilités de base de la classe Stardust et de la manière dont elles collaborent pour que Stardust fonctionne dans son ensemble..

Ensuite, nous examinerons le flux de travail général d'un Stardust et nous nous attacherons à créer un effet de particules avec des étoiles sortant du curseur de la souris. les étoiles ralentissent progressivement, grossissent après la naissance et rétrécissent au moment de la mort.

Enfin, je démontrerai la flexibilité de Stardust en créant plusieurs variantes de l'exemple déjà complet, notamment en utilisant des clips animés en tant que particules, une échelle de temps de simulation de particules variable et en supprimant des objets d'affichage de différentes classes à partir d'un seul émetteur..

Ce didacticiel s'adresse aux personnes déjà familiarisées avec la programmation orientée objet (OOP) d'ActionScript 3.0. Je suppose donc que vous savez déjà très bien ce que sont les classes, les objets, l'héritage et l'interface. Pas de problème avec la POO? Alors allons tirer quelques étoiles!




Moteur à particules Stardust

Comme son nom l'indique, Stardust est utilisé pour créer des effets de particules. Si vous êtes un ActionScripter expérimenté, vous avez peut-être souvent créé des effets de particules à partir de rien et vous avez déclaré: "Je suis totalement cool avec la création d'effets de particules à partir de rien, alors pourquoi aurais-je besoin d'un moteur de particules?" Eh bien, Stardust est là pour vous aider à vous concentrer davantage sur la conception du comportement des particules que sur les tâches fastidieuses sous-jacentes, telles que la gestion de la mémoire. Au lieu d'écrire du code pour gérer les données relatives aux particules, d'initialiser et de supprimer les ressources, avec Stardust, vous pouvez ignorer ces routines ennuyeuses et décider simplement de la manière dont vous souhaitez que vos particules se comportent..

Stardust Caractéristiques

La structure de classe de Stardust est inspirée de FLiNT Particle System, un autre moteur de particules ActionScript 3.0. Ainsi, ils partagent certaines caractéristiques de base similaires.

  • Effets de particules 2D et 3D - Stardust peut être utilisé pour créer des effets de particules 2D et 3D. Il possède son propre moteur 3D intégré et peut également être utilisé en combinaison avec d'autres moteurs 3D à particules tierces, notamment ZedBox, Papervision3D et ND3D..
  • Haute extensibilité - Stardust fournit un grand nombre de comportements de particules et de moteurs de rendu à votre disposition. Si aucun d’entre eux ne répond à vos besoins, vous pouvez toujours étendre les classes de base et créer vos propres comportements de particules personnalisés. Vous pouvez également créer votre propre moteur de rendu pour travailler avec un autre moteur 3D non pris en charge par Stardust..

En plus de ces fonctionnalités de base, Stardust fournit également plusieurs fonctionnalités avancées aux utilisateurs expérimentés..

  • Échelle de temps de simulation réglable - L'échelle de temps utilisée pour la simulation de particules peut être ajustée dynamiquement pendant l'exécution. Par exemple, si vous modifiez l’échelle de temps par la moitié de l’original, l’effet de particules sera deux fois moins rapide que la vitesse normale; et si vous ajustez l’échelle de temps au double de l’original, l’effet de particules sera simulé deux fois plus vite que la normale. Cette fonctionnalité peut s'avérer utile lorsque vous créez un jeu avec des effets de ralenti: l'effet de particules peut ralentir pour correspondre à la vitesse de votre moteur de jeu, en synchronisation avec vos animations et graphiques.
  • Sérialisation XML - Vous pouvez transformer votre système de particules en un fichier au format XML pouvant être stocké sur votre disque dur, chargé ultérieurement au cours de l'exécution et interprété pour reconstruire votre système de particules d'origine. Ceci est très utile lorsque vous travaillez avec un grand projet. Supposons que vous souhaitiez simplement dimensionner un peu vos particules. Vous devez donc ajuster les paramètres du code source et recompiler l’ensemble de votre application Flash, ce qui peut prendre une minute, voire plus de cinq minutes si votre projet est extrêmement volumineux. Est-ce que ça vaut le coup? Absolument pas. C'est une perte de temps totale. En utilisant la fonctionnalité de sérialisation XML pour enregistrer votre système de particules dans des fichiers XML externes, vous séparez les paramètres du code source de l'application principale. Il vous suffira donc d'ouvrir le fichier XML, de modifier les valeurs des paramètres, de le sauvegarder et de rouvrir votre application principale. C'est tout! Aucune recompilation n'est requise du tout. Je dirais que c'est le moyen idéal de travailler avec de grands projets.

En ce qui concerne les effets de particules, il est très important de gérer efficacement des données volumineuses. Stardust utilise beaucoup les pools d'objets et les listes chaînées pour améliorer les performances:

  • Pools d'objets - Les objets utilisés sont stockés dans un pool. plus tard, si un objet du même type est requis, Stardust ne l'instancie pas immédiatement, mais vérifie s'il reste un objet précédemment stocké dans le pool d'objets. Si c'est le cas, Stardust supprime simplement cet objet et l'utilise au lieu de créer un nouvel objet. Habituellement, les effets de particules impliquent beaucoup d'instanciation d'objet, ce qui consomme beaucoup de temps processeur. En utilisant des pools d'objets, Stardust réduit considérablement le temps d'instanciation.
  • Listes liées - Il est très facile et tentant de stocker des données de particules dans un tableau. Cependant, dans le cas où des particules sont créées et éliminées très fréquemment, de nombreuses épissures de matrice ont lieu pour éliminer les particules mortes. L'épissage de tableau est un processus consommateur de temps processeur, en particulier pour les tableaux longs. Quelle que soit la longueur de la liste chaînée, il faut toujours le même temps pour épisser les particules mortes. À partir de la version 1.1, Stardust a commencé à utiliser des listes chaînées en interne pour stocker des données de particules..

Mise en place de poussière d'étoile

Avant de passer au codage proprement dit, nous devons récupérer une copie de Stardust Particle Engine. Il est publié sous licence MIT, ce qui signifie qu'il est totalement gratuit, que vous souhaitiez l'utiliser dans un projet commercial ou non commercial..

Voici la page d'accueil du projet Stardust: http://code.google.com/p/stardust-particle-engine/

Vous pouvez télécharger Stardust ici: http://code.google.com/p/stardust-particle-engine/downloads/list

Au moment de la rédaction de ce document, la dernière version pouvant être téléchargée à partir de la liste de téléchargement est la version 1.1.132 bêta. Vous pouvez toujours récupérer la dernière révision du référentiel SVN (qui peut ne pas être stable, cependant).

Sur la page d'accueil du projet, vous pouvez également trouver d'autres accessoires, tels que la documentation de l'API et une copie du manuel PDF. Il y a même des tutoriels vidéo sur YouTube.

Responsabilités de la classe Stardust

Ici, je vais couvrir brièvement les classes de base Stardust et leurs responsabilités.

StardustElement

Cette classe est la super-classe de toutes les classes principales, qui définit les propriétés et les méthodes en particulier pour la sérialisation XML..

au hasard

De manière générale, les effets de particules consistent essentiellement à contrôler un nombre d'entités ayant une apparence et des comportements similaires mais randomisés. La classe Random est destinée à générer des nombres aléatoires, qui peuvent être utilisés dans Stardust pour randomiser les propriétés des particules. Par exemple, la classe UniformRandom est une sous-classe de la classe Random, et son nom dit tout: le nombre aléatoire généré par un objet UniformRandom est uniformément distribué, et j'utiliserai cette classe en particulier pour l'ensemble du tutoriel..

Zone

Il arrive parfois qu'un nombre aléatoire à une dimension ne soit pas suffisant. Parfois, nous avons besoin de nombres aléatoires à deux dimensions, qui sont essentiellement des paires de nombres aléatoires, pour des propriétés telles que la position et la vitesse. La classe Zone permet de générer des paires de nombres aléatoires à deux dimensions. Cette classe modélise une paire de nombres aléatoires comme un point aléatoire dans une zone 2D. Par exemple, CircleZone génère des paires de nombres aléatoires (x, y) à partir de points aléatoires dans une région circulaire. Les classes Random et Zone sont principalement utilisées par la classe Initializer, qui sera traitée plus tard. La classe Zone3D est l'homologue 3D de cette classe, pour les effets de particules 3D..

Émetteur

La classe Emitter est à la base de l’encapsulation de tous les éléments de bas niveau. Un émetteur initialise les particules nouvellement créées avant leur ajout dans la simulation, met à jour les propriétés des particules à chaque itération de la boucle principale et supprime les particules mortes de la simulation. La méthode Emitter.step () est ce que vous souhaitez invoquer de manière répétée afin de maintenir Stardust opérationnel..

L'horloge

La classe Clock détermine le taux de création de nouvelles particules pour les émetteurs. Un objet Emitter contient exactement une référence à un objet Clock. Au début de chaque appel à une méthode Emitter.step (), l'émetteur demande à l'objet horloge le nombre de nouvelles particules qu'il doit créer. Prenons la classe SteadyClock, par exemple, elle indique aux émetteurs de créer de nouvelles particules à une vitesse constante..

Initialiseur

Cette classe sert à initialiser des particules nouvellement créées. Un objet Initializer doit être ajouté à un émetteur pour fonctionner. Fondamentalement, une sous-classe Initializer initialise une seule propriété de particule. Par exemple, la classe d'initialisation de masse initialise la masse de nouvelles particules. Certains initialiseurs acceptent un objet aléatoire en tant que paramètre constructeur pour initialiser des particules avec des valeurs aléatoires. Le code suivant crée un initialiseur de Life qui initialise la vie des particules à des valeurs centrées de 50 avec une variation de 10, à savoir entre 40 et 60..

 nouvelle vie (nouvelle UniformRandom (50, 10));

action

Les objets d'action mettent à jour les propriétés des particules à chaque itération de la boucle principale (méthode Emiter.step ()). Par exemple, la classe d'action Move met à jour les positions des particules en fonction de la vélocité. Un objet Action doit être ajouté à un émetteur pour fonctionner..

Flux de travail Stustust général

Maintenant que vous savez comment les classes principales collaborent, voyons un flux de travail général pour Stardust..

Vous commencez par créer un émetteur. Utilisez la classe Emitter2D pour les effets de particules 2D et la classe Emitter3D pour les effets 3D.

 var emitter: Emitter = new Emitter2D ();

Pour spécifier le taux de création de particules, nous avons besoin d'une horloge. Cela peut être défini par la propriété Emitter.clock ou en transmettant une horloge comme premier paramètre au constructeur de l'émetteur..

 // approche de propriété emitter.clock = new SteadyClock (1); // approche constructeur var emitter: Emitter = new Emitter2D (new SteadyClock (1));

Ajouter des initialiseurs à l'émetteur via la méthode Emitter.addInitializer ().

 emitter.addInitializer (nouvelle vie (nouvelle UniformRandom (50, 10))); emitter.addInitializer (nouvelle échelle (nouvelle UniformRandom (1, 0.2)));

Ajouter des actions à l'émetteur via la méthode Emitter.addAction ().

 emitter.addAction (nouveau Move ()); emitter.addAction (new Spin ());

Créer un rendu et ajouter l'émetteur à celui-ci via la méthode Renderer.addEmitter ().

 Rendu var: Renderer = new DisplayObjectRenderer (conteneur); // "conteneur" est notre conteneur sprite renderer.addEmitter (emitter);

Enfin, appelez à plusieurs reprises la méthode Emitter.step () pour que la simulation de particules continue. Vous voudrez peut-être utiliser l'événement enter-frame ou un minuteur pour le faire. En un seul appel de la méthode Emitter.step (), l’horloge détermine le nombre de nouvelles particules à créer, ces nouvelles particules sont initialisées par des initialiseurs, toutes les particules sont mises à jour par des actions, les particules mortes sont supprimées et, enfin, le rendu est rendu. l'effet de particules.

 // approche de l'événement enter-frame addEventListener (Event.ENTER_FRAME, mainLoop); // approche timer timer.addEventListener (TimerEvent.TIMER, mainLoop); fonction mainLoop (e: Event): void emitter.step (); 

Bien. C'est à peu près tout pour l'amorce Stardust. Il est maintenant temps d'ouvrir Flash IDE et de vous salir les mains.

Étape 1: Créer un nouveau document Flash

Créez un nouveau document Flash avec une dimension de 640X400, une cadence de 60 images par seconde et un arrière-plan sombre. Ici, j'ai fait un fond dégradé bleu foncé. Soit dit en passant, Stardust fonctionne bien avec Flash Player 9 et 10; il est donc normal que vous utilisiez Flash CS3 ou CS4. Dans ce tutoriel, je vais utiliser Flash CS3..

Étape 2: dessiner une étoile

Nous créons un effet de particule avec des étoiles. Nous devons donc dessiner une étoile et la convertir en symbole, exporté au format ActionScript bien sûr. Ce symbole sera utilisé plus tard pour rendre notre effet de particules. Nommez le symbole et la classe exportée "Star".

Étape 3: Créer la classe de document

Créez une nouvelle classe de document et nommez-la StarParticles.

 package import flash.display.Sprite; Classe publique StarParticles étend Sprite fonction publique StarParticles () 

Étape 4: Étendre l’émetteur

Comme mentionné dans le flux de travail général, la première étape consiste à créer un émetteur. Et l'étape suivante consiste à ajouter des initialiseurs et des actions à l'émetteur. Bien que cela puisse être fait dans le constructeur de la classe document, il est fortement recommandé de le faire dans une sous-classe distincte de l'émetteur. Il est toujours préférable de séparer la conception du comportement des particules du programme principal; ce faisant, le code est beaucoup plus propre et plus facile à modifier à l'avenir, sans être mélangé avec le programme principal.

Nous allons créer un effet de particule 2D, de sorte que Emitter2D est la classe d'émetteur que nous allons étendre. Étendez la classe Emitter2D et nommez-la StarEmitter, car nous allons lui faire tirer les étoiles plus tard. Le constructeur de l'émetteur accepte un paramètre Clock. Nous allons donc déclarer un paramètre de constructeur pour lui transmettre une référence d'objet Clock au constructeur de la superclasse..

 package import idv.cjcat.stardust.twoD.emitters.Emitter2D; classe publique StarEmitter étend Emitter2D fonction publique StarEmitter (clock: Clock) // transmet l'objet clock au constructeur de la superclasse super (clock); 

Étape 5: Déclarez les constantes

Une meilleure approche pour créer une sous-classe d'émetteur consiste à déclarer les paramètres de particule sous forme de constantes statiques, regroupées à un seul endroit. Ainsi, si vous souhaitez modifier les paramètres, vous saurez toujours où trouver les déclarations. La signification de ces constantes sera expliquée plus tard quand elles seront utilisées.

 // durée de vie moyenne privée statique constante LIFE_AVG: Number = 30; // variation de la durée de vie private static const LIFE_VAR: Number = 10; // échelle moyenne privée statique privée SCALE_AVG: Number = 1; // variation d'échelle privée statique statique SCALE_VAR: Number = 0.4; // échelle de temps de croissance privé statique constant GROWING_TIME: Number = 5; // échelle rétrécissement temps privé privé statique const SHRINKING_TIME: Number = 10; // vitesse moyenne privée statique constante SPEED_AVG: Number = 10; // Variation de vitesse private static const SPEED_VAR: Number = 8; // moyenne oméga (vitesse angulaire) privée statique constante OMEGA_AVG: Number = 0; // Variante oméga privée statique statique statique OMEGA_VAR: Number = 5; // coefficient d'amortissement privé statique constant DAMPING: Number = 0.1;

Étape 6: Ajout d'initialiseurs

De quels initialiseurs avons-nous besoin pour créer notre effet de particules? Jetons un coup d'oeil à la liste ci-dessous:

  • DisplayObjectClass - Cet initialiseur affecte un objet d'affichage spécifié à chaque particule, qui sera utilisé par un DisplayObjectRenderer pour restituer les effets de particule. Le constructeur accepte une référence de classe à la classe d'objet d'affichage que nous souhaitons instancier; pour ce tutoriel, cette classe sera la classe Star (symbole) créée à l'étape 2.
  • La vie - Cet initialiseur attribue à chaque particule une valeur de vie aléatoire. Plus tard, nous ajouterons des actions à l'émetteur pour épuiser cette valeur de vie dans le temps et pour marquer une particule comme morte si sa valeur de vie atteint zéro. Un objet Random est transmis au constructeur, qui l'utilisera pour générer une valeur aléatoire pour la vie des particules. Dans la plupart des cas, la classe UniformRandom est pratique et suffisante. le premier paramètre du constructeur UniformRandom est la valeur centrale (ou moyenne) des nombres aléatoires générés, et le second est le rayon (ou la variation). Par exemple, un objet UniformRandom de centre 20 et de variante 5 génère des nombres aléatoires dans la plage [15, 25]. Ici, nous utilisons la constante LIFE_AVG pour la valeur centrale et LIFE_VAR pour le rayon..
  • Échelle - Comme l'initialiseur de vie, l'initialiseur d'échelle initialise l'échelle d'une particule sur une valeur aléatoire, déterminée par un objet aléatoire transmis au constructeur de l'initialiseur. Ici, nous utilisons la constante SCALE_AVG pour la valeur centrale et SCALE_VAR pour le rayon..
  • Position - Cet initialiseur assigne une particule à une position aléatoire. Contrairement aux initialiseurs Life et Scale, qui nécessitent uniquement des nombres aléatoires 1D, l'initialiseur de position nécessite des générateurs de paires de nombres aléatoires 2D. Comme décrit dans la section Responsabilités de la classe Stardust, la classe de zone est exactement destinée à cet usage. L'objet Zone transmis au constructeur de l'initialiseur est utilisé pour générer des paires de nombres aléatoires 2D, qui seront affectées aux particules en tant que vecteurs de position. Dans ce tutoriel, nous allons faire en sorte que les étoiles jaillissent d'un seul point situé au curseur de la souris. Nous allons donc utiliser une classe SinglePoint, qui est une sous-classe Zone. Pour ajuster dynamiquement les coordonnées de cet objet SinglePoint à partir de la classe de document, nous devons exposer une référence à cet objet ponctuel via une propriété publique. Voici à quoi sert la propriété "point".
  • Rapidité - Comme l’initialiseur de position, l’initialiseur de vélocité a besoin d’un objet Zone pour générer des paires de valeurs aléatoires 2D afin d’initialiser la vitesse des particules. Un vecteur 2D généré par l'objet Zone, qui est la coordonnée d'un point aléatoire de la zone, est attribué aux particules en tant que vitesses. Nous utilisons ici la classe LazySectorZone qui représente une région de secteur. Un secteur est une portion de cercle entourée de deux rayons et de deux angles. Pour la LazySectorZone, les deux angles sont 0 et 360 par défaut, ce qui représente un angle complet autour d'un cercle. Le premier paramètre constructeur de la classe LazySectorZone est la moyenne des deux rayons, et le second est la variation des rayons. Dans ce cas, la moyenne des deux rayons représente la vitesse moyenne et la variation des rayons représente la variation de la vitesse. Ici, nous utilisons la constante SPEED_AVG pour le premier paramètre et SPEED_VAR pour le second.
  • Rotation - L'initialiseur de rotation initialise l'angle de rotation d'une particule à une valeur aléatoire. Et comme certains des initialiseurs susmentionnés, le constructeur accepte un objet aléatoire pour générer une valeur aléatoire. Puisque nous aimerions avoir des particules avec des angles allant de 0 à 360 degrés, nous utiliserons 0 comme centre et 180 comme rayon de l'objet UniformRandom..
  • Oméga - Omega, comme dans la plupart des manuels de physique, signifie vitesse angulaire. Cela dit, l'objectif de cet initialiseur est clair: il initialise la vitesse angulaire d'une particule à une valeur aléatoire et la constante OMEGA_AVG est utilisée comme centre et OMEGA_VAR comme rayon de l'objet UniformRandom..

Et voici le code:

 point = new SinglePoint (); addInitializer (new DisplayObjectClass (Star)); addInitializer (nouvelle vie (nouvelle UniformRandom (LIFE_AVG, LIFE_VAR))); addInitializer (nouvelle échelle (nouvelle unité UniformRandom (SCALE_AVG, SCALE_VAR))); addInitializer (nouvelle position (point)); addInitializer (nouvelle Velocity (nouvelle LazySectorZone (SPEED_AVG, SPEED_VAR))); addInitializer (nouvelle rotation (nouvelle UniformRandom (0, 180))); addInitializer (nouvelle Omega (nouvelle UniformRandom (OMEGA_AVG, OMEGA_VAR)));

Étape 7: Ajout d'actions

D'accord, nous avons terminé avec les initialiseurs. Il est maintenant temps d'ajouter des actions à l'émetteur. Vous trouverez ci-dessous une liste d'actions dont nous avons besoin:

  • Âge - L'action Age diminue la valeur de vie d'une particule de 1 à chaque étape de l'émetteur.
  • DeathLife - Lorsque la valeur de vie d'une particule atteint zéro, cette action marque la particule comme morte et remplace sa propriété isDead de false par true. À la fin d'une étape d'émetteur, les particules mortes sont éliminées.
  • Bouge toi - Comme son nom l'indique, l'action Move met à jour la position des particules en fonction de leur vitesse..
  • Tourner - Semblable à l'action Déplacer, l'action Rotation met à jour l'angle de rotation d'une particule en fonction de sa valeur en oméga (vitesse angulaire)..
  • Amortissement - Cette action multiplie le mouvement d'une particule par un facteur compris dans l'intervalle [0, 1], simulant les effets d'amortissement et ralentissant progressivement la particule. Un facteur égal à un signifie aucun amortissement: les particules se déplacent librement comme s'il n'y avait aucun effet d'amortissement; un facteur de zéro signifie un amortissement total: toutes les particules ne peuvent pas bouger un peu. Ce facteur est déterminé par le "coefficient d'amortissement" à l'aide de cette formule: "facteur = 1 - (coefficient d'amortissement)". Le paramètre transmis au constructeur est le coefficient d'amortissement; Ici, nous voulons juste un peu d’amortissement, nous utilisons donc la valeur 0.1 pour le coefficient.
  • ScaleCurve - L'action ScaleCurve modifie l'échelle d'une particule en fonction de sa durée de vie. Il passe d'une échelle initiale à une échelle normale après la naissance et s'efface progressivement jusqu'à la mort. Bien entendu, une particule peut également avoir une valeur d'échelle initiale ou finale plus grande que l'échelle normale; cela dépend du choix personnel. Dans de nombreux cas, nous aimerions que les particules aient une valeur d'échelle initiale et finale égale à zéro, qui est la valeur par défaut. Le premier paramètre du constructeur représente le temps de croissance d'une particule et le second, le temps d'évanouissement; nous passons donc dans les constantes GROWING_TIME et SHRINKING_TIME en tant que premier et deuxième paramètre, respectivement. Le temps de croissance est 5, ce qui signifie qu'une particule passe de l'échelle zéro à l'échelle normale au cours de ses 5 premières unités de durée de vie; et le temps de rétrécissement est de 15, ce qui signifie qu'une particule se réduit à l'échelle zéro au cours des 15 dernières unités de la durée de vie. Notez que la transition est linéaire par défaut, mais vous pouvez utiliser n'importe quelle fonction d'accélération, en particulier les équations d'accélération créées par Robert Penner. Il y a une autre action similaire appelée AlphaCurve, qui fonctionne sur les valeurs alpha de la même manière.

C'est tout. Notre émetteur est fait. Voici le code de cet émetteur dans son intégralité, y compris les instructions d'importation nécessaires.

 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.Clock; 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.Damping; importer idv.cjcat.stardust.twoD.actions.Move; import idv.cjcat.stardust.twoD.actions.Spin; import idv.cjcat.stardust.twoD.emitters.Emitter2D; import idv.cjcat.stardust.twoD.initializers.DisplayObjectClass; import idv.cjcat.stardust.twoD.initializers.Omega; importer idv.cjcat.stardust.twoD.initializers.Position; import idv.cjcat.stardust.twoD.initializers.Rotation; importer idv.cjcat.stardust.twoD.initializers.Velocity; import idv.cjcat.stardust.twoD.zones.LazySectorZone; import idv.cjcat.stardust.twoD.zones.SinglePoint; Classe publique StarEmitter étend Emitter2D / ** * Constantes * / private static const LIFE_AVG: Number = 30; Const statique privée LIFE_VAR: Number = 10; Constante statique privée SCALE_AVG: Number = 1; Constante statique privée SCALE_VAR: Number = 0.4; Const statique privée GROWING_TIME: Number = 5; Const statique privée SHRINKING_TIME: Number = 10; Const statique privée SPEED_AVG: Number = 10; Constante statique privée SPEED_VAR: Number = 8; Constante statique privée OMEGA_AVG: Number = 0; Constante statique privée OMEGA_VAR: Number = 5; Constante statique privée DAMPING: Number = 0.1; public var point: SinglePoint; fonction publique StarEmitter (clock: Clock) super (clock); point = new SinglePoint (); // initializer addInitializer (new DisplayObjectClass (Star)); addInitializer (nouvelle vie (nouvelle UniformRandom (LIFE_AVG, LIFE_VAR))); addInitializer (nouvelle échelle (nouvelle unité UniformRandom (SCALE_AVG, SCALE_VAR))); addInitializer (nouvelle position (point)); addInitializer (nouvelle Velocity (nouvelle LazySectorZone (SPEED_AVG, SPEED_VAR))); addInitializer (nouvelle rotation (nouvelle UniformRandom (0, 180))); addInitializer (nouvelle Omega (nouvelle UniformRandom (OMEGA_AVG, OMEGA_VAR))); // actions addAction (new Age ()); addAction (new DeathLife ()); addAction (new Move ()); addAction (new Spin ()); addAction (nouvel amortissement (DAMPING)); addAction (nouvelle ScaleCurve (GROWING_TIME, SHRINKING_TIME)); 

Étape 8: Terminer la classe de document

Il est maintenant temps de revenir à la classe de document et de la terminer. Jetons un coup d'oeil aux tâches restantes.

  • Créer une instance de StarEmitter - Nous allons instancier la classe StarEmitter que nous venons de terminer.
  • Attribuer un objet Clock à l'émetteur - Nous voulons un taux d'émission de particules constant, nous allons donc utiliser la classe SteadyClock. Le paramètre transmis au constructeur de l'horloge est le taux d'émission ou, en d'autres termes, le nombre de nouvelles particules créées à chaque étape de l'émetteur. un taux fractionnaire de 0,5 signifie à chaque étape d'émetteur, il y a 50% de chance qu'une nouvelle particule soit créée et 50% de chance qu'aucune particule ne soit créée.
  • Créer un rendu - Pour visualiser l'effet de particules, nous aurons besoin d'un moteur de rendu. DisplayObjectRenderer doit être utilisé avec l'initialiseur DisplayObjectClass: l'initialiseur assigne un objet d'affichage à chaque particule et le rendu ajoute ces objets d'affichage à la liste d'affichage du conteneur, en les mettant à jour en permanence. De plus, n'oubliez pas d'ajouter l'émetteur au rendu.
  • Appelez la boucle principale à plusieurs reprises - Cette dernière étape permet à Stardust de rester opérationnel. Ici, nous allons utiliser l'événement enter-frame.
  • Vous trouverez ci-dessous le code complet de la classe de document, avec les instructions d'importation nécessaires..

 package import flash.display.Sprite; import flash.display.StageScaleMode; import flash.events.Event; import flash.geom.Rectangle; importer idv.cjcat.stardust.common.clocks.SteadyClock; import idv.cjcat.stardust.common.renderers.Renderer; importer idv.cjcat.stardust.twoD.renderers.DisplayObjectRenderer; Classe publique StarParticles étend Sprite private var emitter: StarEmitter; fonction publique StarParticles () // instancie l'émetteur StarEmitter = new StarEmitter (new SteadyClock (0.5)); // le conteneur sprite var conteneur: Sprite = new Sprite (); // le rendu qui rend l'effet de particules var renderer: Renderer = new DisplayObjectRenderer (conteneur); renderer.addEmitter (émetteur); // ajoute le conteneur à la liste d'affichage, au-dessus de l'arrière-plan addChildAt (conteneur, 1); // utilise l'événement enter-frame addEventListener (Event.ENTER_FRAME, mainLoop);  fonction privée mainLoop (e: Event): void // met à jour la position de SinglePoint à la position de la souris emitter.point.x = mouseX; emitter.point.y = mouseY; // appelle la boucle principale emitter.step (); 

Enfin, nous avons fini! Voyons maintenant le résultat. Appuyez sur CTRL + ENTRÉE dans Flash pour tester le film et vous verrez le résultat..


Variation 1: étoiles animées

Nous n'avons pas encore fini! Faisons encore quelques variations. Le premier utilise des clips animés pour nos particules.

Étape 9: Créer une animation sur la timeline

Cette première variante est assez simple, sans codage supplémentaire. C'est aussi simple que de créer une animation de scénario de base. Modifiez le symbole étoile dans Flash IDE, créez une autre image clé et modifiez la couleur de l'étoile dans cette image en rouge. Cela fait essentiellement clignoter les étoiles entre jaune et rouge. Vous voudrez peut-être insérer d'autres images vides entre elles, car une fréquence d'images de 60 images par seconde est trop rapide pour un clignotement de deux images..

Maintenant, testez le film et vérifiez le résultat. L'effet d'étoile clignotante a l'air caricatural; cela peut être utilisé pour des effets d'étourdissement classiques, ce qui est commun dans les dessins animés.


Variation 2: Ajuster l'échelle de temps dynamiquement

Comme je l'ai mentionné précédemment, l'une des fonctionnalités de Stardust est "l'échelle de temps de simulation ajustable", ce qui signifie que l'échelle de temps utilisée par Stardust pour la simulation de particules peut être ajustée de manière dynamique. Tout est fait en modifiant la propriété Emitter.stepTimeInterval, qui est 1 par défaut. L'extrait de code suiva