// forked from seniorcreative's Rain Particle Generator
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 = 100;
iDropLengthMin = 5;
iDropLengthRnd = 50;
iDropStroke = 1.5;
iDropColor = 0xcccccc;
iDropAlpha = 1;
iYOffSetStart = -50;
iYOffSetRnd = 100;
nSpeed = 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
}
}