-_--_--_--_--_--_--_--_--_--_--_--_--_--_-
-_--_--_--_--_--_--_--_-
-¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯-
-¯--¯--¯--¯--¯--¯--¯--¯-
AS:3Dimensions - Basic
-----------
The idea of using 3D in flash is that you simulate a third axis:
I am going to discuss just the basics for 3D in flash in this thread:
(the example im going to discuss)
In the example you can see a random arrangement of balls linked to the centre which spins around the X and Y axis with the mouse;
-----------
Creating the 3rd axis:
the 3rd axis is called the z-axis: since flash does not support 3d, you have to simulate it by using projection which can be done by simply scalling the objects using perspective
with perspective, the further something is away from the camera (for this basic 3d thread, ill just say the screen), the smaller the object gets, but also, the closer it seems to appear to the origin (1 point perspective with the vanishing point on the origin) as you can see on this here:
//
to find out where the object (coordinate) appears on the screen you can use this formula
scalar = 500/(n+z); 500 being a constant which you can change (changes the overall look of the projection)
n is an important number which keeps the projection looking real, ever tried dividing 500 by 0? the n value is to keep the division by a number more than 0
then:
screenX = coordX*scalar;
screenY = coordY*scalar;
screenX and Y is where you would place the object in flashes coordinate system (you could then add a value to each to make it be centred in the middle of the screen instead of the top-left)
//
for example, in my example: the coordinate of each ball is random value for each axis from -100 to 100:
to keep the division by above 0, i would set n to a number more than 100 (i used 200) it doesnt really matter what number you use aslong as it keeps the z values more than 0, the higher the value of n, the smaller the resultant coordinate is:
for each 3d coordinate i would then do this: (supposing each 3d coordinate is stored in an object with variables x,y and z)
var scalar:Number = 500/(200+coord.z);
var screenX:Number = 275+coord.x*scalar;
var screenY:Number = 275+coord.y*scalar;
(im using the values 275 because the stage in my example is 550*550)
for each ball i then set its _x and _y to screenX and screenY
ball._x = screenX;
ball._y = screenY;
//
so what about scaling the balls and the transparency effect for further away balls?
you can mess around getting a good effect just by using the coord.z or the scalar number for example in my example:
ball._xscale = ball._yscale = ball._alpha = scalar*30;
//
the last thing for the rendering is this: the z-sorting of the objects
this is very simple and very important: you need to order the balls in flashes depths so that the balls in front are at the front and balls at the back are at the back behind the others:
you can do this using flashes swapDepths() function
for example in my example:
ball.swapDepths(-coord.z*100);
(the reason it is -coord.z is because the closer balls have a smaller z-value whereas the further away balls have a larger z-value so you need to swap it around so that the closer balls appear ontop)
-_--_--_--_--_--_--_--_--_--_--_--_--_--_-
-_--_--_--_--_--_--_--_-
-¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯-
-¯--¯--¯--¯--¯--¯--¯--¯-
the last thing is 3d rotation:
3d rotation uses matrices, but dont worry if you dont know what these are, you dont actually have to use matrice math for the rotations:
any rotation can be described by a matrix and this is where they come in, like i said they are not actually neccesary to use explicitly
a rotation about the x-axis is: (A being the angle)
x2 = x
y2 = y*cosA - z*sinA
z2 = y*sinA + z*cosA
a rotaion about the y-axis is:
x2 = x*cosA + z*sinA;
y2 = y;
z2 = -x*sinA + z*cosA;
a rotation about the z-axis is:
x2 = x*cosA - y*sinA;
y2 = x*sinA + y*cosA;
z2 = z;
note that rotations are done around the origin:
-_--_--_--_--_--_--_--_--_--_--_--_--_--_-
-_--_--_--_--_--_--_--_-
-¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯-
-¯--¯--¯--¯--¯--¯--¯--¯-
putting it all together you now have the basis to create my sample: and for anyone wanting it:
here is the source code:
-_--_--_--_--_--_--_--_--_--_--_--_--_--_-
-_--_--_--_--_--_--_--_-
-¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯--¯-
-¯--¯--¯--¯--¯--¯--¯--¯-
createEmptyMovieClip("balls", 0);
balls._x = balls._y = 275;
balls.attachMovie("cball", "centreball", 1);
balls.centreball.coord = {x:0, y:0, z:0};
var i:Number;
for (i = 0; i < 20; i++)
{
var m:MovieClip = balls.attachMovie("ball", "ball" + i, balls.getNextHighestDepth());
m.coord = {x:random(181) - 90, y:random(181) - 90, z:random(181) - 90};
}
delete m;
var dy:Number = 0, dx:Number = 0;
var pi:Number = Math.PI/180;
function render():Void
{
balls.clear();
balls.lineStyle(1, 0x0000000, 50);
var it:String;
for (it in balls)
{
var coord:Object = balls[it].coord;
//rotate
var sin:Number = Math.sin(dy * pi);
var cos:Number = Math.cos(dy * pi);
//
var tmp:Number = (sin * coord.y) + (cos * coord.z);
coord.y = (cos * coord.y) - (sin * coord.z);
coord.z = tmp;
//
sin = Math.sin(dx * pi);
cos = Math.cos(dx * pi);
//
tmp = (sin * coord.x) + (cos * coord.z);
coord.x = (cos * coord.x) - (sin * coord.z);
coord.z = tmp;
//
delete tmp;
delete sin;
delete cos;
//
//render
var pers:Number = 500 / (coord.z + 200);
var cx:Number = coord.x * pers;
var cy:Number = coord.y * pers;
balls[it]._x = cx;
balls[it]._y = cy;
balls[it]._xscale = balls[it]._yscale = balls[it]._alpha = pers * 30;
if (it != "centreball")
{
balls.lineStyle(1, 0x0000000, pers * 20);
balls.moveTo(cx, cy);
balls.lineTo(0, 0);
}
balls[it].swapDepths(-coord.z * 100);
balls[it].coord = coord;
}
}
render();
//
var mx:Number = _xmouse, my:Number = _ymouse;
this.onMouseMove = function()
{
dx = _xmouse - mx;
dy = _ymouse - my;
mx = _xmouse;
my = _ymouse;
render();
};
If anyone has more questions please ask