Lighting is a class that dynamically draws a lightning strike. The input fields act like the Photoshop palettes. Meaning once you select an input field you can use the up/down arrows to increment/decrement the value. Holding the shift-key down will increase/decrease faster. Values less than 10 change by .1 / 1 whereas values greater than 10 increment by 1 / 10. See it yourself right here. Here's a short animation of how the lighting is created.

You can download a zip file with all the source files you’ll need to look over the code. I would appreciate an email if you would like to use this on your site. The Lightning class file is extensively commented. Enjoy.

Here's a basic walkthrough of how the Lightning class works:

You probably want to use a onMouseDown to initiat the class so use the code below in your FLA.

onMouseDown = function():Void {
var bolt:MovieClip = _root.createEmptyMovieClip("bolt", 0);
// custom settings go below here

var strike:Lightning = new Lightning(bolt);
}

Inside the onMouseDown function you want to create an empty MovieClip that the Lightning can be drawn on. It also insures that the properties get erased from instance to instance since the bolt MovieClip is always created at the same depth the previous incarnation will be wipped out, with it's properties, every time you click.

A MovieClip is all you need to pass to the class constructor. However there are 34 essential properties that determine things like the colors, effects, where the strike starts and ends, ect. The good news is that if you don't pass these properties then the class will set them to defaults.

If you would like to change a setting then add code like this after creating the emptyMovieClip:

bolt.durationTime = 1000;

That's all it takes to create lightning as you like it.

How the Lighting class works.

Now lets walk through how the Lightning class goes about its business.

Lightning()

The class construtor is the first function to run when creating a new instance of the Lightning class. First it calls the setDefaults() method which runs through all the settings. Any settings that are undefined - haven't been set - are given defaults. Now the makeLightning() method is called which, guess what, makes lightning.

makeLightning()

The makeLighting() method gets called from the class constructor and also every time a branch is created. With that in mind the first thing it does is check to see if we are on the main branch because it gets treated slightly differently. There are two main things that get done for the main branch that don't need to be done for the branches. That's to create the blur and glow filters for our effects. It also takes care of how the lightning will fade out.

The last thing the makeLightning method does is call the getTerm() method.

getTerm()

You may be thinking at this point, "When are we actually going to draw something on the stage." First we have to do some math to figure out where to do the drawing.

The xDist/yDist are simply getting the distances from where we are - cloudX/cloudY - to the point we need to get to - groundX/groundY.

The midTermX/Y variables are a point that is a fraction of that remaining distance.

The following if statement is extremely important. This is where we determin if we are close enough to the groundX/Y to just go directly there. Without this statement we would be in an infinite loop.

Supposing that we haven't reached the ground we have have two more steps here. We have found a point that is between the cloudX/Y point and the groundX/Y but lightning that travels in a straight line would be boring. We need to introduce some randomness and this is where it happens.

var rndAngle:Number = Math.random() * 2 * Math.PI;
var rndDelta:Number = Math.random() * clip.termDelta;

clip.termX = clip.midTermX + ( rndDelta * Math.cos(rndAngle) );
clip.termY = clip.midTermY + ( rndDelta * Math.sin(rndAngle) );

All that does is move us in a random direction and a random distance from that point we found between the cloud and ground.

Now we do a little randomness to determine if we want to create a branch here. If so then we call the makeBranch() method. All that the makeBranch() does is create a new MovieClip in the current one, apply some settings, and then call the makeLightning() method again.

Finally, it's time to call the drawStrike() method and use the drawing API to put some pixels on the screen. After that method runs we come back here and notice the last thing in the method is a call to getTerm(). But we're in getTerm() already. We have gone though all the steps to make some lightning. Now it's time to do it again, and again, and again with some recursion. Remember, one of the things that the getTerm() method does is check to see if we are close enough to our end point to end. So it's safe to recurse because eventually it will break itself. (Okay, in practice I ran into numerous infinte loops and locked up my PC more times that I care to remember.)

drawStrike()

This is where we pull out the drawing API and make some pixels. After drawing the current lightning segment we reset where the cloudX/Y to where we just finished drawing to.

What do you think?