09-21-2002, 03:44 PM
|
#1
|
|
|
Tornado in Flash MX
Someone asked me how to make a tornado with Flash, a tornado with letters. So here it is: The Tornado Tutorial
1. What you need on the scene
A movie clip of a dot, any colour you like, with the instance name "dot".
A layer called code that will hold all the code (everything is contained in 1 frame).
2. The rotating motion
First we are going to focus on the rotating effect. You can find the piece of code on this site, in the open source section. Personally, I took it from there: actionscript-toolbox. After cleaning, you get this:
Code:
function rotate(){
this.angle+=anglespeed;
var a=Math.sin(this.angle)*this.radius;
var b=Math.cos(this.angle)*this.radius;
var scalar=perspective/(b+perspective);
this._x=a*scalar + centerx;
this._y=b*scalar/tilt+this.starty;
this._xscale=this._yscale=scalar*100;
}
3. Analyze that function
I won't explain how the function works just now. But I want you to notice that it refers to a certain number of variables that we have to define somewhere: - angle, inside the dot (because refered as this.angle)
- anglespeed, on the timeline
- radius, inside the dot
- perspective, in the timeline
- centerx, in the timeline
- tilt, in the timeline
- starty, in the dot
That's why you'll need to put this just before the function declaration:
Code:
dot.angle=0;
anglespeed = Math.PI/24;
dot.radius=50;
perspective = 300;
centerx=200;
tilt = 5;
dot.starty=200;
4. Let's make the dot move
Now all we have to do is make the dot move...
Code:
dot.onEnterFrame=rotate;
End of Part 1. To be continued...
pom 
__________________
Last smoke by Ilyas : yesterday at 11:45 PM.
|
|
|
09-21-2002, 03:47 PM
|
#2
|
|
|
The complete code and the source:
Code:
// General constants
anglespeed = Math.PI/24;
perspective = 300;
tilt = 5;
centerx=200;
// Dot variables
dot.angle=0;
dot.radius=50;
dot.starty=200;
// Function declaration
function rotate(){
this.angle+=anglespeed;
var a=Math.sin(this.angle)*this.radius;
var b=Math.cos(this.angle)*this.radius;
var scalar=perspective/(b+perspective);
this._x=a*scalar + centerx;
this._y=b*scalar/tilt+this.starty;
this._xscale=this._yscale=scalar*100;
}
// Make it move!
dot.onEnterFrame=rotate;
pom 
__________________
Last smoke by Ilyas : yesterday at 11:45 PM.
|
|
|
09-21-2002, 04:45 PM
|
#3
|
|
|
Part deux
OK, time for some duplication. Ready?
1. What we need to change
First of all, we will have to duplicate that dot of ours, and make them all move, so the last line of the previous code
Code:
dot.onEnterFrame=rotate;
should be included in a loop to make all the dots move.
Then the variables that depend on the dot that we declared first should be declared inside the loop because each duplicated dot has its own variables.
2. The code now
The variables declaration
Code:
anglespeed = Math.PI/24;
perspective = 300;
tilt = 5;
centerx=200;
maxClip=50;
I've just added a maxClip variable that will tell the total amount of dots that you want.
The function remains the same.
The loop that duplicates our dots
Code:
for (var i=0;i < maxClip;i++){
mc=dot.duplicateMovieClip("dot"+i,i);
mc.angle=0;
mc.radius=50;
mc.starty=5*i;
mc.onEnterFrame=rotate;
}
This is where we have to be good to have a good effect. If you don't understand that code, check the AS tricks section, most of it is explained there.
You can see here that all the duplicated clips have the same starting angle angle, the same radius radius, but a different starting point on the _y axis starty. Then we assign the rotate function to the duplicate.
3. Small improvement
If you test the code now, you'll see that the first dot is still visible. To solve that little problem, simply add this line at the bottom of the code: End of Part Deux. Everything OK?
pom 
__________________
Last smoke by Ilyas : yesterday at 11:45 PM.
|
|
|
09-21-2002, 04:46 PM
|
#4
|
|
|
Complete code and source:
Code:
// General constants
anglespeed = Math.PI/24;
perspective = 300;
tilt = 5;
centerx=200;
maxClip=50;
// Function declaration
function rotate(){
this.angle+=anglespeed;
var a=Math.sin(this.angle)*this.radius;
var b=Math.cos(this.angle)*this.radius;
var scalar=perspective/(b+perspective);
this._x=a*scalar + centerx;
this._y=b*scalar/tilt+this.starty;
this._xscale=this._yscale=scalar*100;
}
// Duplicate and make it move!
for (var i=0;i < maxClip;i++){
mc=dot.duplicateMovieClip("dot"+i,i);
mc.angle=0;
mc.radius=50;
mc.starty=5*i;
mc.onEnterFrame=rotate;
}
dot._visible=0;
pom 
__________________
Last smoke by Ilyas : yesterday at 11:45 PM.
|
|
|
09-21-2002, 05:16 PM
|
#5
|
|
|
Part Trois: With a Vengence
Time for us to make it look like a tornado...
The good thing now is that all we have to mess with is the last loop, by changing a little bit the variables we are using.
1. First thing
Increase the maxClip a bit. Something like 150-200. And define 2 new variables: It refers to the height of the tornado.
2. Messing with the variables
So first, we want to give our tornado the right shape. This means that the radius of the particles at the bottom is smaller than the one of the top of the tornado.
Change the for loop into this
Code:
for (var i=0;i < maxClip;i++){
mc=dot.duplicateMovieClip("dot"+i,i);
mc.angle=0;
mc.starty=2*i;
mc.radius=mc.starty/2;
mc.onEnterFrame=rotate;
}
Notice that the radius depends on the _y position, so you should define the radius AFTER the _y position... And I divided by 2 to make it look better. You can try with any number, or nothing at all.
You should now have something like a line the describing a circle, or something like that...
3. The tornado...
The problem is that all the dots are aligned. To solve that, all we have to do is to give the dots a random angle to start with
Code:
mc.angle=random(360);
I know, the tornado is upside down, but we'll solve that problem later
4. A bit of randomness
We are also going to position our dots randomly on the _y axis (the mc.starty variable).
Code:
mc.starty=random(maxHeight);
There's not really a big difference with the previous one, but randomness is always fun...
5. Upside Down
To flip it, just change one tiny thing
Code:
mc.radius=(maxHeight-mc.starty)/2;
You can also give a minimal radius
Code:
mc.radius=(maxHeight-mc.starty)/2+10;
That's it for Part Trois.
pom 
__________________
Last smoke by Ilyas : yesterday at 11:45 PM.
|
|
|
09-21-2002, 05:21 PM
|
#6
|
|
|
The complete code and source:
Code:
// General constants
anglespeed = Math.PI/24;
perspective = 300;
tilt = 5;
maxClip=150;
xcenter=200;
maxHeight=300;
// Function declaration
function rotate(){
this.angle+=anglespeed;
var a=Math.sin(this.angle)*this.radius;
var b=Math.cos(this.angle)*this.radius;
var scalar=perspective/(b+perspective);
this._x=a*scalar + xcenter;
this._y=b*scalar/tilt+this.starty;
this._xscale=this._yscale=scalar*100;
}
// Duplicate and make it move!
for (var i=0;i < maxClip;i++){
mc=dot.duplicateMovieClip("dot"+i,i);
mc.angle=random(360);
mc.starty=random(maxHeight);
mc.radius=(maxHeight-mc.starty)/2+10;
mc.onEnterFrame=rotate;
}
dot._visible=0;
pom 
__________________
Last smoke by Ilyas : yesterday at 11:45 PM.
|
|
|
09-21-2002, 05:39 PM
|
#7
|
|
|
Part Quatre!!
But where are the letters, will you ask me. Well, they're coming now...
1. The idea
We are going to change our dot movie clip into a movie clip containing an empty dynamic textbox, and when we duplicate our clip, we will assign a random letter to the textbox. Pretty simple on the paper
2. Setting up the clip
Edit the dot movie clip. Delete the dot graphic, and replace it with a dynamic textbox, large enough to contain a letter. Set the size to something like 16, choose a nice font, and a color that you will see (it depends on the color of your background...).
Give the textbox the instance name letter. Now go back to the main scene.
Finally, embed your font.
3. Assigning the letter to the clip
First we'll see how to make a tornado with nothing but "i" 's. The for loop becomes
Code:
for (var i=0;i < maxClip;i++){
mc=dot.duplicateMovieClip("dot"+i,i);
mc.letter.text="i";
mc.angle=random(360);
mc.starty=random(maxHeight);
mc.radius=(maxHeight-mc.starty)/2+10;
mc.onEnterFrame=rotate;
}
Pretty neat, hue?
4. Add a bit of randomness...
Now this is a trick I took from Thoriphes and his Cycling Letters tutorial. First you need to define another constant, as string that contains all the letters we can choose from
Code:
myLetters=new String ("abcdefghijklmnopqrstuvwxyz");
Then we need to change the line we've added in the loop
Code:
mc.letter.text=myLetters.charAt(random(myLetters.length-1));
It looks complicated but it's not. charAt returns the caracter of the considered string at the specified index. Our index is random(myLetter.length-1), that is to say a random number from the first to the last caracter of our String.
And that's it for the 4th part of this tutorial.
pom 
__________________
Last smoke by Ilyas : yesterday at 11:45 PM.
|
|
|
09-21-2002, 05:42 PM
|
#8
|
|
|
Complete code and source:
Code:
// General constants
anglespeed = Math.PI/24;
perspective = 300;
tilt = 5;
maxClip=150;
xcenter=200;
maxHeight=300;
myLetters=new String ("abcdefghijklmnopqrstuvwxyz");
// Function declaration
function rotate(){
this.angle+=anglespeed;
var a=Math.sin(this.angle)*this.radius;
var b=Math.cos(this.angle)*this.radius;
var scalar=perspective/(b+perspective);
this._x=a*scalar + xcenter;
this._y=b*scalar/tilt+this.starty;
this._xscale=this._yscale=scalar*100;
}
// Duplicate and make it move!
for (var i=0;i < maxClip;i++){
mc=dot.duplicateMovieClip("dot"+i,i);
mc.letter.text=myLetters.charAt(random(myLetters.length-1));
mc.angle=random(360);
mc.starty=random(maxHeight);
mc.radius=(maxHeight-mc.starty)/2+10;
mc.onEnterFrame=rotate;
}
dot._visible=0;
pom 
__________________
Last smoke by Ilyas : yesterday at 11:45 PM.
|
|
|
09-21-2002, 06:13 PM
|
#9
|
|
|
Well, I don't know what to add now. I just a few improvements, nothing very important: - The shape is not linear, but curved
- There are more particles at the top of the twister than at its bottom
Here's the code
Code:
// General constants
anglespeed = Math.PI/48;
perspective = 300;
tilt=5;
maxClip=120;
xcenter=200;
maxHeight=300;
myLetters=new String ("abcdefghijklmnopqrstuvwxyz");
// Function declaration
function rotate(){
this.angle+=anglespeed;
var a=Math.sin(this.angle)*this.radius;
var b=Math.cos(this.angle)*this.radius;
var scalar=perspective/(b+perspective);
this._x=a*scalar + xcenter;
this._y=b*scalar/tilt+this.starty;
this._xscale=this._yscale=scalar*100;
this._alpha=scalar*100;
}
// Duplicate and make it move!
for (var i=0;i < maxClip;i++){
mc=dot.duplicateMovieClip("dot"+i,i);
mc.letter.text=myLetters.charAt(random(myLetters.length-1));
mc.angle=random(360);
mc.starty=random(maxHeight)*Math.random()+50;
mc.radius=(maxHeight-mc.starty)*(maxHeight-mc.starty)/400+10;
mc.onEnterFrame=rotate;
}
dot._visible=0;
I hope you like the effect, and that you didn't have too many problems along the way.
pom 
__________________
Last smoke by Ilyas : yesterday at 11:45 PM.
|
|
|
09-22-2002, 09:06 PM
|
#10
|
|
|
Cool!
That tornado thingy is really cool... you should make it an official tutorial...
__________________
[swf="http://www.freewebs.com/scottgilmore/kirupa%20footer.swf height=60 width=300"][/swf]
<font color=639EB1>-</font><font color=3A6674>Scott</font>
|
|
|
09-23-2002, 03:38 AM
|
#12
|
|
|
Thanks! But the guy I did it for doesn't have MX
And yeah, I think the next step would be to make a real tutorial, but I don't have the courage to open my HTML editor...
pom 
__________________
Last smoke by Ilyas : yesterday at 11:45 PM.
|
|
|
09-23-2002, 04:44 AM
|
#15
|
|
|
Well, I use phpEdit... Which is probably why it's so painful  I don't know, I never liked HTML, I never trusted it. It is too easily obscurated and totally unreadable.
And no money for DreamWeaver I'm afraid
pom 
__________________
Last smoke by Ilyas : yesterday at 11:45 PM.
|
|
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -4. The time now is 04:29 PM.
|
|