package { // FLASH CLASSES IMPORT import flash.events.*; import flash.display.*; import flash.utils.*; // TWEENER IMPORT import caurina.transitions.Tweener; [SWF(backgroundColor="#000000", frameRate=30)] public class Rain extends MovieClip { private var nXDif:Number; // x offset based on angle and length private var nYDif:Number; // y offset based on angle and length private var iRotDegrees:int; // angle to rotate rain clip private var nRotRadians:Number; // same angle in radians (calculated based on iRotDegrees); private var iRotVariance:int; // number of randomness offset angle (degrees) to apply to general angle or raindrops. 10 will go +5 or -5 either way private var iLen:int // length the rain is going to travel private var iTime:int; // call rainTimerHandler every iTime milliseconds... private var iDrops:int; // new drops to add each time Rain timer is called private var iDropLengthMin:int; // min size of rain private var iDropLengthRnd:int; // random length of new rain drops to add on to min size private var iDropStroke:int; // stroke width of rain drop private var iDropColor:uint; // color of rain stroke private var iDropAlpha:int; // alpha of drop stroke - 0 to 1 private var iYOffSetStart:int; // start new rain drops this y offset so they come on private var iYOffSetRnd:int; // start new rain drops this y offset so they come on private var nSpeed:Number; // speed in seconds rain takes to fall distance private var nSpeedVariance:Number; // speed variance - will go +1 or -1 either way.... private var __displayList:Array; // timer private var tRainTimer:Timer; // Construct function Rain() { initVars(); addEventListener(Event.ADDED_TO_STAGE, attach); } private function initVars() : void { __displayList = new Array(); // in case we want to make a list of all rain objects and loop through and remove when kill function is called. iRotDegrees = 100; nRotRadians = iRotDegrees * Math.PI/180; iRotVariance = 10; iLen = 1400; iTime = 15; iDrops = 12; iDropLengthMin = 5; iDropLengthRnd = 50; iDropStroke = 1.5; iDropColor = 0xcccccc; iDropAlpha = 1; iYOffSetStart = -50; iYOffSetRnd = 100; nSpeed = 1.5; nSpeedVariance = 1.5; } private function attach(e:Event) : void { trace("Rain Added"); removeEventListener(Event.ADDED_TO_STAGE, attach); // timer tRainTimer = new Timer(iTime, 0); // this means the a new drop is added every (iTime) milliseconds approximately tRainTimer.addEventListener(TimerEvent.TIMER, rainTimerHandler); //rainDelayStart(); // just start the rain and have running constantly for this demo tRainTimer.start(); } // ======================================================================== // PUBLIC & PRIVATE METHODS // this method is used for making the rain start and stop periodically rather than running constantly private function rainDelayStart() : void { var nStartDelay:Number = Math.random() * 25000; var nDuration:Number = 5000 + (Math.random() * 35000); setTimeout(function():void{tRainTimer.start();}, nStartDelay); setTimeout(function():void{ tRainTimer.stop(); rainDelayStart();}, nStartDelay + nDuration); } private function addRain() : void { var tRotDegrees:Number = iRotDegrees + (Math.random() * iRotVariance) - iRotVariance/2; // angle to rotate rain clip var tRotRadians:Number = tRotDegrees * Math.PI/180; // same angle in radians (calculated based on iRotDegrees); // create new blank sprite to draw into var sRain:Sprite = new Sprite(); // lineStyle(width, color, alpha, hinting); sRain.graphics.lineStyle(iDropStroke, iDropColor, iDropAlpha, false); sRain.graphics.moveTo(0,0); // draw rain line - random x from 0 to 100 pixels long, y at zero - based on this being rotation of zero which is horizontal facing right sRain.graphics.lineTo(iDropLengthMin + (Math.random() * iDropLengthRnd), 0); // add rain anywhere between - stage width (stage left minus the width again) and + stage width (stage right) sRain.x = stage.stageWidth/2 + ((Math.random() * (stage.stageWidth * 2)) - stage.stageWidth); sRain.y = iYOffSetStart + (Math.random() * iYOffSetRnd); sRain.rotation = tRotDegrees; // add to root (or container if you have one) addChild(sRain); // calc the offset based on the angle and distance to travel nXDif = iLen * Math.cos( tRotRadians ); nYDif = iLen * Math.sin( tRotRadians ); // move it! Tweener.addTween(sRain, {alpha:0, x:sRain.x + nXDif, y:sRain.y + nYDif, time:nSpeed + ((Math.random() * nSpeedVariance) - nSpeedVariance/2), transition:"Linear", onComplete:function():void{ // delete this at end of tween and remove from memory removeChild(this); }}); } // ======================================================================== // EVENTS private function rainTimerHandler (e:TimerEvent) : void { // each time the timer is called - you can add as many drops as you want. this example adds 3 new drops; for (var iDrop:int = 0; iDrop < iDrops; iDrop++) { addRain(); } } public function kill() : void { tRainTimer.stop(); tRainTimer.removeEventListener(TimerEvent.TIMER, rainTimerHandler); } // ======================================================================== // GETTER & SETTER } } Rain Particle Generator