A 3D Engine in Flash 4 ActionScript 1 (2000)

This is a 3D engine made in Flash 4 in the year 2000. It was of the first examples of a 3D engine I created in Flash 4, which I eventually ported to Flash 5 (see below). I believe this is one of the first 3D engines built in Flash.

At the time, Flash didn't support real math calculations. So, operations like sin and cosin had to be estimated or stored in a lookup table. I had to take all these ridiculous equations from c/c++ code and port them to the then primitive ActionScript 1.

There was also no way to dynamically draw a line in Flash. So I pre-created a line asset as a MovieClip and then duplicated and non-uniformly scaled that line to draw it from (x1, y1) to (x2, y2) on the stage. Below, I display the heart of the nasty Flash 4 code.

Flash 4 Code
x_speed = Number(x_speed) + Number(rotate_x);
y_speed = Number(y_speed) + Number(rotate_y);
z_speed = Number(z_speed) + Number(rotate_z);

if (x_speed > 360){ x_speed=number(x_speed)-360;}
if (y_speed > 360){ y_speed=number(y_speed)-360;}
if (z_speed > 360){ z_speed=number(z_speed)-360;}

tellTarget("trig"){
    gotoandStop(/:x_speed);
}
tsx = (trig.point._x +10.1)/100;
tcx = (trig.point._y +10.1)/100;

tellTarget("trig"){
    gotoandStop(/:y_speed);
}
tsy = (trig.point._x +10.1)/100;
tcy = (trig.point._y +10.1)/100;

tellTarget("trig"){
    gotoandStop(/:z_speed);
}
tsz = (trig.point._x +10.1)/100;
tcz = (trig.point._y +10.1)/100;

for (i=1; i<=Number(point_count); i++) {
    tellTarget("point" add i){
        /:bx = x;
        /:by = y;
        /:bz = z;
    }

    rx = tcy * bx + tsy * bz;
    rz = -tsy * bx + tcy * bz;
    ry = tcx * by - tsx * rz;

    rz = tsx * by + tcx * rz;
    rrx = tcz * rx - tsz * ry;
    rry = tsz * rx + tcz * ry;

    rx = rrx * perspective;
    ry = rry * perspective;
    rz = rz + perspective;

    tellTarget("point" add i){
        z_alpha = /:rz
    }

    if (rz == 0) {
        rz = 1;
    }

    dx =  rx/rz + CX;
    dy = -ry/rz + CY;

    setProperty ("point" add i, _x, dx);
    setProperty ("point" add i, _y, dy);

    pos1 = "point" add i;
}


A 3D Engine in Flash 5 ActionScript 1 (2001)

Below is an example of the engine in Flash 5. This was done sometime in early 2001. The engine is more stable with the Flash 5 code and supports vertex dragging (although inaccurate). Rolling over the smaller boxes will morph the 3d object into another shape.

Flash 5 Code
r2d = 0.0174531625854772222222222222222222 ;

if (dragging ne "true"){
if (random_mode eq "true"){
    x_speed = Number(x_speed) + Number(rotate_x);
    y_speed = Number(y_speed) + Number(rotate_y);
    z_speed = Number(z_speed) + Number(rotate_z);
}

for (var i=1; i<=point_count; i++) {
        if (Key.isDown(32)){
            set("point" add i add ":name","point" add i);
        } else {
                set("point" add i add ":name","");
        }

        tsx = math.sin(Number(x_speed) * Number(r2d));
        tsy = math.sin(Number(y_speed) * Number(r2d));
        tsz = math.sin(Number(z_speed) * Number(r2d));

        tcx = math.cos(Number(x_speed) * Number(r2d));
        tcy = math.cos(Number(y_speed) * Number(r2d));
        tcz = math.cos(Number(z_speed) * Number(r2d));

if (random_mode eq "true"){
    if (cont_rand eq "true"){
        for (var ii=1; ii<=Number(line_count); ii++) {
            if (getProperty("line" add ii, _alpha) > 20){
                setProperty ("line" add ii,_alpha,getProperty("line" add ii, _alpha) - 1);
            }
        }
        da_speed = random_speed;
    } else {
        for (var ii=1; ii<=Number(line_count); ii++) {
            if (getProperty("line" add ii, _alpha) < 100){
                setProperty ("line" add ii,_alpha,getProperty("line" add ii, _alpha) + 1);
            }
        }
        da_speed = regroup_speed;
    }
    x[i] = x[i] - ((x[i] - x_goto[i])/da_speed);
    y[i] = y[i] - ((y[i] - y_goto[i])/da_speed);
    z[i] = z[i] - ((z[i] - z_goto[i])/da_speed);
    if (Math.abs(x[i] - x_goto[i]) < 2 && Math.abs(y[i] - y_goto[i]) < 2 && Math.abs(z[i] - z_goto[i]) < 2){
        if (cont_rand eq "true"){
            rand = sizecube*2;
            x_goto[i] = random(rand) - random(rand);
            y_goto[i] = random(rand) - random(rand);
            z_goto[i] = random(rand) - random(rand);
            if (x_goto[i] > sizecube){ x_goto[i] = sizecube;}
            if (y_goto[i] > sizecube){ y_goto[i] = sizecube;}
            if (z_goto[i] > sizecube){ z_goto[i] = sizecube;}
            if (x_goto[i] < -sizecube){ x_goto[i] = -sizecube;}
            if (y_goto[i] < -sizecube){ y_goto[i] = -sizecube;}
            if (z_goto[i] < -sizecube){ z_goto[i] = -sizecube;}
        } else {
            x[i] = x_goto[i];
            y[i] = y_goto[i];
            z[i] = z_goto[i];

            random_wait++;

            if (random_wait eq point_count){

                random_wait = 0;
                random_mode  = "false";
            }
        }
    }
} else {
    for (var ii=1; ii<=Number(line_count); ii++) {
            if (getProperty("line" add ii, _alpha) < 100){
                setProperty ("line" add ii,_alpha,getProperty("line" add ii, _alpha) + 1);
            }
        }
}
    bx = x[i];
    by = y[i];
    bz = z[i];

    rx = tcy * bx + tsy * bz;
    rz = -tsy * bx + tcy * bz;
    ry = tcx * by - tsx * rz;

    rz = tsx * by + tcx * rz;
    rrx = tcz * rx - tsz * ry;
    rry = tsz * rx + tcz * ry;


    if (random_mode ne "true"){
        x[i] = rrx;
        y[i] = rry;
        z[i] = rz;
        x_goto[i] = rrx;
        y_goto[i] = rry;
        z_goto[i] = rz;
    }
    rx = rx * perspective;
    ry = ry * perspective;
    rz = rz + perspective;


    if (rz == 0) {
        rz = 1;
    }

    dx =  rx/rz + CX;
    dy = -ry/rz + CY;

    setProperty ("point" add i, _x, dx);
    setProperty ("point" add i, _y, dy);
}
}
        

An updated 3D Engine in Flash 8 ActionScript 2 (2005)

The last thing I did was add shading from the light source. This is the result of a lot of googling, porting various C code equations, and trial and error but it turned out pretty decent. There's event a little motion blur if you rotate real fast.



The light is affected by mouse position and you can spin the cube by dragging.

The engine was neither efficient nor scalable mostly due to Flash's restrictions but I can say it was a large accomplishment at the time. Unfortunately, I never had anytime to play with it in further versions of Flash.



Personal Projects Gary Fong Puffer vs Lightscoop Reddit's Favorite 200 Books