Ready for the storm
How bout a little perlinNoise, Drawing API, and GlowFilter for ya? eh? I started playing with the BitmapData.perlinNoise method and came up with some moving clouds. From there, I added some rain and the lighting which my "northern lights" experiment was based on. After that, I figured I'd make the wind appear to gust by modifying the angle of the rain. Hope you enjoy it!
Actionscript:
-
import flash.filters.GlowFilter;
-
import flash.display.BitmapData;
-
import flash.geom.Point;
-
-
//create the clouds
-
var cloudBmData:BitmapData = new BitmapData(300, 225, false, 0);
-
var clouds:MovieClip = this.createEmptyMovieClip("clouds", this.getNextHighestDepth());
-
clouds.attachBitmap(cloudBmData, this.getNextHighestDepth());
-
var cloudPoint:Point = new Point();
-
var randomSeed:Number = random(15);
-
-
//function to move the clouds (cloudPoint.x controls the speed)
-
function moveClouds(){
-
cloudPoint.x -= 0.3;
-
cloudBmData.perlinNoise(300, 225, 6, randomSeed, false, true, 1, true, cloudPoint);
-
};
-
var moveNow:Number = setInterval(moveClouds,10);
-
-
//set up the GlowFilter for the lightning
-
var color:Number = 0xffffff;
-
var alpha:Number = 1;
-
var blurX:Number = 40;
-
var blurY:Number = 40;
-
var strength:Number = 10;
-
var quality:Number = 3;
-
var inner:Boolean = false;
-
var knockout:Boolean = false;
-
var gFilter:GlowFilter = new GlowFilter(color, alpha, blurX, blurY, strength, quality, inner, knockout);
-
-
//create a MovieClip to hold the lightning
-
var ltng:MovieClip = this.createEmptyMovieClip("ltng", this.getNextHighestDepth());
-
-
//function to "create" lightning
-
function lightning(startX,startY,endX,endY,theJag){
-
ltng.lineStyle(0,0xffffff);
-
if(theJag <1){
-
ltng.moveTo(startX,startY);
-
ltng.lineTo(endX,endY);
-
}else{
-
var midx:Number = (startX+endX)/2;
-
var midy:Number = (startY+endY)/2;
-
midx += (Math.random()-.5)*theJag;
-
midy += (Math.random()-.5)*theJag;
-
var branch:Number = random(500);
-
if(branch>495){
-
//create a "branch" from the lightning strike
-
lightning(midx,midy,endX+random(50)+50,endY+random(20)+20,30);
-
};
-
lightning(startX,startY,midx,midy,theJag/2);
-
lightning(endX,endY,midx,midy,theJag/2);
-
};
-
};
-
-
//function to draw lighting
-
function strikeIt(){
-
clearInterval(lightNow);
-
if(nextPoint <lPoints.length){
-
ltng.moveTo(lPoints[nextPoint][0],lPoints[nextPoint][1]);
-
ltng.lineTo(lPoints[nextPoint][2],lPoints[nextPoint][3]);
-
nextPoint++;
-
}else{
-
clearInterval(drawStrike);
-
nextPoint = 1;
-
var goNow:Number = setInterval(lightIt,100);
-
};
-
};
-
-
//function to make/get length of lightning and choose to put it behind or in front of the clouds
-
function lightIt(){
-
ltng.clear();
-
var strike:Number = random(500);
-
//if strike is greater than 460, create a lightning strike
-
if(strike>460){
-
var startX:Number = random(Stage.width);
-
var startY:Number = random(50);
-
var endX:Number = random(Stage.width);
-
var endY:Number = random(Stage.height)+100;
-
if(endY-startY<230){
-
//behind the clouds
-
gFilter.blurX = 80;
-
gFilter.blurY = 80;
-
gFilter.knockout = true;
-
gFilter.strength = 7;
-
//change the angle of the rain to give the look of wind
-
angle = random(50);
-
}else{
-
//in front of the clouds
-
gFilter.blurX = 40;
-
gFilter.blurY = 40;
-
gFilter.knockout = false;
-
gFilter.strength = 5;
-
};
-
ltng.filters = [gFilter,blur];
-
var lPoints:Array = new Array();
-
lPoints.push([startX,startY]);
-
lightning(startX,startY,endX,endY,80);
-
};
-
};
-
-
var lightNow:Number = setInterval(lightIt,50);
-
-
//create one rain drop
-
var rain:MovieClip = this.createEmptyMovieClip("rain",this.getNextHighestDepth());
-
rain.lineStyle(1,0xffffff);
-
rain.moveTo(0,0);
-
rain.lineTo(0,-20);
-
var angle:Number = random(50);
-
-
//loop thru to create more drops
-
for(var r=0;r<60;r++){
-
duplicateMovieClip("rain","rain"+r,this.getNextHighestDepth());
-
var moreRain:MovieClip = this["rain"+r];
-
moreRain._x = random(500)-200;
-
moreRain._alpha = random(10)+5;
-
moreRain._yscale = random(50)+100;
-
moreRain.speed = random(50)+40;
-
moreRain._rotation = -angle;
-
//onEnterFrame applied to each drop to make it fall and reset to the top of the screen
-
moreRain.onEnterFrame = function(){
-
if(this._y<225){
-
this._rotation = -angle;
-
this._y += this.speed;
-
this._x += angle;
-
}else{
-
this._y = 0;
-
this._x = random(500)-200;
-
this._alpha = random(10)+5;
-
};
-
};
-
};
August 31st, 2006 at 3:16 pm
I was wondering if you had a tutorial on how to do this. I am currenlty working on an image with a storm in the background. I want to make it seem as thought the storm is approching.
Thanks,
Chris
August 31st, 2006 at 3:20 pm
Sure thing Chris! I’m finishing up some projects at work right now, but I’ll get the code for this up before the day is out. Hope that’s not too late for ya.
September 13th, 2006 at 10:47 am
Nice effect, Jason! Long time troller, first time commenter. Love the blog and widget. Also, thanks for posting this project.
I like the first Chris’s idea of having the storm in the background. I haven’t been working with Flash that long and have been struggling with getting the ActionScript to run in the background. I tried putting the foreground in a higher layer, embedding the AS in a movieclip in the lower layer, and even using a mask. Any suggestions? Thanks!
September 13th, 2006 at 10:55 pm
Hey Chris. Thanks! I’ll try a few things out when I get home from Flashforward but just off the top of my head, you might try directly setting the depths of the clouds and stuff to a low number instead of using getNextHighestDepth(). Or you might try creating the storm first and then setting the depth of the objects in the foreground with getNextHighestDepth(). Again tho, I’ll mess around with it when I get home.
September 14th, 2006 at 8:18 am
Thanks Jason! I’ll try those suggestions. Flashforward sounded great this year. It’s awesome that you got to attend. I’m hoping they’ll host it in Atlanta or Orlando next time so I can attend. For now I appreciate your list of winners and the podcasts Flashforward made.
September 15th, 2006 at 12:53 pm
Hey Another Chris. I just tried out placing the code inside a MovieClip instance which I had on the bottom layer in the timeline and it put the storm behind the stuff in the foreground. Take a look at this zip file and let me know if we’re talking about the same thing.
June 2nd, 2007 at 2:46 am
Jason,
I want to tell you this is an awesome script! I would like to know if you will allow me to use it? I’m gonna need to make some modifications but all in all its a workable solution for me. Please let me know as soon as you can. Thanks and keep up the great work!
V/r
Gus C.
June 2nd, 2007 at 8:22 am
Hi Gus. I don’t mind at all if you use this script. Thanks so much for having the courtesy to ask first and let me know if you have any questions about it.