forked from: flash on 2009-10-26

by pepea28
♥0 | Line 263 | Modified 2009-10-26 22:11:11 | MIT License
play

ActionScript3 source code

/**
 * Copyright pepea28 ( http://wonderfl.net/user/pepea28 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/1bxr
 */

// forked from pepea's flash on 2009-10-26
package {
	import caurina.transitions.Tweener;
    import flash.display.Sprite;
	import flash.display.Shape;
	import flash.events.*;
	import flash.utils.Timer;
	import flash.ui.Keyboard;	
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
	
	[SWF(width="500", height="500", backgroundColor="#000000", frameRate=30)]
    public class Main extends Sprite
	{
		private var stop_emit_mc:Sprite;
		private var container:Sprite;
		
        public function Main()
		{
			const PI:Number = 3.14;
			
            // construction des movieclip nécessaires
			
			container = new Sprite();
			container.x = stage.stageWidth/2;
			container.y = stage.stageHeight/2;
			addChild(container);
			
			// le bouton pour l'anim des jets
			stop_emit_mc = new Sprite();
			var rectangle:Shape = new Shape();
			rectangle.graphics.beginFill(0xFFFFFF);
			rectangle.graphics.drawRect(-15, -15, 30, 30);
			stop_emit_mc.addChild(rectangle);
			stop_emit_mc.x = stage.stageWidth/2;
			stop_emit_mc.y = stage.stageHeight/2+150;
			addChild(stop_emit_mc);
			
			// un texte explicatif en haut
			 var format:TextFormat = new TextFormat();
            format.font = "Verdana";
            format.color = 0xFFFFFF;
            format.size = 14;
			
			var tf:TextField = new TextField();
			
			tf.autoSize = TextFieldAutoSize.CENTER;
			tf.y = 15;
			tf.x = stage.stageWidth/2 - tf.width/2;
			tf.defaultTextFormat = format;
			tf.text = "You can use LEFT and RIGHT Arrows";
			addChild(tf);
			
			stop_emit_mc.buttonMode = true;

			var tab:Array = new Array();
			var directionTab:Array = new Array();

			// on crée plein d'émetteurs
			for (var i:uint = 0; i < 20; i++)
			{
				var e:Emetteur = new Emetteur();

				e.x = -180+i*20;
				e.y = 0;
				//e.setDirection( ((((6*PI)/4)*i)/(20))+(-3*PI)/4 );
				e.setDirection( ((PI* i)/40)  - ((3*PI)/4) );
				//e.setDirection( (-(1*PI)/4) );
				e.startEmit();
				tab.push(e);
				directionTab.push(e.getDirection());
				container.addChild(e);
			}

			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyHandler);
			stop_emit_mc.addEventListener(MouseEvent.CLICK, ola);
			this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);

			var timer:Timer = new Timer(1200, 0);
			//timer.addEventListener(TimerEvent.TIMER, timerHandler);
			//timer.start();

			/* -- fonctions -- */
			function keyHandler(e:KeyboardEvent):void
			{
				var i:uint;
				var newDir:Number;
				if (e.keyCode == Keyboard.LEFT)
				{
					// parcours du tableau et changement de l'angle
					for (i = 0; i < tab.length; i++)
					{
						newDir = Emetteur(tab[i]).getDirection()-0.05;
						Emetteur(tab[i]).setDirection(newDir);
						directionTab[i] = newDir;
					}
					
				} else if (e.keyCode == Keyboard.RIGHT) {
					// parcours du tableau et changement de l'angle
					for (i = 0; i < tab.length; i++)
					{
						newDir = Emetteur(tab[i]).getDirection()+0.05;
						Emetteur(tab[i]).setDirection(newDir);
						directionTab[i] = newDir;
					}
				}
			}

			function toggleEmit(evt:MouseEvent):void
			{
				if (!e.isEmitting())
				{
					// parcours du tableau 
					for (i = 0; i < tab.length; i++)
					{
						Emetteur(tab[i]).startEmit();
					}
				} else {
					// parcours du tableau 
					for (i = 0; i < tab.length; i++)
					{
						Emetteur(tab[i]).stopEmit();
					}
				}
			}

			/* -- gère le enter frame -- */
			function enterFrameHandler(e:Event):void
			{
				// on calcule l'affichage pour chaque emetteur
				// parcours du tableau 
				for (i = 0; i < tab.length; i++)
				{
					Emetteur(tab[i]).emittingHandler(null);
				}
			}

			/* -- gère le timer -- */
			function timerHandler(e:TimerEvent):void
			{
				timer.removeEventListener(TimerEvent.TIMER, timerHandler);
				toggleEmit(null);
				timer.stop();
				timer.reset();
				timer = new Timer(Math.random() * 1500,0);
				timer.addEventListener(TimerEvent.TIMER, timerHandler);
				timer.start();
				
				/*/
				var newDir:Number = Math.random() * 5;
				// parcours du tableau et changement de l'angle
				for (var i:uint = 0; i < tab.length; i++)
				{
					Emetteur(tab[i]).setDirection(newDir+i*0.2);
				}
				//*/
			}

			/* joue avec les direction de emetteurs */
			function ola(e:Event):void
			{
				for (var i:uint = 0; i < tab.length; i++)
				{
					Tweener.addTween( Emetteur(tab[i]),{
						time:0.5,
						transition:"linear",
						direction : i < tab.length/2 ? 0 : -PI,
						delay :  Math.abs(tab.length/2 - i)*0.10,
						onComplete: 
							function(emet:Emetteur, dir:Number):void
							{
								Tweener.addTween( emet,{
									time:0.5,
									transition:"linear",
									direction : dir,
									delay:0.5
								});
							},
						onCompleteParams:[Emetteur(tab[i]), ((PI* i)/40)  - ((3*PI)/4)]
					});
				}
			}   
        }
    }
	
}
	/*  |||||||||||||||| -- Classes -- |||||||||||||||| */
	
	/* ----> Emetteur */
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.events.Event;
	import flash.utils.Timer;
    import flash.events.TimerEvent;
	import flash.geom.Point;
	
	/**
	 * Classe représentant un émetteur de particules
	 */
	class Emetteur extends MovieClip
	{

		public const PI:Number = 3.14;

		private var graviteP:Number = 0.025;			// gravité appliquée aux particules
		private var particules:Array; 				// ensemble de particules que gère à un temps donné l'émetteur courant
		private var directionParticules:Array;		// ensemble des directions pour chaque particule du tableau précédent
		private var forceEmetteurs:Array;			// force pour le particule courant (peut etre légèrement différent de la forceEmetteur de base)
		
		private var intervalleTemps:Number = 30;	// intervalle de temps entre deux émissions (en millisecondes)
		private var _direction:Number = (-3*PI)/4; 	// indique l'angle principal d'émission de particules
		private var intervalleAngle:Number = 0.05;	// indique l'angle de précision de l'émission de particules
		private var nombreParticules:Number;		// nombre de particules émis à chaque émission (chaque intervalle de temps)
		private var forceEmetteur:Number = 2.5;		// force de l'émetteur
		private var gravite:Number;					// gravité appliqué aux particules émises par l'émetteur
		private var timer:Timer;					// timer pour calculer l'intervalle entre deux émissions

		private var XInfLimite:Number = -250;
		private var XSupLimite:Number = 250;
		private var YInfLimite:Number = -250;
		private var YSupLimite:Number = 10;
		//private var temps:Number = 0;


		/* Constructeur de la classe Emetteur */
		public function Emetteur():void
		{
			/*/
			var rectangle:Shape = new Shape();
			rectangle.graphics.beginFill(0x0000FF);
			rectangle.graphics.drawRect(5, 5, 100, 30);
			this.addChild(rectangle);
			//*/
			particules = new Array();
			directionParticules = new Array();
			forceEmetteurs = new Array();
			
			// on ajoute le listener sur le Enter Frame pour pouvoir gérer l'animation
			//this.addEventListener(Event.ENTER_FRAME, emittingHandler);

			timer = new Timer(intervalleTemps,0);
			timer.addEventListener(TimerEvent.TIMER, timerHandler);
			
		}

		public function set direction(n:Number):void
		{
			_direction = n;
		}
		public function get direction():Number
		{
			return _direction;
		}
		/**
		 * Débute l'émission
		 */
		public function startEmit():void
		{
			timer.start(); // on démarre le timer
		}

		/**
		 * Stoppe l'émission de particules
		 */
		public function stopEmit():void
		{
			timer.stop();
			timer.reset();
		}

		/**
		 * Stoppe l'émission de particules et efface toutes les particules qui étaient présentes
		 */
		public function clearEmetteur():void
		{

		}

		public function isEmitting():Boolean
		{
			return timer.running;
		}

		public function getDirection():Number
		{
			return direction;
		}

		public function setDirection(dir:Number):void
		{
			direction = dir;
		}

		/**
		 * Gère l'émission et l'animation des particules
		 */
		public function emittingHandler(e:Event):void
		{
			// on parcourt toutes les particules et on calcule leur position
			// avant de les afficher
			var i:uint = 0;
			while (i < particules.length)
			{					
				var xmoinsun:Number = particules[i].x;
				var ymoinsun:Number = particules[i].y;
				
				var p:Point = new Point(particules[i].x, particules[i].y);
				p = localToGlobal(p);
				
				particules[i].x += Math.cos(directionParticules[i])*forceEmetteurs[i];
				particules[i].y += Math.sin(directionParticules[i])*forceEmetteurs[i] + particules[i].temps*particules[i].temps*graviteP;
				particules[i].temps += 0.15;
				particules[i].alpha -= 0.010;
				
				/*/
				if (p.y < -1.25*p.x+510 && p.y < 155 && p.x > 275)
				{
					particules[i].y -= 0;
					particules[i].x += 3;
				} else if (p.y < 1.25*p.x-175 && p.y < 155 && p.x <= 275)
				{
					//particules[i].y = ymoinsun;
					//particules[i].x -= 3;
					particules[i].y -= 0;
					particules[i].x -= 3;
				}
				//*/
				
				//directionParticules[i] = (Math.tan( (particules[i].y-ymoinsun)/(particules[i].x-xmoinsun) ));
				
				particules[i].rotation = toDeg((Math.atan( (particules[i].y-ymoinsun)/(particules[i].x-xmoinsun) )));//directionParticules[i];
					
				//particules[i].x = forceEmetteur*5.05*Math.cos(direction)*temps;
				//particules[i].y = -( (-1.5/2)*(temps*temps)+forceEmetteur*5.05*Math.sin(direction)*temps );
				// on regarde si la particule ne sort pas de l'écran
				// si tel est le cas : on la dégage !
				if (particules[i].x > XSupLimite 		|| particules[i].y > YSupLimite
				 || particules[i].x < XInfLimite 	   	|| particules[i].y < YInfLimite
				 || particules[i].alpha <= 0.01)
				{
					this.removeChild(particules[i]);
					particules.splice(i,1); 			// on DELETE : -> on recrée forcément une particule
					directionParticules.splice(i,1); 	// on supprime également dans le tableau de directions pour pas perturber l'ordre
					forceEmetteurs.splice(i, 1);
				}
				i++;
			}
			//temps++;
		}

		/**
		 * Gère la création des particules toutes les intervalleTemps millisecondes
		 */
		private function timerHandler(e:TimerEvent):void
		{
			// on va créer un particule
			var p:Particule = new Particule();
			p.x = 0;
			p.y = 0;
			p.rotation = toDeg(direction);
			particules.push(p);
			directionParticules.push(direction+Math.random()*intervalleAngle*2);
			forceEmetteurs.push(forceEmetteur+Math.random()*0.5);
			addChild(p);
		}

		private function toRad(deg:Number):Number
		{
			return  PI*(deg)/180;
		}

		private function toDeg(rad:Number):Number
		{
			return 180*(rad) /PI;
		}

	}
	
	/* ----> Particules */
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.filters.BlurFilter;

	class Particule extends MovieClip
	{

		public var temps:Number = 0;
		
		public function Particule():void
		{
			var rectangle:Shape = new Shape();
			rectangle.graphics.beginFill(0xFFFFFF);
			rectangle.graphics.drawEllipse(-4.5, -2, 9, 4);
			
			//var blur:BlurFilter = new BlurFilter(2, 2, 3);
			
			//rectangle.filters = [blur];
			rectangle.alpha = 1;
			this.addChild(rectangle);
		}

	}