3D Flower in Flash - Flash Tutorials

Flash Tutorials

3D, Actionscripting, Animation, Special & Text Effects, Dynamic, Games, Basics, Interactivity, Math Physics and Web Design tutorials


Hello there flash users! In this tutorial, we will try to create a 3 Dimensional flower like this:


Now, let's list out the things we want to do:(This will be a good idea for any movie clip)

  • We want a 3D Flower rotating in a black background.
  • It should change it's color as it rotates.
  • It must rotate along with the mouse, i.e., it should respond to the mouse.
  • It must look real enough so that the user believes it is really a 3d flower.
Now, lets work out the logic, formulae, etc.

The Logic

Before you can even know the logic, you must understand a few points:
  1. Flash 5 has practically no capability to do anything in 3d space.
  2. Flash cannot also draw any lines or objects at runtime.
  3. Complex 3d objects can cause it to become a nightmare in slow machines(like mine, a PII 350).
Now that you have understood these facts, you can go and design a logic:
  1. You need to first specify the number of vertices an object is made up of, what points are connected and where they are located in 3 dimensional space.
  2. You need to then rotate the object virtually, i.e., you must rotate an object that does not even exist. You can do this using trignometrical formulae(No, they are the easiest part of the apple).
  3. Since Flash does not draw 3d, you must convert the 3D Points (with 3 co-ordinates x,y,z) to 2D Points(with 2 co-ordinates x & y). You can do this too by using simple formulae.(Now don't think that life's easy)
  4. Then you must draw lines or circles connecting the 2D vertices got from the previous step. You can do this by using a small movieclip with a 45 degree line and then duplicating it and positioning it.
  5. Then you must rotate this object every time the mouse moves.
We will do all the above one by one in the following steps.

Prepare the Stage

  1. Open Flash 5. Press Ctrl+N to create a new movie. Press Ctrl+M to open Movie Properties. Give Frame Rate to 21. Set movie width and height to 700 and 525 pixels respectively. Any size is acceptable, as long as you change some of the variables you will come across as required. Also, change the background of the movie clip to black or some other dark color. We want the flower to stand out from the background.

  2. Press F5 twice to make the movie three frames long. Click on the new layer icon thrice to create three new layers. Now name the layers as Miscellaneous, Scripts, Lines and vertices. Now, the time line should look like this:
  3. Now, we need to create a few movieclips. But don't worry: the majority of the work will be done in the ActionScript Window later. Press Ctrl+F8 to create a new symbol. Name it as 'Vertex' and give behavior as MovieClip.
  4. Now, Enter some text or anything. If it was text or some other movie clip, then press Ctrl+B to break it apart, or the alpha effects won't work. This is optional. You can even leave the movie clip empty. You just need the movieclip to hold some variables.
  5. Now go back to the main scene. Click on the vertices layer. Drag the vertex movie clip from the library window(If you don't see the Library, press Ctrl+L to see it) on to the stage. If you don't see the Instance Pane, press Ctrl+I to open the Instance Pane. In that, give the name of the Vertex movieclip instance as point.
  6. Press Ctrl+F8 to create a new movieclip named Line.
  7. Press O to select the Oval tool.
  8. Press the Click on the pencil button under the colors toolbar.
  9. Then click on the no-Color icon under the colors toolbar.
  10. Holding down the shift key, draw a circle.
  11. Press V to enable the Arrow tool. Click on the circle to select it.
  12. Click on Window - Panels - Transform to open the transform panel. Now, Click on the Skew Radio button and enter the two field's values as -40 and 35. The panel should look like this:
  13. Click outside the circle to deselect the skewed circle. Now select it again by clicking on it.
  14. If you donot see the info Panel, press Ctrl+Alt+I to invoke the info toolbar.
  15. Enter W and H values as 100. If you see an icon similar to in the panel, click on the white box in the top left of that icon to get this icon:
  16. Now enter X and Y values as 0 and 0.
  17. Your workspace should look something like below
  18. When done with the circle, click on the ' Scene 1' button on the top left above the timeline to go back to the Main Stage.
  19. Click on the Lines layer. Now drag the Line movieclip from the Library window onto the stage. Now, press Ctrl+I to invoke the Instances Panel. Now give the Line MovieClip instance the name 'wire'.
  20. Press F8 to create a new button. Give it any name you like.
  21. Hit F5 thrice and then draw a small box or circle around the plus sign.
  22. Go back to the main stage by clicking on the Scene 1 button on the top left.
  23. Click on the Miscellaneous layer and then drag the button movieclip onto the stage.
  24. Note:
    Make sure that all the three symbols are placed in the main stage outisde the viewable area. To do this,press Ctrl+2and drag the symbols to the grey area.


The Panel

  1. Now that the stage is all set, we can go on to the ActionScripting part. But first, click on the first frame of the Scripts layer and press F6 to create a keyframe. If you don't see the Actions window, Press Ctrl+Alt+A to invoke the actions panel.
  2. Most probably, you would end up with a panel like this:
  3. Now, press the Small arrow in between the two vertical panes to hide the left pane. If it is already hidden, leave this step.
  4. Now, press on the blank white space in the panel. Press Ctrl+E to shift to expert mode. This step is required only if you are in Normal mode, i.e., you cannot enter the script directly.
  5. Now, resize the Actions panel as large as you can. But make sure that you can see it fully. In a fully maximized Flash window at 800 X 600 Resolution, you can get this big:

The Variables

  1. Now, let's start with the scripting. We need to initialize certain variables and arrays. To the Java or C programmers, the first frame is like a constructor. It only runs once and has all the initializations and methods.
  2. First, we need to initialize two variables, points and lines. Points defines the number of points the our 3d Object is made up of. Lines defines the number of lines our object consist of. For our objects, the following lines would be neccessary:
    Points = 11;
    Lines = 10;
  3. Now, a variable named viewport defines the zooming component of the screen. An initial value of 500 would be likely.
    Viewport = 500;
  4. We will now declare a variable having a formula to convert degrees to radians. We will need this later.
    rad = (3.14*2)/360;
  5. We need two arrays to contain the properties of our object. One is the line array, containing the properties of the lines. Another is the vertex array, containing the properties of each vertex. So, enter the following lines:
    line = new Array(Lines);
    vertex = new Array(Points);
  6. Because this movie is just to show off the 3d capabilities of flash, viewing it fullscreen would be more beautiful. So, enter the following line:
    fscommand ("fullScreen", true);
  7. Next, we need to duplicate the line and the point movieclips. Enter the following lines to do it:
    for (i=0; i != Lines; i++) {
    wire.DuplicateMovieClip("l" add i, i);
    line[i] = eval("l" add i);
    }
    for (i=0; i != Points; i++) {
    point.DuplicateMovieClip("v" add i, (Lines*2)+i);
    vertex[i] = eval("v" add i);
    }
    Explanation: The 1st for loop loops and duplicates the line movieclip until the number movieclips is equal to the value specified in the Lines variable. The 2nd loop creates n duplicates of the wire movieclip where n denotes the value of the variable of points. You could see that in both the loops, there is an eval function which assigns each duplicated movieclip a slot in the array we created in Step 4. This makes it easier to refer to their properties and the variables contained in them later.

Plot the Points

    Here is a property in flash actionscript not everyone knows; As a matter of fact, even I learnt it just before making this movie. It goes like this: Because we have assigned a array slot to each movieclip, each array becomes like an object. Similar to java, we can have variables for each object, apart from their properties. That is, we can have 3 variables x,y and z for each array element to store the co-ordinates of each vertex. So let's put it to use. What we are going to do now is give each vertex its position in the 3 dimensional world. Because flash is not equipped to do this in any decent manner, we have a boring part of typing an awful lot of lines. We have to give the x,y,z co-ordinates for each vertex. In this tutorial, however, it is going to be easy as all you have to do is copy the following code and paste it in the action script window.


  1. Now, we need to give the location of all the vertices. So, just copy the following code into the actionscript window of Flash:
    vertex[0].x = 0;
    vertex[1].x = -100;
    vertex[2].x = -150;
    vertex[3].x = -150;
    vertex[4].x = 0;
    vertex[5].x = 100;
    vertex[6].x = 150;
    vertex[7].x = 100;
    vertex[8].x = 150;
    vertex[9].x = 0;
    vertex[10].y = 0;
    vertex[0].y = 0;
    vertex[1].y = -100;
    vertex[2].y = 0;
    vertex[3].y = 100;
    vertex[4].y = 150;
    vertex[5].y = 100;
    vertex[6].y = 0;
    vertex[7].y = -100;
    vertex[8].y = -150;
    vertex[9].y = 0;
    vertex[10].y = 0;
    vertex[0].z = 0;
    vertex[1].z = -100;
    vertex[2].z = 0;
    vertex[3].z = 100;
    vertex[4].z = 0;
    vertex[5].z = 100;
    vertex[6].z = 0;
    vertex[7].z = -100;
    vertex[8].z = 0;
    vertex[9].z = -150;
    vertex[10].z = 150;
    As you can see, the values and the number of lines itself will differ for each object and you have to experiment with this to get a rough idea of where a -100,-100,-100 point will lie after rendering. I can explain that to you, however, that will be beyond the scope of this tutorial. And the .x, .y, .z are mere variables which can be assigned to an object array.
  2. Remember when you were a kid and played those 'Join the Dots' games in the books? Well, you are going to do that again. This time, it will be in 3 dimensions. Here too, you will use the object array logic to store the variables. All you have to do is specify the two points to which each line is connected. So, we will need two variables a and b for each line. We will use the line array. Just copy the following code and paste it into the flash actionscript window:
    line[0].a = 0;
    line[0].b = 1;
    line[1].a = 0;
    line[1].b = 2;
    line[2].a = 0;
    line[2].b = 3;
    line[3].a = 0;
    line[3].b = 4;
    line[4].a = 0;
    line[4].b = 5;
    line[5].a = 0;
    line[5].b = 6;
    line[6].a = 0;
    line[6].b = 7;
    line[7].a = 0;
    line[7].b = 8;
    line[8].a = 0;
    line[8].b = 9;
    line[9].a = 0;
    line[9].b = 10;
    The values assigned to them might be confusing, but if you see, they will say the number of the vertex in the vertex array to which they are connected. For example, the line 'line[0].a=0' says that it is connected to the vertex contained in the vertex array at the location of 0. Now, if your imagination powers are excellent and you are good in math, you will see that all this means to describe a err... flower like object.

Be sure that all the scripts mentioned in this page and all other previous pages are all placed in order in the first frame's actions. Also, place the upcoming scripts in the first frame itself, until or otherwise, specified.

A little this way

Note:
If you find that any of the following has something common with the 'Advanced Math' Professor from the College you studied in, it is purely incidental.

But actually, it has something that you might remember studying in High School. It's actually the trignometrical formulae you will use to rotate the vertices "virtually" and then project it on to the screen.

The Logic:
Now we have to workout the logic; You might say that "but we did that a long time ago!", but then, you read the note above: It's just as confusing as Advanced Math. You just can't understand it by reading it. So, let's go.

First, let's note that, we can rotate only one axis at a time. So, we need 3 sets of 3 variables for each vertex to rotate it along all the axes. We will then apply the formula, to rotate it on the x axis. We will store the rotated values in a new set of 3 variables. We will then apply the formula to rotate it on the y axis on the newly created set of 3 variables. We will then store the result in the next set of 3 variables. We will repeat it for the z axis rotation.

Now read the above paragraph again and again until you get it right.

Now, an important point: Although you can use the formula to rotate the object using just degree measure, Flash can calculate sine and cos values only with radian measure. So, you need to convert the degree to radian before you can use the sine and cos functions.

After rotating the object, we need to apply some formula to convert the x,y,z co-ordinates to just x,y co-ordinates, that is, convert the 3d address to a 2d address. That too will be done induvidually for each axes using formulae and the result is stored in two new variables.

After converting the object to 2d, we will have to draw the lines and vertices. We will use a for loop for doing this. We will adjust the _x,_y,_xscale,_yscale and _alpha properties of each movieclip to do this.

We will use three methods, each one for rotating, projecting and rendering the object.

We will do this next.

The Rotation

Now just copy and paste the following code into the first frame's actionscript window:

function Rotate (x, y, z) {
radx = rad*x;
rady = rad*y;
radz = rad*z;
for (i=0; i != Points; i++) {
vertex[i].x1 = vertex[i].x;
vertex[i].y1 = (Math.cos(radx)*vertex[i].y)-(Math.sin(radx)*vertex[i].z);
vertex[i].z1 = (Math.sin(radx)*vertex[i].y)+(Math.cos(radx)*vertex[i].z);
vertex[i].x2 = (Math.cos(rady)*vertex[i].x1)-(Math.sin(rady)*vertex[i].z1);
vertex[i].y2 = vertex[i].y1;
vertex[i].z2 = (Math.sin(rady)*vertex[i].x1)+(Math.cos(rady)*vertex[i].z1);
vertex[i].x3 = (Math.cos(radz)*vertex[i].x2)-(Math.sin(radz)*vertex[i].y2);
vertex[i].y3 = (Math.sin(radz)*vertex[i].x2)+(Math.cos(radz)*vertex[i].y2);
vertex[i].z3 = vertex[i].z2;
}
}

Now don't think that it is too difficult, we will break it down.

  1. First, the parameters of the Rotate function recieve the number of degrees to be rotated in each axis.
  2. The next 3 lines assign the radx,rady and radz variables the 'converted to radian' values of x, y and z variables. If you have poor memory, let me remind you that the rad variable you multiply with the x,y and z variables is actually a formula used to convert degrees to radians. We declared this variable in the first itself.
  3. Next a for loop loops n number of times where n denotes the value of the points variable.
  4. Inside the for loop, the formula for rotating the vertex in each axis is executed. Explaining each line would end up only in pages of explanation. So, try to figure it out all by yourself.

3d to 2d

Now that the object rotation script is over, we need to convert it to 2d. This is relatively simple. Just a few lines. Copy the following lines of code to the action script window:

function toScreen () {
for (i=0; i != Points; i++) {
vertex[i].dx = (vertex[i].x3*viewport)/(vertex[i].z3+600)+350;
vertex[i].dy = (vertex[i].y3*viewport)/(vertex[i].z3+600)+262.5;
}
}

Not much to explain here: A for loop similar to the previous one. Two formulae are applied to the vertices and then stored in two new variables.

One thing to be noted, however, is that the constants at the end of the two formulae- 350 and 262.5 are actually half the values of the height and width values of the movieclip. If you are changing the size of the movieclip, you will have to change this values accordingly.

Rendering it

The last thing left to do is render the object. This will get a little complex, though. But just one function will do.

Copy and paste the following code into the actionscript window:

function render () {
for (i=0; i != lines; i++) {
with (line[i]) {
_visible = true;
_x = vertex[line[i].a].dx;
_y = vertex[line[i].a].dy;
_xscale = vertex[line[i].b].dx-vertex[line[i].a].dx;
_yscale = vertex[line[i].b].dy-vertex[line[i].a].dy;
}
}
for (i=0; i != points; i++) {
with (vertex[i]) {
_x = dx;
_y = dy;
_xscale = 75+(((((500-z3[i])/10)*30)/100)*(-1));
_yscale = 75+(((((500-z3[i])/10)*30)/100)*(-1));
_alpha = ((((z3[i]*(-1))+500)/10));
}
}

Explanation:

Two For loops, one for drawing the lines and other for drawing the vertices are given. In the first loop, we change the x, y, xscale and yscale values of each line movieclip. Next, in the second loop, we change the x and y co-ordinates of the vertex movieclips. The xscale, yscale and alpha properties are adjusted so that they add more 'depth' realism to the scene. They are just some formulae created by me.

The TouchUps

Now that the methods are all done, there is very little coding to be done.

  1. First, we need some variables that will change every time the frame is loaded. You will know what each of them does in the upcoming steps. Copy the following line and add it to the first frame's actionscript:
    var ax, ay, az, oldx, oldy, bx, by, bz, nu;
  2. Now, if you can't see the timeline, press the Tab key once to hide all panels.
  3. Select the 2nd frame of the Scripts layer by clicking on it.
  4. Press Tab key again to see the actions panel.
  5. Copy the following code and paste it into the 2nd frame's actionscripts:
    rotx = (oldy-_ymouse)/2;
    roty = (oldx-_xmouse)/2;
    oldx = _xmouse;
    oldy = _ymouse;
    ax += rotx;
    ay += roty;
    ay += by;
    ax += bx;
    az += bz;
    bx = 0;
    by = 0;
    bz = 0;
    rotate(ax, ay, az);
    ax++;
    ay++;
    az++;
    if (ax>360) {
    ax -= 360;
    }
    if (ay>360) {
    ay -= 360;
    }
    if (az>360) {
    az -= 360;
    }
    toScreen();
    render();
    The first four lines tell that the mouse has moved this much and so, add some values accordingly to the ax and ay variables. The next six lines will be explained later. Next, we call the rotate function to rotate the objects as per the ax, ay and az variables. Next, we increment the three variables by one. This is done to insure that the object keeps rotating even if the mouse is not moving.

    Because the mouse moves only in 2 dimensions, we cannot get the z rotation values from the mouse movement itself. So, we just increment the z rotation value automatically.

    Now the next 3 if functions make sure that the ax, ay and az variables don't cross 360 degrees.

    Then, the toScreen() and render() methods to do the rest.

  6. Then press Tab key to hide the panels. Click on the third frame in the Scripts layer. Press Tab key again to see the panels. Now just add one line of code to the script:
    goToAndPlay(2);
    This makes sure that the movie loops again and again within the two frames and does not enter the first frame once again.

The majority of the work is done. If you want, press Ctrl+Enter to check if all this has paid off. But wait! There is still some to go!

The Final touch

Now just two more steps to go.

  1. If you cannot see the stage, press Tab key to hide all the panels. Now, select the button you once dragged on to the stage. Scroll through the stage to find it. After it has been selected, press Ctrl+Alt+A to open the ActionScript window. Copy and paste the following code into it:
    on (keyPress "") {
    by = 2;
    }
    on (keyPress "") {
    by = -2;
    }
    on (keyPress "") {
    bx = 2;
    }
    on (keyPress "") {
    bx = -2;
    }
    on (keyPress "a") {
    bz = 2;
    }
    on (keyPress "z") {
    bz = -2;
    }
    on (keyPress "'") {
    Viewport += 5;
    }
    on (keyPress "/") {
    Viewport -= 5;
    }
    These just add more interactivity to the movie. Now, the user can rotate the object in any axis and also zoom in or out of it. By press in up or down keys, the user is giving a positive or negative value to the bx variable. Remember that this variable also affects rotation.

    Similarly, pressing the left and right keys rotates the object in y axis.

    Since there is no way of controlling the z axis, pressing the a and z keys rotates it on the z axis.

    The Next 2 events increment or decrement the Viewport variable. This variable is used to convert the 3d objects to 2d objects. This variable determines how close to the screen the point of origin is. So, by pressing the apostrohe(') and the slash(/) keys, you literally zoom in and out of the object.

There is one more small thing left to do. If you don't see the Library window, press Ctrl+L to invoke it. Now open the Line movieclip and select the "fat-line" like thing. If you don't see the Mixer panel, go to Window - Panels - Mixer to see the mixer panel. Now, change the alpha value of the circle to 83%.

If you want, you can give a color tween to the line movieclip so that it changes color as it moves.

Now that's it. Project Complete. Publish or save the file and view it in the standalone player.

Comments and suggestions welcome.

Download the files used in this tutorial. Download (51 kb)

0 comments

Post a Comment

Subscribe to: Post Comments (Atom)