Before we get stuck in, let me say that there is certainly more than one way to do this, it depends what you’re comfortable with and what’s easiest for you. What follows is just the way which seems logical to me, and is by no means the most efficient way of doing it. (although it does work a treat.)

We’ll be moving around in our 3D world using the keyboard. These will be our keys:

UP arrow: move the camera up
DOWN arrow: move the camera down
LEFT arrow: move the camera left
RIGHT arrow: move the camera right
SPACE : move camera forward
CTRL: move camera backward

Don’t worry about the mention of the word ‘camera’ above. There is no camera in flash, its just a fancy-pants way of saying that it will seem as if we are moving the viewing area in a particular direction. This of course will not actually be happening. What we will be doing instead is moving everything else on-screen in the opposite way. So instead of moving the fictitious camera left we will be moving the object right etc.

We will need to check for updated movements for every ‘tick of the clock’ that passes (in this case, for every frame).

I think it’s best to deal with a single particle first. We can attach the ActionScript directly to this first instance, and then apply the same theory to everything else by duplicating the instance on-stage.

Okay, so let’s begin by drawing a simple circle. This will be our first particle. Draw a black circle in flash with a black outline and then convert it into a movie clip (f8). Call it anything you like as a symbol name and also give it a meaningful instance name. (I usually call mine Jeff, and sometimes Greg.)

Our particle will need its own x,y, and z values. These will not be actual on-screen x and y co-ordinates (movieclip._x and movieclip._y) but their values if they existed in the real world. Imagine we have a fish tank, and x,y,z co-ordinates are drawn along the edges. X is across the bottom, Y is up the side, and z is into the fish tank, away from us. Imagine we have a stationary camera in the fish tank, and we are able to move all the objects at once via remote control by using the keys noted above. We can move them up,down,left,right,away and toward us.

These x,y,z value will keep a track of how our object would move in the real 3D world, and will be called xval,yval and zval. We’ll then need to alter them before applying them as _x and _y in flash, because we need to take z into consideration and calculate what that means for our 2D screen.

Let’s start with something easy. When the arrow keys are pressed we want our object to move the opposite direction in the fish tank. (everyone OK with the fish tank theme? No fish phobias? Good.)

Remember how we haven’t actually got a moveable camera in flash, so we have to move everything else in the opposite way to make it look as if we are moving a camera.

To make it easy to duplicate our object and its properties we are going to attach our actionscript to the actual particle movie clip. We do this using onClipEvent(load) {} which we’ll use to set things up one time at the start and onClipEvent(enterframe) {} which we’ll use for each frame that passes. To attach these to a movie clip you just click on the movie clip, so that its selected on-stage and then type into the actions panel.

We can add the following code into our onClipEvent(enterframe) {} curly brackets.

	if (Key.isDown(Key.LEFT)) {
		xval += 5;
	} else if (Key.isDown(Key.RIGHT)){
		xval -= 5;
	}

	if (Key.isDown(Key.UP)) {
		yval += 5;
	} else if (Key.isDown(Key.DOWN)){
		yval -= 5;
	}

	if (Key.isDown(Key.SPACE)) {
		zval += 5;
	} else if (Key.isDown(Key.CTRL)){
		zval -= 5;
	}

This checks for any key presses for each frame that passes, so if your project is set to 25fps then it will check 25 times every second.

Note: In flash, y increases as you travel down the screen and x increases as you travel to the right.

If our keyboard were actually linked to the object in the fish tank then the code above would dictate that on pressing LEFT the object will move RIGHT and vice versa. On pressing UP it will move DOWN and vice versa. And using CTRL and SPACE will move it away and towards us.

e.g xval += 5; simply means take the current value of xval and add 5 to it.

As it is not actually linked to a physical fish tank, then the above code merely holds the value of the x,y,z values of a theoretical object in a theoretical space. We can still access the information after any number of key presses and flash will have ‘remembered’ our movements and give us our current position in the theoretical fish tank, even though we do not actually see any visual representation yet.

Since we are asking Flash to add or subtract 1 from current values of xval,yval, and zval then we also need to define what the initial values are.

This is done in the onClipEvent(load) {} curly brackets, since its something we only need to do once.

	xval = 0;
	yval = 0;
	zval = 0;

This sets the initial co-ordinates of our object as being in the top left corner that is closest to us of the fish tank. You could change these values so that the object is centred if you like, but for now we’ll keep things simple.

We now need an equation that will turn these three variables into two variables (x and y) for our 2D screen, so that we can use movieclip._x and movieclip._y for positioning. We also need to use our zval to somehow adjust an object’s scale accordingly (movieclip._xscale and movieclip._yscale).

How do we somehow apply zval to xval and yval and come up with an accurate representation of real world perspective? My first instinct was to scale things up and move them away from the centre depending on their zval value.. so as the zval of an object decreased (got closer), its scale got larger and it drifted away from the centre of the screen. This seemed to work to an extent but something was missing, and the perspective was a little off.

What we need to do is to take into account focal length, which is the distance between the viewers eyes and the screen, and imagine that we are peering through the screen into an actual 3D world. So then, using our zval (distance from screen inward toward the object inside its ‘3D’ world) and focal length (distance from screen to eyes) we have an equation that gives us a scaling value for xval, yval, and the size of our object.

The equation is this:

scaler = focal length / (focal length + zval)


*****************************************************************************
[optional reading]
*****************************************************************************

[Hold on a sec, while I climb onto the shoulders of giants*.. ahem...]

The equation is derived from Thales’ theorem that states:

(actual scale) / (on-screen scale) = (focal length + z ) / focal length

where if we turn the first part on its head we have (on-screen scale) / (actual scale) which is what we are after.. a scaling factor.. scaler. So then we turn the other side on its head to match which gives us our final equation:

(on-screen scale) / (actual scale) = scaler = focal length / (focal length + zval)

*Thanks to Kirupa.com for the excellent thales theorem discussion

*****************************************************************************

Now we can add the following lines of code to our (enterframe) section:

	scaler = f / (f+zval);
	this._x  =  scaler*xval;
	this._y  =  scaler*yval;
	this._xscale = 100*scaler;
	this._yscale = 100*scaler;

And the following to our (load) section to initialise:


	f = 350; (a constant value that you can alter as you wish for different 'lens' effects)

You could now test your movie. Make sure you’re running at 25fps at least in your project settings. You should see your particle move in what appears to be a 3D space as you use the keys as described earlier.