Mouse3Dでルービックキューブ
昔書いたコード http://mae-itr.com/data/swf/rubiccube/RubicCube.swf を整理。
のはずがほとんどコピペにorz
イベント地獄w
カメラ周り参考にさせてもらいました。http://kozy.heteml.jp/pukiwiki/ActionScript3.0%2520papervision3D%25202.x%2520%25B4%25F0%25CB%25DC%25A5%25AA%25A5%25D6%25A5%25B8%25A5%25A7%25A5%25AF%25A5%25C8/index.html
/**
* Copyright Mae_ITR ( http://wonderfl.net/user/Mae_ITR )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/wuO4
*/
//昔書いたコード http://mae-itr.com/data/swf/rubiccube/RubicCube.swf を整理。
//のはずがほとんどコピペにorz
//イベント地獄w
//カメラ周り参考にさせてもらいました。http://kozy.heteml.jp/pukiwiki/ActionScript3.0%2520papervision3D%25202.x%2520%25B4%25F0%25CB%25DC%25A5%25AA%25A5%25D6%25A5%25B8%25A5%25A7%25A5%25AF%25A5%25C8/index.html
package {
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.events.*;
import com.flashdynamix.utils.SWFProfiler;
import org.papervision3d.view.BasicView;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.core.math.Matrix3D;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.events.InteractiveScene3DEvent;
import org.papervision3d.core.utils.InteractiveSceneManager;
import org.papervision3d.core.utils.Mouse3D;
[SWF(width = "465", height = "465", backgroundColor = 0x000000, frameRate = "60")]//
public class RubicCube extends BasicView {
private var cubes:Array;
private var eventcube:DisplayObject3D;
private var cameraX:int;
private var cameraY:int;
private var cameraX2:int;
private var cameraY2:int;
private var hitX:Number;
private var hitY:Number;
private var hitZ:Number;
private var rotX:int;
private var rotY:int;
private var rot:int = 0;
private var dir_X:Boolean;
private var dir_Y:Boolean;
private var dir_Z:Boolean;
private var Rot:int;
public function RubicCube():void {
super(0, 0, true, true);
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
SWFProfiler.init( this);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
init_scene();
init_RubicCube();
startRendering();
stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown);
}
private function init_scene():void {
this._camera.z = -1000;
this._camera.focus = 500;
this._camera.zoom = 0.5;
Mouse3D.enabled = true;
}
private function init_RubicCube():void {
//excludeFacesは面ごとに決められた整数を足していけば複数箇所指定可
//Cube.FRONT == 1 , Cube.BACK == 2 , Cube.LEFT == 8 , Cube.RIGHT == 4 , Cube.TOP == 16 , Cube.BOTTOM == 32
//Cube.FRONT + Cube.RIGHT + Cube.TOP = 21 とか
var excludeFaces:Array = [21, 23, 22, 53, 55, 54, 37, 39, 38, 29, 31, 30, 61, 63, 62, 45, 47, 46, 25, 27, 26, 57, 59, 58, 41, 43, 42];
var materialsList:MaterialsList = new MaterialsList();
materialsList.addMaterial(new ColorMaterial(0xDE2783,1,true), "front");
materialsList.addMaterial(new ColorMaterial(0xFF5446,1,true), "back");
materialsList.addMaterial(new ColorMaterial(0x5042FD,1,true), "right");
materialsList.addMaterial(new ColorMaterial(0x39FDFD,1,true), "left");
materialsList.addMaterial(new ColorMaterial(0x05F17B,1,true), "top");
materialsList.addMaterial(new ColorMaterial(0xEEFB44, 1, true), "bottom");
var n:int = 0;
var cx:Number;
var cy:Number;
var cz:Number;
var cl:Number = 200;
cubes = new Array();
for (var i:int = 0; i < 3; i++) {
cx = i * cl *1.2;
for (var j:int = 0; j < 3; j++) {
cy = j * cl *1.2;
for (var k:int = 0; k < 3; k++) {
cz = k * cl *1.2;
var cube:Cube = new Cube(materialsList, cl, cl, cl, 1, 1, 1, Cube.NONE, excludeFaces[n]);
cube.x = cx - 240;
cube.y = cy -240;
cube.z = cz -240;
cube.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS,mousePress3D);
scene.addChild(cube);
cubes.push(cube);
n++;
}
}
}
}
private function mousePress3D(e:InteractiveScene3DEvent):void {
//trace(this.viewport.interactiveSceneManager.mouse3D.x);
e.displayObject3D.removeEventListener(InteractiveScene3DEvent.OBJECT_PRESS,mousePress3D);
e.displayObject3D.addEventListener(InteractiveScene3DEvent.OBJECT_MOVE, mouseMove3D);
stage.removeEventListener(MouseEvent.MOUSE_MOVE,cameraMove);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
eventcube = e.displayObject3D;
hitX = viewport.interactiveSceneManager.mouse3D.x - eventcube.x;
hitY = viewport.interactiveSceneManager.mouse3D.y - eventcube.y;
hitZ = viewport.interactiveSceneManager.mouse3D.z - eventcube.z;
rotX = stage.mouseX-stage.width/2;
rotY = stage.mouseY-stage.height/2;
}
private function mouseMove3D(e:InteractiveScene3DEvent):void {
var hitX2:Number = viewport.interactiveSceneManager.mouse3D.x - eventcube.x;
var hitY2:Number = viewport.interactiveSceneManager.mouse3D.y - eventcube.y;
var hitZ2:Number = viewport.interactiveSceneManager.mouse3D.z - eventcube.z;
if ((Math.abs(hitY2 - hitY)-15 > 0 ) &&(hitX2 == hitX)) {
dir_X = false;
dir_Y = false;
dir_Z = true;
e.displayObject3D.removeEventListener(InteractiveScene3DEvent.OBJECT_MOVE, mouseMove3D);
stage.addEventListener(MouseEvent.MOUSE_MOVE,cubeMove);
} else if ((Math.abs(hitZ2 - hitZ)-15 > 0 ) &&(hitX2 == hitX)) {
dir_X = false;
dir_Y = true;
dir_Z = false;
e.displayObject3D.removeEventListener(InteractiveScene3DEvent.OBJECT_MOVE, mouseMove3D);
stage.addEventListener(MouseEvent.MOUSE_MOVE,cubeMove);
} else if ((Math.abs(hitX2 - hitX)-15 > 0)&&(hitZ2 == hitZ)) {
dir_X = false;
dir_Y = true;
dir_Z = false;
e.displayObject3D.removeEventListener(InteractiveScene3DEvent.OBJECT_MOVE, mouseMove3D);
stage.addEventListener(MouseEvent.MOUSE_MOVE,cubeMove);
} else if ((Math.abs(hitY2 - hitY)-15 > 0 )&&(hitZ2 == hitZ)) {
dir_X = true;
dir_Y = false;
dir_Z = false;
e.displayObject3D.removeEventListener(InteractiveScene3DEvent.OBJECT_MOVE, mouseMove3D);
stage.addEventListener(MouseEvent.MOUSE_MOVE,cubeMove);
} else if ((Math.abs(hitZ2 - hitZ)-15 > 0 )&&(hitY2 == hitY)) {
dir_X = true;
dir_Y = false;
dir_Z = false;
e.displayObject3D.removeEventListener(InteractiveScene3DEvent.OBJECT_MOVE, mouseMove3D);
stage.addEventListener(MouseEvent.MOUSE_MOVE,cubeMove);
} else if ((Math.abs(hitX2 - hitX)-15 > 0)&&(hitY2 == hitY)) {
dir_X = false;
dir_Y = false;
dir_Z = true;
e.displayObject3D.removeEventListener(InteractiveScene3DEvent.OBJECT_MOVE, mouseMove3D);
stage.addEventListener(MouseEvent.MOUSE_MOVE,cubeMove);
}
}
private function cubeMove(e:MouseEvent):void {
var rotX2:int = ((stage.mouseX-(stage.width/2)) - rotX)/2;
var rotY2:int = ((stage.mouseY-(stage.height/2)) - rotY)/2;
if (Math.abs(rotX2) >= Math.abs(rotY2)) {
rot = rotX2;
} else if (Math.abs(rotX2) < Math.abs(rotY2)) {
rot = rotY2;
}
Rot += rot;
rotationCubes(rot);
//trace(rot);
rotX = (stage.mouseX-(stage.width/2));
rotY = (stage.mouseY-(stage.height/2));
stage.addEventListener(MouseEvent.MOUSE_UP,mouseUp);
}
private function rotationCubes(_rot:int,round:Boolean=false):void {
if (dir_X == true ) {
rotationCubeX(_rot,round);
} else if (dir_Y == true) {
rotationCubeY(_rot,round);
} else if (dir_Z == true) {
rotationCubeZ(_rot,round);
}
//trace("X : " + dir_X + " ,Y : " + dir_Y + " ,Z : " + dir_Z);
}
private function rotationCubeX(_rot:int,round:Boolean):void {
var X:int =0;
for (X=0; X<27; X++) {
if (eventcube.x == cubes[X].x) {
var v:Matrix3D = new Matrix3D([cubes[X].x,cubes[X].y,cubes[X].z,1,0,0,0,0,0,0,0,0]);
var vrx:Matrix3D = Matrix3D.rotationX(_rot/180*Math.PI);
var va:Matrix3D = Matrix3D.multiply(v,vrx);
rotationCube(X,_rot,round);
if (round == false) {
cubes[X].x = va.n11;
cubes[X].y = va.n12;
cubes[X].z = va.n13;
} else if (round == true) {
cubes[X].x = Math.round(va.n11);
cubes[X].y = Math.round(va.n12);
cubes[X].z = Math.round(va.n13);
}
}
}
}
private function rotationCubeY(_rot:int,round:Boolean):void {
var X:int =0;
for (X=0; X<27; X++) {
if (eventcube.y == cubes[X].y) {
var v:Matrix3D = new Matrix3D([cubes[X].x,cubes[X].y,cubes[X].z,1,0,0,0,0,0,0,0,0]);
var vrx:Matrix3D = Matrix3D.rotationY(_rot/180*Math.PI);
var va:Matrix3D = Matrix3D.multiply(v,vrx);
rotationCube(X,_rot,round);
if (round == false) {
cubes[X].x = va.n11;
cubes[X].y = va.n12;
cubes[X].z = va.n13;
} else if (round == true) {
cubes[X].x = Math.round(va.n11);
cubes[X].y = Math.round(va.n12);
cubes[X].z = Math.round(va.n13);
}
}
}
}
private function rotationCubeZ(_rot:int,round:Boolean):void {
var X:int =0;
for (X=0; X<27; X++) {
if (eventcube.z == cubes[X].z) {
var v:Matrix3D = new Matrix3D([cubes[X].x,cubes[X].y,cubes[X].z,1,0,0,0,0,0,0,0,0]);
var vrx:Matrix3D = Matrix3D.rotationZ(_rot/180*Math.PI);
var va:Matrix3D = Matrix3D.multiply(v,vrx);
rotationCube(X,_rot,round);
if (round == false) {
cubes[X].x = va.n11;
cubes[X].y = va.n12;
cubes[X].z = va.n13;
} else if (round == true) {
cubes[X].x = Math.round(va.n11);
cubes[X].y = Math.round(va.n12);
cubes[X].z = Math.round(va.n13);
}
}
}
}
//Cube単体での回転
private function rotationCube(X:int,_rot:int,round:Boolean):void {
var vrx:Matrix3D;
for each (var O:* in cubes[X].geometry.vertices) {
var v:Matrix3D = new Matrix3D([O.x,O.y,O.z,1,0,0,0,0,0,0,0,0]);
if (dir_X == true ) {
vrx = Matrix3D.rotationX(_rot/180*Math.PI);
} else if (dir_Y == true ) {
vrx = Matrix3D.rotationY(_rot/180*Math.PI);
} else if (dir_Z == true ) {
vrx = Matrix3D.rotationZ(_rot/180*Math.PI);
}
var va:Matrix3D = Matrix3D.multiply(v,vrx);
if (round == false) {
O.x = va.n11;
O.y = va.n12;
O.z = va.n13;
} else if (round == true) {
O.x = Math.round(va.n11);
O.y = Math.round(va.n12);
O.z = Math.round(va.n13);
}
}
}
/*private function enterframe(e:Event):void {
}*/
//mouseDown
private function mouseDown(event:Event):void {
cameraX =(stage.mouseX-(stage.width/2));
cameraY =(stage.mouseY-(stage.height/2));
stage.removeEventListener(MouseEvent.MOUSE_DOWN,mouseDown);
stage.addEventListener(MouseEvent.MOUSE_MOVE,cameraMove);
stage.addEventListener(MouseEvent.MOUSE_UP,mouseUp);
}
//cameraMove
private function cameraMove(event:Event):void {
cameraX2 += ((stage.mouseY-(stage.height/2)) - cameraY)/2.3;
cameraY2 -= ((stage.mouseX-(stage.width/2)) - cameraX)/2.3;
if (-89<cameraX2&&cameraX2<89) {
} else if (-89>=cameraX2) {
cameraX2 = -89;
} else {
cameraX2 = 89;
}
var v:Matrix3D = new Matrix3D([0,0,-1000,1,0,0,0,0,0,0,0,0]);
var vrx:Matrix3D = Matrix3D.rotationX(cameraX2/180*Math.PI);
var vry:Matrix3D = Matrix3D.rotationY(cameraY2/180*Math.PI);
var va0:Matrix3D = Matrix3D.multiply(v,vrx);
var va1:Matrix3D = Matrix3D.multiply(va0,vry);
this._camera.x = va1.n11;
this._camera.y = va1.n12;
this._camera.z = va1.n13;
cameraX =(stage.mouseX-(stage.width/2));
cameraY =(stage.mouseY-(stage.height/2));
}
//mouseUp
private function mouseUp(e:MouseEvent):void {
var m:int = Rot % 360;
if ((0 < m)&&(m <= 45)||(-315 > m)&&(m >= -360)) {
rotationCubes(0 - Rot,true);
} else if ((45 < m)&&(m <= 135)||(-225 > m)&&(m >= -315)) {
rotationCubes(90 - Rot,true);
} else if ((135 < m)&&(m <= 225)||(-135 > m)&&(m >= -225)) {
rotationCubes(180 - Rot,true);
} else if ((225 < m)&&(m <= 315)||(-45 > m)&&(m >= -135)) {
rotationCubes(270 - Rot,true);
} else if ((315 < m)&&(m <= 360)||(0 >= m)&&(m >= -45)) {
rotationCubes(360 - Rot,true);
}
Rot = 0;
stage.removeEventListener(MouseEvent.MOUSE_MOVE, cameraMove);
stage.removeEventListener(MouseEvent.MOUSE_MOVE,cubeMove);
stage.removeEventListener(MouseEvent.MOUSE_UP,mouseUp);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
if (eventcube) {
eventcube.removeEventListener(InteractiveScene3DEvent.OBJECT_MOVE, mouseMove3D);
eventcube.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS,mousePress3D);
}
}
}
}