Flash (AS3) et particules : effets divers.

Posté par Axel dans Tutoriels | 20 juil 2009 à 15:06 0

Dans ce tutoriel nous allons voir comment créer des effets intéressants (réalistes ou fantastiques) avec la classe Particle.as développée il y a déjà un moment par Keith Peter.
Vous trouverez la version AS2 et la documentation de cette classe à cette adresse :
http://www.bit-101.com/Particles/

Par contre ce tutoriel se fera en AS3. Un portage par Eric Dolecki de la classe en AS3 est disponible ici :
http://www.christeso.com/index.php/lab/bit-101-particle-class-in-as3/

Téléchargez le fichier et dézippez le dans un dossier. Le zip contient un exemple d’utilisation de la classe que je n’ai personnellement pas réussi à ouvrir. Supprimez donc tous les fichiers sauf Particle.as qui est le seul qui nous intéresse.
Dans ce dossier, créez un nouveau fichier flash particules.fla en Actionscript 3. La classe Particle utilise une instance de la scène principale pour définir les limites du champ d’action des particules. Pour qu’elle puisse fonctionner, nous devons donc associer notre FLA à une classe de document.
Pour cela, faites Fichier=>Nouveau=>Fichier ActionScript et copiez-collez le code suivant:

package{
	import flash.display.MovieClip;
	import flash.display.Stage;
	public class Main extends MovieClip{
		static public var stage:Stage;
		public function Main():void{
			Main.stage = this.stage;
		}
	}
}

Sauvegardez ce fichier dans le dossier du FLA et nommez le “Main.as”. Dans particules.fla, cliquez dans le grisé en dehors de la scène (le carré blanc) dans l’espace de travail. Vous allez pouvoir alors modifier les propriétés de l’animation. Dans le champ de texte “Classe de document” tapez “Main” pour lui affecter la classe que l’on vient de créer. Cliquez sur le petit crayon juste a droite pour vérifier s’il ouvre bien le fichier Main.as
Toujours dans les propriétés de l’animation, changez la cadence à 60 images par secondes et mettez un arrière plan noir.

Nous allons commencer par faire tomber de la neige de façon assez réaliste et ce, avec seulement quelques lignes de codes.
Tout d’abord, créons un flocon. sur la scène : dessinez un cercle avec un fond blanc, sans contour et avec 3px de diamètre . Convertissez ce cercle en symbole en le sélectionnant et en appuyant sur F8.
Dans le fenêtre qui s’affiche, nommez le “flocon”, Type : “Clip” et alignement au centre.
Cliquez sur “Avancé” si le panneau avancé n’est pas ouvert.
Nous allons à présent faire de ce MovieClip une particule en l’étendant à la classe Particle. Cochez la case “Exporter pour ActionScript”. Nommez sa classe “Flocon” et donnez lui comme classe de base “Particle” … Enfin, cliquez sur OK !

Puisque nous avons une classe de document, nous devons piloter l’animation via cette classe. Ouvrez Main.as, et après la ligne Main.stage = this.stage; écrivez le code suivant :

var f:Flocon = new Flocon();
for( var i=0; i<100; i++ ){
	f = new Flocon();
	f.x = Math.random()*this.stage.stageWidth;
	f.y = Math.random()*this.stage.stageHeight;
	f.scaleX = f.scaleY = Math.random()*2
	this.addChild(f);
	f.grav = 0.1;
	f.wander = 0.5;
	f.edgeBehavior = "wrap";
}

Compilez votre animation (Ctrl+Entrée) et vous voila en décembre !

Une petite explication du code qui vous permettra à partir de ça d’obtenir d’autres effets :

for( var i=0; i<100; i++ ){
}

Tout ce qui se trouve entre les deux accolades sera répété 100 fois. Le code entre les accolades permettent la création d’une particule. Il y aura donc 100 particules à l’écran. Vous pouvez changer la valeur 100, mais attention trop de particules et votre ordinateur “ramera” !

var f:Flocon = new Flocon();
Crée en mémoire une nouvelle instance f de la classe Flocon, associée à notre MovieClip flocon.

f.x = Math.random()*this.stage.stageWidth;
f.y = Math.random()*this.stage.stageHeight;

Place la particule aléatoirement sur la scène sur l’axe x et l’axe y. “Math.random()” est une fonction qui retourne un nombre aléatoire compris entre 0 et 1. Multiplié par “this.stage.stageWidth” qui correspond à la largeur totale de votre scène, nous avons donc un nombre entre 0 et la largeur maximale.

f.scaleX = f.scaleY = Math.random()*2
Permet de changer la taille de chaque particule. scaleX et scaleY est le ratio (un chiffre compris entre 0 et 1) de sa taille de base (3px). “Math.random()” étant multiplié par 2, nous avons donc un ratio de taille allant de 0 a 2, soit de 0px à 6px de diamètre pour chaque particules.

this.addChild(f);
Ajoute la particule à la scène

f.grav
Est la valeur de la gravité de la particule, plus elle est élevée, plus la particule tombera vite.

f.wander
Est une valeur définissant le mouvement de secousse de la particule, mettez cette valeur à 0 et vos particules tomberons de manière droite.

f.edgeBehavior = "wrap";
Définit l’action de la particule lorsqu’elle sort de la scène. “wrap” signifie que la particule se téléporte de l’autre côté de la scène et continue son chemin, d’où le fait que la neige ne cesse jamais de tomber. Essayez “bounce”, qui fait rebondir la particule comme s’il y avait un sol et des murs ou “remove” qui efface tout simplement la particule à sa sortie (attention cette version de la classe est bugée à l’utilisation de cette fonction, voir à la fin pour corriger le bug)

Essayons en quelques clics de transformer cette neige en nuée de lucioles. Premièrement dans votre FLA, créez un nouveau symbole luciole, comme précédemment avec le flocon en remplissant “luciole” à la place de “flocon” et “Luciole” à la place de “Flocon”. Dans ce symbole, mettez-y un cercle de couleur verte ou jaune, avec un petit effet de flou ou rayonnement. Vous pouvez également travailler une image sur Photoshop et l’importer dans ce MovieClip.
Changez dans le code de Main.as, entre les 2 accolades de l’instruction “for”, par le code suivant:

var f:Luciole = new Luciole();
f.x = Math.random()*this.stage.stageWidth;
f.y = Math.random()*this.stage.stageHeight;
f.scaleX = f.scaleY = Math.random()*2
this.addChild(f);
f.grav = 0;
f.wander = 2;
f.edgeBehavior = "wrap";
f.repelMouse(true,1, 40);

Le résultat :


Pour obtenir cette animation, j’ai juste changé le paramètre “grav” et “wander” ainsi que la taille.
Vous noterez qu’en parcourant l’animation avec la souris, les lucioles s’éloignent du curseur. Ceci s’obtient grace à la methode repelMouse().
Dans la documentation on peux lire :

repelMouse(bRepel:Boolean [, force:Number, minDist:Number])
- causes the particle to spring away from the mouse
- arguments:
bRepels. if true, particle will spring away from the mouse. if false it won’t.
force. the strength of the spring action. generally numbers less than 1 are used. default is 0.1
minDist. the distance in pixels from the mouse that the particle will attempt maintain.
default is 100
- returns:
the index number of the point added (can be used to remove the point)

Le premier argument (entre les parenthèses) doit être “true” pour activer cette action.
Le deuxieme argument est la force à laquelle les particules sont rejetées.
Le troisième argument est la distance à laquelle le rejet prend effet (cela forme donc un cercle autour du curseur, comme une espèce de champ de force).

Essayons maintenant de faire quelque chose qui s’éloigne un peu de la réalité et créer un effet un peu plus “fantastique”. Nous allons réaliser un serpent lumineux qui suivra notre curseur.
Créez un nouveau symbole comme précédemment que vous nommerez “serpent” pour le clip et “Serpent” pour la classe, avec comme classe de base Particle. J’ai choisi de créer un carré au bord arrondis de couleur bleu, avec un léger dégradé radial.
Changez les instructions contenus entre les accolades de la boucle “for” par :

var f:Serpent = new Serpent();
f.x = Math.random()*this.stage.stageWidth;
f.y = Math.random()*this.stage.stageHeight;
f.scaleX = f.scaleY = i/100;
this.addChild(f);
f.grav = 0;
f.wander = 0;
f.edgeBehavior = "bounce";
f.springToMouse(true, (i/100) * 0.02);
f.turnToPath = true;

J’ai donc mis la gravité à 0, le wander à 0, et le edgeBehavior à “bounce” pour éviter que les particules ne sortent de l’écran. Pour d’autres effet intéressant, essayez de rajouter une gravité ou du wander.
Vous remarquerez l’ajout de la methode springToMouse() qui a pour effet d’attirer les particules vers la souris. Le premier argument “true” est nécessaire pour activer cette fonction, le second correspond à la force : i est le numéro de la particule (la première particule est 0, la derniere 99), on peux donc considérer que la force des particules est croissante allant de 0 à 0.02 selon l’ordre à laquelle elle sont créées. De même pour la taille grâce à la ligne f.scaleX = f.scaleY = (i+1)/100;
Le paramètre turnToPath indique que la particule doit s’orienter dans le sens de son mouvement.

Pour finir ce tutoriel, nous allons essayer de créer un feu d’artifice avec une interaction avec la souris.
Pour cela, nous avons besoin d’utiliser le edgeBehavior=”remove” pour que les particules sortent de l’écran et disparaissent de la scène et de la mémoire. Seulement, cette version de la classe semble bugguée à l’utilisation de cette fonction. Pour corriger le bug, dans le fichier Particle.as à la ligne 548, remplacez la ligne removeChild( this ); par:

__efClip.removeEventListener( Event.ENTER_FRAME, __efHandler );
parent.removeChild( this );

Après avoir sauvegarder le fichier, retournez dans votre FLA et créez un nouveau symbole vide appelé “feu”, avec comme nom de classe “Feu” et comme classe de base Particle. Nous remplirons ce symbole dynamiquement via le code.
Dans Main.as, effacez tout et copiez-collez le code suivant:

package{
	import flash.display.MovieClip;
	import flash.display.Graphics;
	import flash.display.Stage;
	import flash.filters.BlurFilter;
	import flash.events.MouseEvent;
	public class Main extends MovieClip{
		static public var stage:Stage;
		private var tabCouleur:Array =["0xff0000", "0x00ff00", "0x0000ff"];
		public function Main():void{
			Main.stage = this.stage;
			stage.addEventListener(MouseEvent.CLICK, boum);
		}
		private function boum(e:MouseEvent):void{
			var f:Feu;
			var numCouleur:int;
			for( var i=0; i&lt;100; i++ ){
				f = new Feu();
				f.x=mouseX;
				f.y=mouseY;
				numCouleur = Math.random()*tabCouleur.length;
				trace(tabCouleur[numCouleur]);
				f.graphics.beginFill(tabCouleur[numCouleur], 0.8);
				f.graphics.drawCircle(0, 0, 3);
				f.graphics.endFill();
				f.filters = [new BlurFilter(5,5)];
				f.grav=Math.random()+0.5;
				f.wander=0.5;
				f.edgeBehavior = "remove";
				f.addRepelPoint(f.x+(Math.random()*2-1), f.y+5, 20, 2);
				this.addChild(f);
			}
		}
	}
}

Vous pouvez lancer l’animation et cliquer sur la scène.

Si vous sentez des ralentissement à l’explosion c’est normal,  dites vous que 3 autres animations avec chacune 100 particules sont calculée sur cette page en même temps.

Une petite explication rapide sur le code : un écouteur d’événements sur le clic de la souris a été ajouté à la scène. A cet écouteur est associé une fonction qui va créer à l’emplacement de la souris 100 particules rondes. La couleur des particules est piochée aléatoirement dans un tableau “tabCouleur” (valeur de couleur en hexadécimal). Pour donner un effet d’explosion, un point de repoussement (addRepelPoint) à été ajouté juste en dessous de l’endroit où sont créés les particules, légèrement sur la gauche ou la droite (aléatoirement). Pour plus de réalisme, on y ajoute également un filtre de flou (BlurFilter), une gravité aléatoire (entre 0.5 et 1.5) et un wander à 0.5.

Partager:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google
  • BlinkList
  • blogmarks
  • De.lirio.us
  • Design Float
  • LinkedIn
  • Netvouz
  • StumbleUpon
  • Technorati

Pas de commentaires

pour “Flash (AS3) et particules : effets divers.”

Envoyer un commentaire

Vous devez être connecté pour envoyer un commentaire.