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.
We can take things a step further and broaden the capabilities of this technique of 3D. With this example, we have something very similar to example 1, only instead of scaled movieclips, theoretical points in the 3D space are moved and then Flash's drawing API is used to dynamically draw lines between those points to give the impression that there is a tall wire frame 3D box moving in the space!
[ tall 3d rendered wire frame box ]
This example is very similar to example 1, only, instead of using figure movieclips, Flash's drawing API is used to dynamically connect-the-dots, if you will, to give the impression of a wire frame box being moved around in 3D! Because of this, very little has changed.
origin = new Object();
origin.x = 150;
origin.y = 150;
focalLength = 300;
MakeA3DPoint = function(x,y,z){
var point = new Object();
point.x = x;
point.y = y;
point.z = z;
return point;
};
This function really only serves to make our lives easier in what lies ahead. It's not technically necessary as a new object could be manually defined every time we needed to make one. This just lets us make a new object with three properties quickly and easily with one function call.
ConvertPointIn3DToPointIn2D = function(pointIn3D){
var pointIn2D = new Object();
var scaleRatio = focalLength/(focalLength + pointIn3D.z);
pointIn2D.x = pointIn3D.x * scaleRatio;
pointIn2D.y = pointIn3D.y * scaleRatio;
return pointIn2D;
};
pointsArray = [
MakeA3DPoint(-20, -40, -20),
MakeA3DPoint(20, -40, -20),
MakeA3DPoint(20, -40, 20),
MakeA3DPoint(-20, -40, 20),
MakeA3DPoint(-20, 80, -20),
MakeA3DPoint(20, 80, -20),
MakeA3DPoint(20, 80, 20),
MakeA3DPoint(-20, 80, 20)
];
this.createEmptyMovieClip("box",1);
direction = "left";
speed = 5;
backAndForthAndSideToSide = function(){
var screenPoints = new Array();
for (var i=0; i < pointsArray.length; i++){
var thisPoint = pointsArray[i];
if (direction == "left"){
thisPoint.x -= speed;
if (i == pointsArray.length-1 && thisPoint.x <= -100) direction = "backward";
}else if (direction == "backward"){
thisPoint.z += speed;
if (i == pointsArray.length-1 && thisPoint.z >= 150) direction = "right";
}else if (direction == "right"){
thisPoint.x += speed;
if (i == pointsArray.length-1 && thisPoint.x >= 60) direction = "forward";
}else if (direction == "forward"){
thisPoint.z -= speed;
if (i == pointsArray.length-1 && thisPoint.z <= 0) direction = "left";
}
screenPoints[i] = ConvertPointIn3DToPointIn2D(thisPoint);
screenPoints[i].x += origin.x;
screenPoints[i].y += origin.y;
}
// to be continued ...
The very end part of this function is the drawing of the lines to each point in the new 2D points array created with the conversion of ConvertPointIn3DToPointIn2D. This where its important to know where each point is in the array since you use the index of the array in determining which points you are moving and lining to. Here, the top is drawn followed by the bottom - each as a single square. Then the 4 corners of those squares are connected with the remaining lines needed to complete the box. This function will be set as the onEnterFrame of the box movieclip setting up the actions of the movie.
// continued ...
this.clear();
this.lineStyle(2,0xFF0000,100);
// top
this.moveTo(screenPoints[0].x, screenPoints[0].y);
this.lineTo(screenPoints[1].x, screenPoints[1].y);
this.lineTo(screenPoints[2].x, screenPoints[2].y);
this.lineTo(screenPoints[3].x, screenPoints[3].y);
this.lineTo(screenPoints[0].x, screenPoints[0].y);
// bottom
this.moveTo(screenPoints[4].x, screenPoints[4].y);
this.lineTo(screenPoints[5].x, screenPoints[5].y);
this.lineTo(screenPoints[6].x, screenPoints[6].y);
this.lineTo(screenPoints[7].x, screenPoints[7].y);
this.lineTo(screenPoints[4].x, screenPoints[4].y);
// connecting bottom and top
this.moveTo(screenPoints[0].x, screenPoints[0].y);
this.lineTo(screenPoints[4].x, screenPoints[4].y);
this.moveTo(screenPoints[1].x, screenPoints[1].y);
this.lineTo(screenPoints[5].x, screenPoints[5].y);
this.moveTo(screenPoints[2].x, screenPoints[2].y);
this.lineTo(screenPoints[6].x, screenPoints[6].y);
this.moveTo(screenPoints[3].x, screenPoints[3].y);
this.lineTo(screenPoints[7].x, screenPoints[7].y);
};
box.onEnterFrame = backAndForthAndSideToSide;
|
|
SUGGESTION: Pre-plan and Plot |
|
A
simple box isn't that
difficult to plot out
in your head. You basically
have a 2 4-point squares,
one with the same points,
just with an increased
y value. When you start
getting into more complicated
shapes though, since
you are modeling
these manually and not
in some GUI, it's a
good idea to draw out
the shape and its points
on a piece of paper,
preferably graph paper.
This will make using
those points much easier
on you. If you want,
you can even map it
out in Flash if you
feel comfortable enough
doing so. |
|
|
|
SUGGESTION: Conquering the Origin Offset |
| In these past two examples, an origin offset was used to place the 3D scene in the middle of the view. After all, Flash's 2D origin is in the upper left of the screen (point 0,0). However, in Example 2, an empty movieclip was used to hold the lines of drawn box. Now, instead of adding the origin to the location of a point every time it moves, you could actually, instead, just move the entire empty movieclip itself to the center of the screen in the main timeline. Then, everything would still be based on 0, but no offset would be needed since the entire movieclip itself is already centered in view. | |
In the two previous examples, you have a constant static view of 3D shapes moving in an apparent 3D space. Though the shapes are able to move about and reposition themselves, the view itself, or camera, is not.
When dealing with 3D, a view is often referred to as a camera or camera view. A camera represents a theoretical location in a 3D space that acts as the point of view of that space. As with the previous examples, the camera there didn't move, or really do anything at all, so there was really no need to even acknowledge its existence. That won't always be the case though, as you'll soon find out.
This idea of the camera is to allow the view to change in respect to everything else in your 3D world. For the most part, all a camera really is, is a set of 3D offset values for your 3D shapes. Imagine yourself standing somewhere remote like in the middle of Utah's Bonneville Salt Flats (U.S.A.) - nothing but a huge flat desert of salt. Now imagine my friend Joe Q. Public is standing slightly off in the distance and he begins walking to you.
In doing so, he gets closer and closer to you until you finally meet. Now lets reverse the situation and say, instead, that you begin walking to him. As you walk, the same thing is happening. He is getting closer to you. The only difference is that you're the one doing the walking here; your feet are moving, not his. Since you see what you see, you represent the camera in the 3D space. With your camera moving towards Joe, you get the same effect as if Joe was moving towards you.
[ moving camera vs moving a figure ]
So, really, instead of the camera actually ever moving, it could, and technically does, just offset everything else in relation to it. Cameras don't move. They move everything else to adjust for what would happen if they did.
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 //--