// forked from PESakaTFM's [Alternativa3D] Rubik's Cube (v0.1) /** It's a start... I plan to eventually make it work! Maybe add an auto scrable / solve feature in the end. **/ package { import alternativ5.engine3d.core.Camera3D; import alternativ5.engine3d.core.Object3D; import alternativ5.engine3d.core.Scene3D; import alternativ5.engine3d.display.View; import alternativ5.engine3d.materials.FillMaterial; import alternativ5.engine3d.materials.SurfaceMaterial; import alternativ5.engine3d.primitives.Box; import alternativ5.types.Matrix3D; import alternativ5.types.Point3D; import gs.TweenLite; import flash.display.BlendMode; import flash.display.Sprite; import flash.events.Event; import flash.events.KeyboardEvent; import flash.ui.Keyboard; import net.hires.debug.Stats; [SWF (backgroundColor = "0x0", frameRate = "30", width = "465", height = "465")] public class RubiksCube extends Sprite { public const ROLL_UP:Point3D = Matrix3D.rotationMatrix(-Math.PI/2).getRotations(); public const ROLL_DOWN:Point3D = Matrix3D.rotationMatrix(Math.PI/2).getRotations(); public const ROLL_LEFT:Point3D = Matrix3D.rotationMatrix(0,Math.PI/2).getRotations(); public const ROLL_RIGHT:Point3D = Matrix3D.rotationMatrix(0,-Math.PI/2).getRotations(); private var view:View; private var scene:Scene3D; private var rubik:Object3D; private var spinObject:Object3D; private var red:FillMaterial = new FillMaterial(0xFF0000, 1, BlendMode.NORMAL); private var blue:FillMaterial = new FillMaterial(0x0000FF, 1, BlendMode.NORMAL); private var green:FillMaterial = new FillMaterial(0x00FF00, 1, BlendMode.NORMAL); private var yellow:FillMaterial = new FillMaterial(0xFFFF00, 1, BlendMode.NORMAL); private var white:FillMaterial = new FillMaterial(0xFFFFFF, 1, BlendMode.NORMAL); private var orange:FillMaterial = new FillMaterial(0xFF5500, 1, BlendMode.NORMAL); private var black:FillMaterial = new FillMaterial(0x000000, 1, BlendMode.NORMAL); private var F:Vector.<Box> = new Vector.<Box>(); private var B:Vector.<Box> = new Vector.<Box>(); private var U:Vector.<Box> = new Vector.<Box>(); private var D:Vector.<Box> = new Vector.<Box>(); private var L:Vector.<Box> = new Vector.<Box>(); private var R:Vector.<Box> = new Vector.<Box>(); private var M:Vector.<Box> = new Vector.<Box>(); private var E:Vector.<Box> = new Vector.<Box>(); private var S:Vector.<Box> = new Vector.<Box>(); private var roll:Point3D; private var inMotion:Boolean = false; public function RubiksCube() { addChild(new Stats()); initScene(); rubik = createCube(); spinObject = new Object3D(); spinObject.addChild(rubik); scene.root.addChild(spinObject); addEventListener(Event.ENTER_FRAME, onEnter); stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp); } private function initScene():void { scene = new Scene3D; scene.root = new Object3D(); view = new View; view.camera = new Camera3D(); scene.root.addChild (view.camera); view.width = view.height = 465; view.camera.z = -100; addChild (view); } private function createCube():Object3D { var obj:Object3D = new Object3D(); var box:Box; for(var i:int = 0; i<3; i++) { for(var j:int = 0; j<3; j++) { for(var k:int = 0; k<3; k++) { box = new Box(10,10,10); box.name = "cube"+i+j+k; box.x = 11*k - 11; box.y = 11*j - 11; box.z = 11*i - 11; switch(i) { case 0: D.push(box); break; case 1: E.push(box); break; case 2: U.push(box); } switch(j) { case 0: F.push(box); break; case 1: S.push(box); break; case 2: B.push(box); } switch(k) { case 0: L.push(box); break; case 1: M.push(box); break; case 2: R.push(box); } if(j == 0) box.setMaterialToSurface(red.clone() as SurfaceMaterial, "front"); else box.setMaterialToSurface(black.clone() as SurfaceMaterial, "front"); if(j == 2) box.setMaterialToSurface(orange.clone() as SurfaceMaterial, "back"); else box.setMaterialToSurface(black.clone() as SurfaceMaterial, "back"); if(i == 2) box.setMaterialToSurface(white.clone() as SurfaceMaterial, "top"); else box.setMaterialToSurface(black.clone() as SurfaceMaterial, "top"); if(i == 0) box.setMaterialToSurface(yellow.clone() as SurfaceMaterial, "bottom"); else box.setMaterialToSurface(black.clone() as SurfaceMaterial, "bottom"); if(k == 2) box.setMaterialToSurface(blue.clone() as SurfaceMaterial, "right"); else box.setMaterialToSurface(black.clone() as SurfaceMaterial, "right"); if(k == 0) box.setMaterialToSurface(green.clone() as SurfaceMaterial, "left"); else box.setMaterialToSurface(black.clone() as SurfaceMaterial, "left"); obj.addChild(box); } } } obj.name = "rubik"; return obj; } private function onEnter(event:Event):void { scene.calculate(); } private function onKeyUp(event:KeyboardEvent):void { if(inMotion) return; inMotion = true; switch(event.keyCode) { case Keyboard.UP: roll = ROLL_UP; break; case Keyboard.DOWN: roll = ROLL_DOWN; break; case Keyboard.LEFT: roll = ROLL_LEFT; break; case Keyboard.RIGHT: roll = ROLL_RIGHT; break; } TweenLite.to(spinObject, 1, {rotationX:roll.x, rotationY:roll.y, rotationZ:roll.z, onComplete:fixRotation}); } private function fixRotation():void { Transform.setGlobalToLocalTransform(rubik); spinObject.rotationX = spinObject.rotationY = spinObject.rotationZ = 0; inMotion = false; } } } import alternativ5.engine3d.core.Object3D; import alternativ5.types.Matrix3D; import alternativ5.types.Point3D; class Transform { public static function setGlobalToLocalTransform(obj:Object3D):void { var m:Matrix3D = obj.transformation; obj.x = m.d; obj.y = m.h; obj.z = m.l; var p:Point3D = m.getRotations(); obj.rotationX = p.x; obj.rotationY = p.y; obj.rotationZ = p.z; } } [Alternativa3D] Rubik's Cube (v0.2)