Draggable 3D object, XZ ver.
fork元を連立方程式として解き、Z座標を拾っただけなのでZ座標の計算式はとっちらかってます。。
/**
* Copyright Kay ( http://wonderfl.net/user/Kay )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/ta54
*/
// forked from Kay's Draggable 3D object, XY ver.
package {
import flash.display.*;
import flash.geom.*;
import flash.events.*;
public class DragXZ extends Sprite {
private const SW:Number = stage.stageWidth;
private const SH:Number = stage.stageHeight;
private var canvas:Canvas;
private var targetObj:Object;
private var proj:PerspectiveProjection;
private var disPoint:Point;
public function DragXZ():void {
//---------------------------------------------------
// 3D表示情報を設定
proj = root.transform.perspectiveProjection;
// カメラ角度
proj.fieldOfView = 55;
// 消失点を設定(カンバス中央から)
disPoint = new Point(-100, -SH/2);
proj.projectionCenter = new Point(SW/2+disPoint.x,SH/2+disPoint.y);
//---------------------------------------------------
// カンバスをステージ中央に配置
canvas = new Canvas(SW,SH,disPoint);
canvas.x = SW/2;
canvas.y = SH/2;
addChild(canvas);
//---------------------------------------------------
// カンバスに3Dオブジェクトを表示
var numPoints:int = 10;
for (var i:int = 0; i < numPoints; i++) {
var rects:Rects = new Rects();
rects.x = Math.random()*100-50;
rects.y = i*10 + 5;
rects.z = Math.random()*100-50;
rects.dispVector();
canvas.addChild(rects);
rects.addEventListener(MouseEvent.MOUSE_DOWN, mDown);
}
}
public function mDown(e:MouseEvent):void {
targetObj = e.target;
e.target.addEventListener(Event.ENTER_FRAME, dragStart);
stage.addEventListener(MouseEvent.MOUSE_UP,mUp);
}
public function mUp(e:MouseEvent):void {
e.target.removeEventListener(Event.ENTER_FRAME, dragStart);
stage.removeEventListener(MouseEvent.MOUSE_UP,mUp);
}
private function dragStart(e:Event):void {
// 2DのマウスXY情報をオブジェクトのXY座標値に置き換える
var ratio:Number = (proj.focalLength+targetObj.z)/proj.focalLength;
if (targetObj.z != 0) {
targetObj.x = canvas.mouseX*ratio + disPoint.x - disPoint.x*ratio;
targetObj.z = (proj.focalLength - (canvas.mouseY - disPoint.y) / (targetObj.y - disPoint.y) * proj.focalLength)
* (targetObj.y - disPoint.y) / (canvas.mouseY - disPoint.y);
} else {
targetObj.x = canvas.mouseX*ratio;
targetObj.z = targetObj.y * proj.focalLength / canvas.mouseY - proj.focalLength;
}
targetObj.dispVector();
}
}
}
import flash.display.*;
import flash.geom.*;
import flash.text.*;
class Canvas extends Sprite {
public function Canvas(w:Number, h:Number, p:Point):void {
graphics.lineStyle(0,0x999999);
// x軸
graphics.moveTo(-w/2,0);
graphics.lineTo(w/2,0);
// y軸
graphics.moveTo(0,-h/2);
graphics.lineTo(0,h/2);
// z軸
graphics.moveTo(-p.x,-p.y);
graphics.lineTo(p.x,p.y);
}
}
class Rects extends Sprite {
private var field:TextField;
public function Rects(size:Number=40, nColor:int=0x0066ff):void {
// 側面
var sideL:Panel = new Panel(size,size/4,0x66ccff);
sideL.rotationY = 90;
sideL.x -= size/2;
addChild(sideL);
var sideR:Panel = new Panel(size,size/4,0x66ccff);
sideR.rotationY = 90;
sideR.x += size/2;
addChild(sideR);
// 上面
var top:Panel = new Panel(size,size,nColor);
top.rotationX = 90;
top.y -= size/8;
addChild(top);
// 正面
var front:Panel = new Panel(size,size/4,0x003399);
front.z -= size/2;
addChild(front);
field = new TextField();
field.mouseEnabled = false;
field.autoSize = TextFieldAutoSize.CENTER;
field.selectable = false;
field.text = 'temp';
field.x = -field.width/2;
field.y = -field.height-size/8;
addChild(field);
}
// 3D座標を表示
public function dispVector():void {
field.text = '(x:'+roundNum(x)+', y:'+roundNum(y)+', z:'+roundNum(z)+')';
}
private function roundNum(num:Number):Number {
return Math.round(num*10)/10;
}
}
class Panel extends Shape {
public function Panel(w:Number=10, h:Number=10, color:int=0):void {
graphics.beginFill(color);
graphics.drawRect(-w/2,-h/2,w,h);
graphics.endFill();
}
}