forked from: [Papervision3D] Rubik's Cube (v1.1)
forked from [Papervision3D] Rubik's Cube (v1.1) (diff: 232)
Next Step: Add Timer. (Look for solved state) Final Step: Auto Solve. ------------------------------------------------
ActionScript3 source code
/**
* Copyright tepe ( http://wonderfl.net/user/tepe )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7Qtk
*/
/**
Next Step: Add Timer. (Look for solved state)
Final Step: Auto Solve.
**/
//------------------------------------------------
package {
import flash.display.*;
import flash.events.*;
import flash.geom.Point;
import flash.text.*;
import flash.ui.Keyboard;
import net.hires.debug.Stats;
import org.papervision3d.core.math.Matrix3D;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.render.QuadrantRenderEngine;
import org.papervision3d.view.BasicView;
public class Main extends Sprite
{
public var rubik:RubiksCube;
public var view:BasicView;
public var mdp:Point = new Point(); // mouse down point
public var dragPoint:Point = new Point();
public var bgClicked:Boolean = false;
public var background:Sprite;
public var shift:Boolean;
private var tf:TextField = new TextField();
public static const SCRAMBLE_DEPTH:int = 22;
public static var tween:Sprite = new Sprite();
private var axii:Array = ['x','y','z'];
//エントリ
public function Main()
{
background = new Sprite();
background.graphics.beginFill(0x0,1);
background.graphics.drawRect(0,0,465,465);
background.graphics.endFill();
addChild(background);
addChild(new Stats());
init3DEngine();
rubik = new RubiksCube();
view.scene.addChild(rubik);
}
//初期化
private function init3DEngine():void
{
view = new BasicView(0, 0, true, true, "Target");
view.camera.z = -100;
view.buttonMode = true;
view.renderer = new QuadrantRenderEngine(QuadrantRenderEngine.CORRECT_Z_FILTER);
this.addChild(view);
this.addEventListener(Event.ENTER_FRAME, onEventRender3D);
stage.addEventListener(MouseEvent.MOUSE_DOWN, startRotation);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
}
private function startRotation(event:MouseEvent):void
{
bgClicked = event.target == background;
stage.addEventListener(MouseEvent.MOUSE_UP, endDrag);
stage.addEventListener(Event.MOUSE_LEAVE, endDrag);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
mdp.x = mouseX;
mdp.y = mouseY;
onMove();
}
public function endDrag(event:Event = null):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, endDrag);
stage.removeEventListener(Event.MOUSE_LEAVE, endDrag);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
}
public function onMove(event:Event=null):void
{
if(bgClicked){
var m:Matrix3D;
if(!shift){//カメラZ軸回転
m = Matrix3D.rotationY((mouseX - mdp.x)/150);
m = Matrix3D.multiply(m, Matrix3D.rotationX(-(mouseY - mdp.y)/150));
}
else {//オブジェクト回転
var rot:Number = (mouseX < 233)? (mouseY - mdp.y)/150 : (mdp.y - mouseY)/150;
rot += (mouseY > 233)? (mouseX - mdp.x)/150 : (mdp.x - mouseX)/150;
m = Matrix3D.rotationZ(rot);
}
//回転
rubik.transform = Matrix3D.multiply(m, rubik.transform);
mdp.x = mouseX;
mdp.y = mouseY;
}
}
private function onEventRender3D(e:Event):void {
view.singleRender();
}
private function onKeyDown(event:KeyboardEvent):void {
shift = event.shiftKey;
}
private function onKeyUp(event:KeyboardEvent):void {
shift = event.shiftKey;
}
}
}
//------------------------------------------------
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import org.papervision3d.core.math.Matrix3D;
import org.papervision3d.core.math.Number3D;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.MovieMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Cube;
class RubiksCube extends DisplayObject3D
{
//public var selected:Number3D;
//public var selSide:Number3D;
private var miniCubes:Vector.<MiniCube> = new Vector.<MiniCube>();
private var temp:Vector.<MiniCube>;
private var endParams:Object;
private var inMotion:Boolean = false;
private var opperation:String;
public function RubiksCube()
{
createCube();
}
private function createCube():void
{
var cube:MiniCube;
cube = new MiniCube(1,1,1);
//cube.addEventListener(MouseEvent.MOUSE_DOWN, onCubeSelected);
miniCubes.push(cube);
addChild(cube);
name = "rubik";
}
/*
private function onCubeSelected(event:MouseEvent):void
{
if(!inMotion)
{
selected = MiniCube(event.currentTarget).location;
selSide = event.target.selectedSide;
}
}
*/
}
//------------------------------------------------
class MiniCube extends DisplayObject3D
{
public var cube:Cube;
private var _loc:Number3D;
private var _selFace:String;
private var faceNums:Object = {
'back': new Number3D(0,0,1),
'front': new Number3D(0,0,-1),
'top': new Number3D(0,-1,0),
'bottom': new Number3D(0,1,0),
'right': new Number3D(-1,0,0),
'left': new Number3D(1,0,0)
}
public function MiniCube(k:int, j:int, i:int)
{
var matList:Object = {all: new ColorMaterial(0x000000, 1, true)};
matList.back = createColorMC(0xD80505, 'back');
matList.front = createColorMC(0xFF9900, 'front');
matList.top = createColorMC(0xFFFFFF, 'top');
matList.bottom = createColorMC(0xFFFF00, 'bottom');
matList.right = createColorMC(0x0018EE, 'right');
matList.left = createColorMC(0x1CA91B, 'left');
cube = new Cube(new MaterialsList(matList), 10, 10, 10);
addChild(cube);
name = "MC"+i+j+k;
cube.x = 11*k - 11;
cube.y = 11*j - 11;
cube.z = 11*i - 11;
_loc = new Number3D(k,j,i);
}
public function update():void
{
cube.transform = Matrix3D.multiply(this.transform, cube.transform);
rotationX = rotationY = rotationZ = 0;
_loc.x = Math.round((cube.x + 11)/11);
_loc.y = Math.round((cube.y + 11)/11);
_loc.z = Math.round((cube.z + 11)/11);
//Round off position
cube.x = 11*_loc.x - 11;
cube.y = 11*_loc.y - 11;
cube.z = 11*_loc.z - 11;
//Round off rotation
var m:Matrix3D = cube.transform;
for(var i:int=1; i<4; i++)
{
for(var j:int=1; j<4; j++)
{
m['n'+i+j] = Math.round(m['n'+i+j]);
}
}
cube.transform = m;
}
public function get location():Number3D { return _loc; }
public function get selectedFace():String { return _selFace; }
public function get selectedSide():Number3D
{
var n:Number3D = faceNums[_selFace];
n = MyUtils.transformNumber(n, cube.transform);
return n;
}
private function createColorMC(color:uint, name:String):MovieMaterial
{
var colorBox:Sprite = new Sprite();
colorBox.graphics.beginFill(color);
colorBox.graphics.drawRect(0, 0, 100, 100);
colorBox.graphics.endFill();
colorBox.name = name;
colorBox.mouseChildren = false;
colorBox.addEventListener(MouseEvent.MOUSE_DOWN, onMovieMatClicked);
var movieMat:MovieMaterial = new MovieMaterial(colorBox, true, true);
movieMat.interactive = true;
movieMat.smooth = true;
return movieMat;
}
//クリックイベント
private function onMovieMatClicked(event:MouseEvent):void
{
_selFace = event.target.name;
this.dispatchEvent(event);
}
}
//------------------------------------------------
class MyUtils
{
public static function transformNumber(n:Number3D, m:Matrix3D):Number3D
{
var v:Number3D = new Number3D(0,0,0);
v.x = m.n11 * n.x + m.n12 * n.y + m.n13 * n.z;
v.y = m.n21 * n.x + m.n22 * n.y + m.n23 * n.z;
v.z = m.n31 * n.x + m.n32 * n.y + m.n33 * n.z;
return v;
}
}