Selteco.com > FlashDesignerZONE.com > Tutorials > T1034

Self-Animating Objects and Bezier Curves


by Alan Burkhart

Flash Designer has a ton of animation options, but there may be times when you need to move an object independently via ActionScript. This tutorial demonstrates a way to get that done and also provides a quick overview of Bezier curves. In the animation at right, there are four separate balls, each contained in a single-frame, 30x30 pixel Flash movie. Frame delay is set to .05 in each one. The balls are 26x26 and thus occupy the entire frame. Each "mini-movie" has a short ActionScript that facilitates movement by increasing (moving right/down) or decreasing (moving left/up) its x/y coordinates relative to the parent movie.

The parent (_root) .swf interacts with the balls and updates their internal scripts to keep them moving in the right direction. This is necessary since the values within the balls' script would otherwise reset to their default values every time the movies loop. There's a goodly amount of coding overall, but I promise it's simpler than it sounds.

Create the Parent Movie...

First, create a new .sfd and set the frame size to 310x300. It's important that the frame be rectangular, not square. Otherwise the balls could end up "trapped" repeating the same path over and over. Set the frame delay to "Stop". Add the following ActionScript to the frame:

dir= new Object();
//red ball
dir.horz1=-5;
dir.vert1=-5;

//green ball
dir.horz2=2;
dir.vert2=3;

//blue ball
dir.horz3=-7;
dir.vert3=7;

//yellow ball
dir.horz4=8;
dir.vert4=-8;

dir.grnx=grnball._x;
dir.grny=grnball._y;

dir.redx=redball._x;
dir.redy=redball._y;

dir.bluex=blueball._x;
dir.bluey=blueball._y;

dir.yelx=yelball._x;
dir.yely=yelball._y;

dir.drwmax=0; //maximum # of draws before clear

Save this file as "BouncingCurves" in .sfd format

About the script...
The "dir" (direction) object controls the speed and pixel increment of each ball. "horz" is horizontal movement. "vert" is vertical movement. A larger number moves the ball faster by advancing it more pixels each time. A positive value moves right or down. A negative value moves up or left. There is a separate horz/vert value set for each ball to keep them moving independently. It'd be a bit boring if they all moved together. The last property of the dir object is "drwmax". This allows you to decide how many lines are drawn before the box is cleared. A setting of zero keeps it at a constant single curved line for each ball. Increasing the value can have interesting effects. Click here to see the finished .swf with drwmax set at 55.

When the animation starts, the balls get their starting directions from the above script. Each time a ball gets its value from here, it calculates its next position, then sends that info back here. This way the balls and this script keep each other updated. All drawing is done by the red ball. The rest of them just bounce around and drag the curves. Each time a line is drawn, the drawing position is moved back to the green ball.

Creating the Balls...

Green Ball:
Create a new .sfd. Size the frame to 30x30 and set the frame delay to .05. Hold down the CTRL key and draw a circle from the top/left corner of the frame to the bottom/right. Set line width to "None". Keep the circle selected and click Item > Gradient Fill. Select "Radial". Set the inner color to "00FF00" and the outer color to "007F00". Set the Delta x & y values to -10. Click "OK".

Add the following script to the frame:
onEnterFrame=function(){
var hmax=279;
var vmax=269;

if (this._x>hmax) {_parent.dir.horz2=-2;}
if (this._x<0) {_parent.dir.horz2=2;}

if (this._y>vmax) {_parent.dir.vert2=-3;}
if (this._y<0) {_parent.dir.vert2=3;}
};

this._x=this._x+_parent.dir.horz2;
this._y=this._y+_parent.dir.vert2;

_root.dir.grnx=this._x;
_root.dir.grny=this._y;

Save the file as "grnball" in both .sfd and .swf format.

Blue Ball:
Create a new .sfd. Size the frame to 30x30 and set the frame delay to .05. Hold down the CTRL key and draw a circle from the top/left corner of the frame to the bottom/right. Set line width to "None". Keep the circle selected and click Item > Gradient Fill. Select "Radial". Set the inner color to "0000FF" and the outer color to "00007F". Set the Delta x & y values to -10. Click "OK".

Add the following script to the frame:
onEnterFrame=function(){
var Hmax=279;
var Vmax=269;

if (this._x>Hmax) {_parent.dir.horz3=-7;}
if (this._x<0) {_parent.dir.horz3=7;}

if (this._y>Vmax) {_parent.dir.vert3=-7;}
if (this._y<0) {_parent.dir.vert3=7;}
};

this._x=this._x+_parent.dir.horz3;
this._y=this._y+_parent.dir.vert3;

_root.dir.bluex=this._x;
_root.dir.bluey=this._y;
Save the file as "blueball" in both .sfd and .swf format.

Yellow Ball:
Create a new .sfd. Size the frame to 30x30 and set the frame delay to .05. Hold down the CTRL key and draw a circle from the top/left corner of the frame to the bottom/right. Set line width to "None". Keep the circle selected and click Item > Gradient Fill. Select "Radial". Set the inner color to "FFFF00" and the outer color to "A8A800". Set the Delta x & y values to -10. Click "OK".

Add the following script to the frame:
onEnterFrame=function(){
var Hmax=279;
var Vmax=269;

if (this._x>Hmax) {_parent.dir.horz4=-8;}
if (this._x<0) {_parent.dir.horz4=8;}

if (this._y>Vmax) {_parent.dir.vert4=-8;}
if (this._y<0) {_parent.dir.vert4=8;}
};

this._x=this._x+_parent.dir.horz4;
this._y=this._y+_parent.dir.vert4;

_root.dir.yelx=this._x;
_root.dir.yely=this._y;

Save the file as "yelball" in both .sfd and .swf format. Just one more ball!

Red Ball:
The red ball does all of the drawing and controls how many lines are drawn by communicating with the parent .swf.

Create a new .sfd. Size the frame to 30x30 and set the frame delay to .05. Hold down the CTRL key and draw a circle from the top/left corner of the frame to the bottom/right. Set line width to "None". Keep the circle selected and click Item > Gradient Fill. Select "Radial". Set the inner color to "FF0000" and the outer color to "920000". Set the Delta x & y values to -10. Click "OK".

Add the following script to the frame:
onEnterFrame=function(){
var Hmax=279;
var Vmax=269;
dr=_root.dir.drwmax;

if (this._x>Hmax) {_parent.dir.horz1=-8;}
if (this._x<0) {_parent.dir.horz1=8;}

if (this._y>Vmax) {_parent.dir.vert1=-8;}
if (this._y<0) {_parent.dir.vert1=8;}
};

this._x=this._x+_parent.dir.horz1;
this._y=this._y+_parent.dir.vert1;
_root.dir.redx=this._x;
_root.dir.redy=this._y;

//blue line
c=c+1;
if (C>dr){_root.clear();c=0;}
_root.lineStyle(1,0x0000ff);
_root.moveTo(_root.dir.grnx+15,_root.dir.grny+15);
_root.curveTo(this._x,this._y,_root.dir.bluex+15,_root.dir.bluey+15);

//yellow line
_root.lineStyle(1,0xffff00);
_root.moveTo(_root.dir.grnx+15,_root.dir.grny+15);
_root.curveTo(this._x,_root.dir.bluex,_root.dir.yelx+15,_root.dir.yely+15);

//red line
_root.lineStyle(1,0xff0000);
_root.moveTo(_root.dir.grnx+15,_root.dir.grny+15);
_root.curveTo(_root.dir.bluex,_root.dir.bluey,_root.dir.redx+15,_root.dir.redy+15);

Save the file as "redball" in both .sfd and .swf format.

Putting it all together...
Return to the parent .sfd. Click "Insert" > "SWF Clip". Insert redball.swf. Repeat this process for the other balls. Place them at random locations in the larger file. It's better if you don't place any of them in the center. Resave BouncingCurves.sfd.

How it works...
Note the first two variables in each ball script:
var Hmax=279;
var Vmax=269;

These tell the balls when they reach an edge of the parent so they can bounce back in the other direction. Hmax is calculated on the width of the parent minus the width of the ball graphic you drew inside the smaller swf's. This causes the ball to bounce when its right side reaches the edge of the parent. Vmax does the same thing based upon the height of the parent and the height of the ball. If you build your own bouncing graphics you'll need to adjust this value according to the width & height of the parent and the bouncing graphics within it.

The next code block is what actually moves the balls:
if (this._x>Hmax) {_parent.dir.horz4=-8;}
if (this._x<0) {_parent.dir.horz4=8;}

if (this._y>Vmax) {_parent.dir.vert4=-8;}
if (this._y<0) {_parent.dir.vert4=8;}
};

this._x=this._x+_parent.dir.horz4;
this._y=this._y+_parent.dir.vert4;

The first 4 lines check to see if the ball has reached the edge of the parent by checking its own _x and _y properties against Hmax and Vmax. If so, the script sends a message back to the parent to negate the value of its corresponding horz/vert values. This causes the ball to reverse direction. If the horz/vert values are positive, the ball moves right and down. If they're negative, the ball moves left and up. In the last two lines, the ball retrieves its updated values from the parent and moves accordingly.

In the red ball's code you'll notice the following code: dr=_root.dir.drwmax; in the third line. This gets the value for the number of lines to draw before clearing the box and assigns it to the variable "dr". The value comes from the "drwmax" property of the "dir" object in the parent. Farther down in the red ball's script is the following code:
c=c+1;
if (C>dr){_root.clear();c=0;}

Each time the ball movie loops, the variable "c" is incremented by 1. When c is greater than dr (the maximum number of lines to draw), "_root.clear()" wipes out all graphics drawn by ActionScript. Objects you draw or add yourself, like the balls, are not affected by this command.

The rest of the code draws the curving lines between the balls:

_root.lineStyle(1,0x0000ff);
_root.moveTo(_root.dir.grnx+15,_root.dir.grny+15);
_root.curveTo(this._x,this._y,_root.dir.bluex+15,_root.dir.bluey+15);

The first command above sets the line width and color. In this case, width is set to 1, and the hex code "0000ff" is bright blue. The "0x" that precedes the hex code tells ActionScript that it's about to receive a hexadecimal code (I'll give you an easy way to create hex colors in a moment). The next line of code moves the "drawing point" to the green ball's coordinates, from which in this case all of the curves originate. The "_root.dir.grnx value is the property in the parent's "dir" object that is updated as the ball moves. A value of 15 is added to it to move the origin point behind the ball. This is for the sake of appearance only. Trust me, it looks better this way. The value approximates half of the ball's width.

Drawing the lines and understanding Bezier Curves...
The code, "_root.curveTo(this._x,this._y,_root.dir.bluex+15,_root.dir.bluey+15);" draws the curve. In this case the curve is drawn from the green ball to the blue ball. The destination coordinates are also adjusted to move the end of the line behind the blue ball. If you're not familiar with Bezier Curves and how ActionScript uses them, here's a brief explanation:

In ActionScript, a Bezier Curve is drawn between two points with a "control point" that defines the direction and height/depth of the curve. In the example at right, you can drag the handles on each end of the curved line, or drag the red control point around to see how they interact. I didn't invest a lot of coding in this example... be sure to release the mouse INSIDE the box. Otherwise it'll behave improperly.

The first 2 values in the "curveTo" command set the control point (the red dot at right) for the curve. The next two values set the ending coordinates for the curve. In this case, the blue ball. This script uses different control points for the balls so the lines wave all around the box. This code draws a curve from the green ball to the blue ball using the coordinates of the red ball ("this") as the control point. You can mix-n-match the control points, even using the y value from one ball and the x value from another. The more variation, the more diverse the curves.

Each time you use a "curveTo" or "lineTo" command in ActionScript the next drawing point is set to the ending point of the previous draw. So, ActionScript would automatically draw from the blue ball's coordinates unless we reset with a "moveTo" command. This script resets the start position of each curve back to the green ball.

Lastly... I don't know of anyone who actually enjoys figuring out HEX codes for colors. Here's a link to a free online Flash-based color code generator that's easy to use. It'll create any color your computer can display with a few mouse clicks and give you the hex or rgb code, with the proper prefix for Flash (0x), CSS (#) or HTML (no prefix). Much easier than figuring it out on your own!

Download Flash Designer source projects: t1034.zip (17 kb)

Products | Purchase | Downloads | Support | Flash Tutorials | Contact
Copyright © 1999-2017 Selteco Software, Inc. www.selteco.com, ph: +1 810 377 5778