Sunday, September 13th, 2009
Ah, you see what I did there? Anyway, on to the serious stuff. So yeah, I’m close, but not quite there.
I’ve created a base class that does the “maths” for you, it’s called “Sprite3D()” and you won’t ever need to call it, unless you wanted just a simple 3D object container.
I’ve also created a “Rectangle3D()” base class and am extending it in the “Cube3D()” class (that’s not complete yet, so don’t use it).
So the biggest issue is still rotation, but I’ve nearly cracked it. I just need to figure out a way of maintaining a central pivot point. Once the angle get’s over 45° and is less than 135°, it throws itself up. It’s not a simple case of just doing a negative multiplication too, there needs to be some subtle maths. I’ll figure it out.
Nevertheless, here’s some code you can play with:
{
import com.firestartermedia.lib.as3.display.threedee.shape.Rectangle3D;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.geom.Point;
import flash.text.Font;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.utils.setInterval;
[SWF( width='580', height='500', frameRate='30', backgroundColor='#FFFFFF' )]
public class App3D1 extends Sprite
{
[Embed( systemFont='Arial Black', fontName='ArialBlack', mimeType='application/x-font', unicodeRange='U+0041-U+005A' )]
private var arialBlack:Class;
private var cube1:Rectangle3D;
private var cube2:Rectangle3D;
private var cube3:Rectangle3D;
public function App3D1()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
Font.registerFont( arialBlack );
init();
}
private function init():void
{
transform.perspectiveProjection.projectionCenter = new Point( stage.stageWidth / 2, stage.stageHeight / 2 );
transform.perspectiveProjection.fieldOfView = 45;
cube1 = new Rectangle3D();
cube1.faceFront = createFace( 0x333333, 'front' );
cube1.faceBack = createFace( 0x333333, 'back' );
cube1.faceLeft = createFace( 0x3333FF, 'left', 500 );
cube1.faceRight = createFace( 0x333333, 'right', 500 );
cube1.faceTop = createFace( 0x333333, 'top', 300, 500 );
cube1.faceBottom = createFace( 0x333333, 'bottom', 300, 500 );
cube1.build();
addChild( cube1 );
cube1.x = -400;
cube1.y = ( stage.stageHeight / 2 ) - ( cube1.height / 2 );
cube1.z = 1000;
cube2 = new Rectangle3D();
cube2.faceFront = createFace( 0x333333, 'front' );
cube2.faceBack = createFace( 0x333333, 'back' );
cube2.faceLeft = createFace( 0x3333FF, 'left', 500 );
cube2.faceRight = createFace( 0x333333, 'right', 500 );
cube2.faceTop = createFace( 0x333333, 'top', 300, 500 );
cube2.faceBottom = createFace( 0x333333, 'bottom', 300, 500 );
cube2.build();
addChild( cube2 );
cube2.rotationX = 45;
cube2.x = ( stage.stageWidth / 2 ) - ( cube2.width / 2 );
cube2.y = ( stage.stageHeight / 2 ) - ( cube2.height / 2 );
cube2.z = 1000;
cube3 = new Rectangle3D();
cube3.faceFront = createFace( 0x333333, 'front' );
cube3.faceBack = createFace( 0x333333, 'back' );
cube3.faceLeft = createFace( 0x3333FF, 'left', 500 );
cube3.faceRight = createFace( 0x333333, 'right', 500 );
cube3.faceTop = createFace( 0x333333, 'top', 300, 500 );
cube3.faceBottom = createFace( 0x333333, 'bottom', 300, 500 );
cube3.build();
addChild( cube3 );
cube3.rotationX = 90;
cube3.x = 400 + cube3.width;
cube3.y = ( stage.stageHeight / 2 ) - ( cube3.height / 2 );
cube3.z = 1000;
addEventListener( Event.ENTER_FRAME, handleEnterFrame );
}
private function createFace(colour:uint, name:String, width:Number=300, height:Number=300):Sprite
{
var face:Sprite = new Sprite();
var text:TextField = new TextField();
face.graphics.beginFill( colour, .3 );
face.graphics.lineStyle( 1, colour );
face.graphics.drawRect( 0, 0, width, height );
face.graphics.endFill();
face.name = name;
text.autoSize = TextFieldAutoSize.LEFT;
text.defaultTextFormat = new TextFormat( 'ArialBlack', 40, 0xFFFFFF );
text.embedFonts = true;
text.text = name.toUpperCase();
face.addChild( text );
return face;
}
private function handleEnterFrame(e:Event=null):void
{
cube1.rotationX += 1; // pitch
//cube1.rotationY += 1; // scope
//cube1.rotationZ += 1; // roll
cube2.rotationX += 1; // pitch
//cube2.rotationY += 1; // scope
//cube2.rotationZ += 1; // roll
cube3.rotationX += 1; // pitch
//cube3.rotationY += 1; // scope
//cube3.rotationZ += 1; // roll
}
}
}
And this is what you get, lovely ain’t it?
So, like I said, I’ll figure this out! All the classes are up on Github and feel free to fork me!