By Rodney Smith
 
Rodney Smith
Modified
4 December 2009
 

 
Requirements

Prerequisite knowledge
You should have a basic understanding of the Adobe Flash authoring interface, working with symbols, and mouse interaction. An awareness of 3D is useful too; you should be familiar with the topics discussed in Mariko Ogawa's article, Exploring the new 3D features in Flash. Links to more information about 3D in Flash are included at the end of this tutorial.
 
User level
Beginning
 
Required products
Adobe Animate CC
 
Additional Requirements
Flash Player 10 or later
 
This tutorial shows how to use the three-dimensional features of Adobe Flash Player 10 and Adobe Flash CS4 Professional using ActionScript 3, and how to apply them to make a user-controlled 3D animation.
 
The new 3D support in Flash Player 10 does a lot of the 3D work for you, and is integrated to work like the 2D properties. Since these 3D properties are similar to their 2D counterparts, adding 3D features and effects to games and animations may feel familiar to you, even if the mental and visual model is not.
 
In this 3D tutorial, I show you how to create a string of stars moving in 3D and how to get them to respond in 3D to user input, as shown in Figure 1 (click to play the animation; adjust the sliders to see the effect).
 

 
Creating the Stage and stars

The 3D features in Flash Player 10 enable you to set 3D attributes and let Flash Player do the rest of the calculations for you. This allows you to add 3D to games or SWF content without the amount of math calculations previously needed. This tutorial will manipulate stars in ActionScript, but first you need to create the Stage and put the graphic assets into the Library:
 
1. Create a new movie and give the Stage a size of 600 × 320, with the background set to black (see Figure 2).
 
Figure 2. Setting the Stage size and background color
Figure 2. Setting the Stage size and background color
2. Create three sliders in the top-left corner of the Stage: Open the Components window (select Window > Components) and drag the Slider component to the Stage. Repeat twice to make three sliders in all, and give them instance names of angleSpeedSlider, zSpeedSlider, and radiusSlider, each with a label (see Figure 3).
 
Figure 3. The user controls: slider components and their text box titles
Figure 3. The user controls: slider components and their text box titles
3. Create a star on the Stage using the PolyStar tool: Click and hold the Rectangle Tool and then select the PolyStar tool on the submenu. Choose Options under the Tool Settings and set the Style to star, Number of Sides to 5, and Star point size to 0.48 (see Figure 4) to get it to appear as a star constructed of straight lines from point to point.
 
Figure 4. Setting the options on the PolyStar tool
Figure 4. Setting the options on the PolyStar tool
4. Set the Stroke to 2 pt White and the Fill to Blue. While drawing, hold the Shift key while rotating the star to force it to be aligned horizontally. When you're done, set the Width to 150.
 
5. Convert the object to a MovieClip symbol (select Modify > Convert to Symbol), enter the name Star, and place the registration point in the center (see Figure 5). Select the Export for ActionScript option (if it's not visible, select the Advanced button to see the check box). Ignore the warning, if displayed, about not finding a definition for this class. Let Flash use the one that's automatically generated.
 
Figure 5. Converting to a Symbol and exporting for use in ActionScript
Figure 5. Converting to a Symbol and exporting for use in ActionScript
6. Delete the star from the Stage. You will use ActionScript to add the stars to the Stage.
 
7. Add a Play/Pause button to start and stop the star movement. From the Components panel, drag a PlayPauseButton component to the lower left. In Property inspector, set its Instance Name to playpause. In my example, I set x to 3, y to 282, and width and height to 34.
 

 
Manipulating in 3D with ActionScript

Now that the assets are available in the Library, you will use ActionScript to place them on the Stage and then move them towards the viewer:
 
1. Type the following in the Actions panel of the first frame:
 
//The number of stars to show
const NUMBER_OF_STARS:int = 14;

//Visible distance up from the bottom for the top-most star
//(all have the same y value)
const ORIGINAL_YBORDER:Number = 35;

//The z distance between the stars (an arbitrary setting)
const ZDISTANCE:int = 215;

//The initial Z position of the first star, so the top star is at z=0
const INITIAL_STAR_DEPTH:Number = 2795;

//Z value for when a star goes out of view (found visually)
const MINIMUM_STAR_DEPTH:Number = -221;

//Timer delay in milliseconds. 30 ms equals about 33.3 frames per second.
const MYTIMERFREQUENCY:Number = 30;

// The speed of the stars toward the user
var zSpeed:Number = 15;

//Create an array that will contain all the stars
var stars:Array = new Array();

//These variables declared outside of loops for performance reasons:
//Star depth local variable
var starDepth:Number = INITIAL_STAR_DEPTH;

//Local variable for operating on stars
var currentStar:Star;

//The default vanishing point is set at the center of the stage. For
//this demo, we'll move it closer to the top, so we can "look down" on
//the stars.
root.transform.perspectiveProjection.projectionCenter =
new Point(stage.stageWidth / 2, stage.stageHeight / 8);

//Star creation loop
//Create and position the stars, starting with the farthest one
for (var i:int=0; i < NUMBER_OF_STARS; i++)
{
//Create a new star
currentStar = new Star();

//x and y coordinates are the same for all stars: middle of the
//stage, a little up from the bottom.
currentStar.x = (stage.stageWidth/2);
currentStar.y = stage.stageHeight - ORIGINAL_YBORDER;

//Set the depth, or z-value, representing how far away the box is
//from the viewer
currentStar.z = starDepth;

//Set the object alpha so that stars further away appear fainter
currentStar.alpha = Math.min(1.0, 0.25 +
((INITIAL_STAR_DEPTH - starDepth) /

(INITIAL_STAR_DEPTH - MINIMUM_STAR_DEPTH) * 0.8));
//Add star to the array
stars.push(currentStar);

//Add star to the stage
addChild(currentStar);

//Update the starting depth for the next star, which will be closer
starDepth -= ZDISTANCE;
}
You should have something showing a trail of stars leading off into the horizon, as shown in Figure 1 at the beginning of the article.
 
2. To add motion, you will use a Timer to cause the stars to move at regular intervals. Alternatively, you could use the ENTER_FRAME event, but this way you can adjust the frame rate of the clip and the animation will behave the same. Each time the timer goes off, the stars are moved closer to the viewer. Add the timer creation and timer handler code at the bottom of the Actions panel using this code:
 
//Create a timer to go off every 30 ms, which equals about about 33.3 frames per second.
var actionTimer=new Timer(MYTIMERFREQUENCY);
actionTimer.addEventListener(TimerEvent.TIMER, timerHandler);

//This function is called each time the timer goes off "top"
function timerHandler(e:TimerEvent):void
{
//Loop through the array of stars
for (var i=0; i < NUMBER_OF_STARS; i++)
{
//Access the star via a local variable.
currentStar = stars[i];

//Bring the star closer by decreasing its y value
currentStar.z -= zSpeed;

//When the z value is less than the minimum star depth, we know the
//star has "passed" us, and can be placed at the end of the line
//by setting both the z order and putting it first in the display
//list (ff z is less than zero, then the star is "really close", but
//still may be on screen.)
if (currentStar.z < MINIMUM_STAR_DEPTH)
{
//Set to end of line, farthest from the viewer
currentStar.z = INITIAL_STAR_DEPTH;

//Move this star to the end (behind others in the display list)
setChildIndex(currentStar,0);
}

//Set the object alpha so that stars further away appear fainter
currentStar.alpha = Math.min(1.0, 0.25 + ((INITIAL_STAR_DEPTH - currentStar.z) /
(INITIAL_STAR_DEPTH - MINIMUM_STAR_DEPTH) * 0.8));
}
}
//Hook the play/pause button up to start and stop the timer
playpause.addEventListener(MouseEvent.CLICK, playButtonHandler);
function playButtonHandler(ev:MouseEvent):void
{
if (actionTimer.running)
{
actionTimer.stop();
playpause.play_mc.visible = true;
playpause.pause_mc.visible = false;
} else
{
actionTimer.start();
playpause.play_mc.visible = false;
playpause.pause_mc.visible = true;
}
}
3. Test the movie by selecting Control > Test Movie and click the play button. You now have the stars parading towards the viewer in a straight line. See the sample file Moving-Stars-1.fla to see the functionality we've done so far.
 

 
Adding user interaction

Now hook up the user inputs to control the animated stars. The controls add a horizontal oscillation and speed control:
 
1. Use the angle and radius inputs to move the stars left and right as the stars flow toward the user. Add this code above the star creation loop to configure the sliders and set up initial values and variables for the movement:
 
//Configure the sliders.
angleSpeedSlider.value = 10;
angleSpeedSlider.minimum = 1;
angleSpeedSlider.maximum = 30;
zSpeedSlider.value = zSpeed;
zSpeedSlider.minimum = 1;
zSpeedSlider.maximum = 30;
radiusSlider.value = 7;
radiusSlider.minimum = 1;
radiusSlider.maximum = 20;

//Assign a different starting angle for each star (incremented later)
var angle:Number = 0;

//Angle difference between the stars
const ANGLEDIFFERENCE:Number = 0.3;

//How fast the angle changes
var angleSpeed:Number = angleSpeedSlider.value * 0.01;

//The radius for the boxes
var radius:Number = radiusSlider.value * 20;

//Array to match the stars array to hold the corresponding star's angle.
var angles:Array = new Array();
2. You also need to change the star creation loop to set and track the horizontal position. When creating the stars, set the x position based on the value in the slider. Replace this line of code, which sets the x coordinate line:
 
currentStar.x = (stage.stageWidth / 2);
with this:
 
currentStar.x = (stage.stageWidth / 2) - Math.sin(angle)*radius;
3. At the end of the star creation loop, add the following lines to save and increment the angle:
 
//Store the angle of this star. Each star and it's angle can be
//referenced using the same array index
(stars[i] and angles[i]).angles.push(angle);

//Update the angle for the next star
angle += ANGLEDIFFERENCE;
The star creation loop should now look like the following:
 
//Star creation loop
//Create and position the stars, starting with the farthest one
for (var i:int=0; i < NUMBER_OF_STARS; i++)
{
//Create a new star
currentStar = new Star();

//x and y coordinates are the same for all stars: middle of the
//stage, a little up from the bottom.
currentStar.x = (stage.stageWidth / 2) - Math.sin(angle)*radius;
currentStar.y = stage.stageHeight - ORIGINAL_YBORDER;

//Set the depth, or z-value, representing how far away the box is
//from the viewer
currentStar.z = starDepth;

//Set the object alpha so that stars further away appear fainter
currentStar.alpha = Math.min(1.0, 0.25 + ((INITIAL_STAR_DEPTH - starDepth) /

(INITIAL_STAR_DEPTH - MINIMUM_STAR_DEPTH) * 0.8));
//Add star to the array
stars.push(currentStar);

//Add star to the stage
addChild(currentStar);

//Update the starting depth for the next star, which will be closer
starDepth -= ZDISTANCE;

//Store the angle of this star. Each star and it's angle can be
//referenced using the same array index (stars[i] and angles[i]).
angles.push(angle);

//Update the angle for the next star
angle += ANGLEDIFFERENCE;
}
 
4. Change the timer function in several places to use the values from the sliders for the z speed and for calculating the new x position. The new timer function is:
 
//This function is called each time the timer goes off
function timerHandler(e:TimerEvent):void
{
//First get the dynamic speeds from the user interface sliders
angleSpeed =angleSpeedSlider.value*0.01;
zSpeed = zSpeedSlider.value;
radius = radiusSlider.value * 20;

//Loop through the array of stars
for (var i=0; i < NUMBER_OF_STARS; i++)
{
//Access the star via a local variable.
currentStar = stars[i];

//Get the Star's angle
angle = angles[i];

//Bring the star closer by decreasing its y value
currentStar.z -= zSpeed;

//When the z value is less than the minimum star depth, we know the
//star has "passed" us, and can be placed at the end of the line
//by setting both the z order and putting it first in the display
//list (if z is less than zero, then the star is "really close", but
//still may be on screen.)
if (currentStar.z < MINIMUM_STAR_DEPTH)
{
//Set to end of line, farthest from the viewer
currentStar.z = INITIAL_STAR_DEPTH;
// reset the angle to follow the previous star, by
// getting the angle of the previous star
if (i != NUMBER_OF_STARS - 1)
{
//Set behind the last star, by the angle difference
angle = angles[i+1] - ANGLEDIFFERENCE;
}
else
{
//Angles[0] has already been incremented,
//so also subtract the anglespeed we'll be adding
//after this if block, to maintain just the angledifference.
angle = angles[0] - ANGLEDIFFERENCE - angleSpeed;
}

//Move this star to the end (behind others in the display list)
setChildIndex(currentStar,0);
}

//Increment and save the star's new angle
angle += angleSpeed;
angles[i] = angle;

//Calculate the new x position for this star
currentStar.x = (stage.stageWidth/2) - Math.sin(angle) * radius;

//Set the object alpha so that stars further away appear fainter
currentStar.alpha = Math.min(1.0, 0.25 + ((INITIAL_STAR_DEPTH - currentStar.z) /
(INITIAL_STAR_DEPTH - MINIMUM_STAR_DEPTH) * 0.8));
}
}
You now have given the user the ability to control the speed and the amount of oscillation of the stream of stars. The sample file Moving-Stars-2.fla shows the star parade with user controls hooked up.
 

 
Bonus: Adding a twist

You can perform multiple movements at the same time, both 2D and 3D. Adding a z-axis rotation to the stars is the same as a 2D rotation. Add this line of code to the star creation loop (which assumes a five-pointed star):
 
//Set rotation, each star rotated a litle bit more than the other
currentStar.rotationZ = i*360/(NUMBER_OF_STARS*5);
The multiplication by the variable i subtlely rotates each star slightly more than the previous star. Add this in the timer function to start the slow clockwise rotation:
 
//Slow clockwise rotation
currentStar.rotationZ += 2;

 
Where to go from here

This tutorial used the z-property of display objects and animated objects with a timer-based function. For another tutorial about 3D in Flash and ActionScript 3, read my companion article, 3D view controller in Flash using ActionScript 3.
 
Also see the following sections in the online documentation which discuss 3D: