This is an archived tutorial from the kirupa.com legacy collection. It covers software that may no longer be available, but it is kept online because the ideas still hold up.
This example will bring back our figures and have them occupy an environment as we pan the camera through it. The panning motion alone doesn't do much in terms of depth, so the 3D-ness of this example may be limited. Nonetheless, its a step in the right direction to getting really involved with 3D motion as it introduces trig and shows how it can be used with positions in 3D space.
[ panning the camera around viewing figures (LEFT and RIGHT keys) ]
this.createEmptyMovieClip("theScene", 1);
theScene._x = 150;
theScene._y = 150;
objectsInScene = new Array();
cameraView = new Object();
cameraView.rotation = 0;
focalLength = 300;
displayFigure = function(){
var angle = this.angle + cameraView.rotation;
var x = Math.cos(angle)*this.radius;
var z = Math.sin(angle)*this.radius;
var y = this.y;
if (z > 0){
if (!this._visible) this._visible = true;
var scaleRatio = focalLength/(focalLength + z);
this._x = x * scaleRatio;
this._y = y * scaleRatio;
this._xscale = this._yscale = 100 * scaleRatio;
this.swapDepths(Math.round(-z));
}else{
this._visible = false;
}
};
angleStep = 2*Math.PI/10;
for (i = 0; i < 10; i++){
attachedObj = theScene.attachMovie("friend", "friend"+i, i);
attachedObj.angle = angleStep * i;
attachedObj.radius = 100 + i*100;
attachedObj.x = Math.cos(attachedObj.angle) * attachedObj.radius;
attachedObj.z = Math.sin(attachedObj.angle) * attachedObj.radius;
attachedObj.y = 0;
attachedObj.display = displayFigure;
objectsInScene.push(attachedObj);
}
panCamera = function(){
if (Key.isDown(Key.LEFT)) cameraView.rotation -= .1;
if (Key.isDown(Key.RIGHT)) cameraView.rotation += .1;
for (var i=0; i < objectsInScene.length; i++){
objectsInScene[i].display();
}
};
theScene.onEnterFrame = panCamera;
It's time to drop the camera concept for a second and re-evaluate the idea of panning or spinning in this manner. The whole concept of panning is rotating shapes in the 3D space around the camera.This puts those shapes in front of the camera which are viewable, as well as rotates shapes behind the camera which are not. Anything below a relative 0 z is technically behind the view and hidden. However, we can take advantage of the cushion we have with the focal length and rotate images around the 0,0 location of the camera without hiding any of the shapes. This will give the impression of shapes rotating around a center point but, since we can see the shapes on the inside of that center point, that center point wont be seen as the camera center but, rather, a point in front of the camera. Exploiting that cushion allows us to easily rotate shapes in a fully viewable circle right in full view on the screen.
Here is a good example of that rotation with this set of rotating images that can be used (and has been used in many instances) for an interactive 3d-esque interface.
[ spinning of image panes ]
this.createEmptyMovieClip("theScene", 1);
theScene._x = 150;
theScene._y = 100;
objectsInScene = new Array();
focalLength = 500;
spin = 0;
displayPane = function(){
var angle = this.angle + spin;
var x = Math.cos(angle)*this.radius;
var z = Math.sin(angle)*this.radius;
var y = this.y;
var scaleRatio = focalLength/(focalLength + z);
this._x = x * scaleRatio;
this._y = y * scaleRatio;
this._xscale = this._yscale = 100 * scaleRatio;
this._xscale *= Math.sin(angle);
this.swapDepths(Math.round(-z));
};
You can see here that no check was made for z values below 0. We don't want to hide those panes which have gone below 0, but instead, keep them visible so that they can be seen through the entire rotation cycle. You just need to be sure that z values don't exceed the focalLength.
angleStep = 2*Math.PI/8;
for (i=0; i < 8; i++){
attachedObj = theScene.attachMovie("pane", "pane"+i, i);
attachedObj.angle = angleStep * i;
attachedObj.radius = 100;
attachedObj.x = Math.cos(attachedObj.angle) * attachedObj.radius;
attachedObj.z = Math.sin(attachedObj.angle) * attachedObj.radius;
attachedObj.y = 40;
attachedObj.display = displayPane;
objectsInScene.push(attachedObj);
}
panCamera = function(){
spin -= this._xmouse/1000;
for (var i=0; i < objectsInScene.length; i++){
objectsInScene[i].display();
}
};
theScene.onEnterFrame = panCamera;
Note, however, that it is feasible to just rotate around a point that does logically exist in front of the camera instead of the default camera position of 0,0 specifically (something like (x:0, z:50). There's no harm in doing so. You will be a little further away, but the positioning of such a rotation would be more suitable in terms of relation to the camera view. Using the "exploit" just makes it easier.
|
|
SUGGESTION: Use of OOP, Classes and Prototypes |
| So far, I've purposely avoided the use of Flash OOP. I did so to prevent further confusion that may arise from those who not comfortable using it or simply may not yet know how to. This doesn't mean that the current, more procedural method is any better or worse than one done in OOP; it's just a different approach. Using OOP, developing custom classes for you 3D elements, can, however, add more organization to your movie. The examples here are simple enough to not have to worry about such a need for organization. | |
You may feel that you have learned everything there is to know about 3D in Flash, but there is still a bit more left.
That wraps up this tutorial. A huge thank you to all of you who buy kirupa's books, became a paid subscriber, watch the videos, and/or interact on the forums. Your support is what keeps writing like this online! 😇
This tutorial was written by senocular, also known as Trevor McCauley. He has been one of this community's most generous teachers since the early Flash days, and he is still around: find him on senocular.com and on the forums.
:: Copyright KIRUPA 2026 //--