Dice サイコロ
--------------------------------------------------
* サイコロ
*
* author: motoki matsumoto
* blog: http://www.matzmtok.com/blog
* email: mtmotoki(at)gmail.com
*---------------------------------------------------
/*--------------------------------------------------
* サイコロ
*
* author: motoki matsumoto
* blog: http://www.matzmtok.com/blog
* email: mtmotoki(at)gmail.com
*---------------------------------------------------*/
package
{
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.geom.Matrix3D;
import flash.geom.Point;
import flash.geom.Vector3D;
import flash.text.TextField;
import flash.display.Sprite;
import flash.events.Event;
import flash.utils.Timer;
[SWF(width="465", height="465", backgroundColor="0xffffff", frameRate="0")]
public class Dice extends Sprite
{
private var output:TextField;
private var world:Sprite;
private var timer:Timer;
private var mousePos:Point;
private var axis:Vector3D;
private var angle:Number;
private var flag:Boolean;
public function Dice()
{
super();
addEventListener(Event.ADDED_TO_STAGE, addedToStage);
}
public function init():void {
drawBackground();
z = 0;
world= new Sprite();
world.z = 200;
world.x = stage.stageWidth * 0.5;
world.y = stage.stageHeight * 0.5;
addChild(world);
var c:Cube = new Cube();
world.addChild(c);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
timer = new Timer(1000 / 24);
timer.addEventListener(TimerEvent.TIMER, timerHandler);
timer.start();
}
private function drawBackground():void {
var bg:Sprite = new Sprite();
bg.graphics.beginFill(0x000000);
bg.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
bg.graphics.endFill();
addChild(bg);
}
private function mouseDownHandler(e:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
mousePos = new Point(mouseX, mouseY);
}
private function mouseMoveHandler(e:MouseEvent):void
{
var mat:Matrix3D = transform.getRelativeMatrix3D(world);
var vecM0:Vector3D = mat.transformVector(new Vector3D(mousePos.x, mousePos.y, 0));
var vecM1:Vector3D = mat.transformVector(new Vector3D(mouseX, mouseY, 0));
axis = vecM0.crossProduct(vecM1);
//trace(axis);
angle = 10 * Vector3D.angleBetween(vecM1, vecM0) * 180 / Math.PI;
flag = true;
axis.normalize(); //必要っぽい
}
private function mouseUpHandler(e:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
stage.removeEventListener(e.type, arguments.callee);
flag = false;
}
private function hiddenSurface(c:DisplayObjectContainer):void {
var i:int;
var d:DisplayObject;
var vo:Vector3D = new Vector3D(0, 0, 0);
var vx:Vector3D = new Vector3D(100, 0, 0);
var vy:Vector3D = new Vector3D(0, 100, 0);
var po:Point;
var px:Point;
var py:Point;
var pxo:Point;
var pyo:Point;
if (c.numChildren > 0) {
for (i = 0; i < c.numChildren; i++) {
d = c.getChildAt(i);
if (d is Surface) {
po = d.local3DToGlobal(vo);
px = d.local3DToGlobal(vx);
py = d.local3DToGlobal(vy);
pxo = px.subtract(po);
pyo = py.subtract(po);
if (pxo.x * pyo.y < pxo.y * pyo.x) {
d.visible = false;
}else {
d.visible = true;
}
} else if ( d is DisplayObjectContainer) {
hiddenSurface(d as DisplayObjectContainer);
}
}
}
}
private function timerHandler(e:TimerEvent):void
{
hiddenSurface(world);
if (flag) {
world.transform.matrix3D.prependRotation(angle, axis);
}
}
private function addedToStage(e:Event):void
{
removeEventListener(e.type, arguments.callee);
initOutput();
init();
}
private function initOutput():void {
var margin:Number = 10;
addChild(output = new TextField());
output.selectable = false;
output.multiline = true;
output.width = stage.stageWidth - margin * 2;
output.height = stage.stageHeight - margin * 2;
}
public function print(str:String):void {
output.appendText(str);
}
public function println(str:String):void {
output.appendText(str);
output.appendText("\n");
}
}
}
import flash.display.Shape;
import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.display.GradientType;
import flash.display.SpreadMethod;
import flash.display.InterpolationMethod;
class Cube extends Sprite {
private var _size:Number;
public function Cube() {
super();
size = 200;
}
public function get size():Number { return _size; }
public function set size(value:Number):void
{
_buildCube();
_size = value;
var i:int;
var j:int;
var r:Rectangle = new Rectangle( -_size * 0.5, -_size * 0.5, _size, _size);
var offsetX:Number;
var offsetY:Number;
var p:Surface;
var gradMat:Matrix = new Matrix();
var colors:Array = [0x960C0C, 0xFF0000];
var alphas:Array = [1.0, 1.0];
var ratios:Array = [0, 255];
var rad:Number;
var tx:Number;
var ty:Number;
//1
p = _createSurface(r);
p.rotationX = 0;
rad = 40;
tx = ty = -rad
gradMat.createGradientBox(rad * 2, rad * 2, 0, tx, ty);
p.graphics.lineStyle(1, 0xcc0000);
p.graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios, gradMat, SpreadMethod.PAD, InterpolationMethod.RGB, 0.5);
p.graphics.drawCircle(0, 0, rad);
p.graphics.endFill();
p.z = -_size * 0.5;
addChild(p);
//6
p = _createSurface(r);
p.rotationX = 180;
offsetX = -50;
offsetY = -50;
rad = 20;
p.graphics.lineStyle(1, 0xcc0000);
colors = [0x000000, 0x3c3c3c];
for (i = 0; i < 3; i++) {
for (j = 0; j < 2; j++) {
tx = offsetX + j * 100;
ty = offsetY + i * 50;
gradMat.createGradientBox(rad * 2, rad * 2, 0, tx - rad, ty - rad);
p.graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios,
gradMat, SpreadMethod.PAD, InterpolationMethod.RGB, 0.5);
p.graphics.drawCircle(tx, ty, rad);
p.graphics.endFill();
}
}
p.z = -_size * 0.5 + _size;
addChild(p);
//3
p = _createSurface(r);
p.rotationX = 90;
p.y = _size * 0.5;
offsetX = -50;
offsetY = -50;
for (i = 0; i < 3; i++) {
tx = offsetX + i * 50;
ty = offsetY + i * 50;
gradMat.createGradientBox(rad * 2, rad * 2, 0, tx - rad, ty - rad);
p.graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios,
gradMat, SpreadMethod.PAD, InterpolationMethod.RGB, 0.5);
p.graphics.drawCircle(tx, ty, rad);
p.graphics.endFill();
}
addChild(p);
//4
p = _createSurface(r);
p.rotationX = 90 + 180;
p.y = _size * 0.5 - _size;
offsetX = -50;
offsetY = -50;
for (i = 0; i < 2; i++) {
for ( j = 0; j < 2; j++) {
tx = offsetX + 100 * j;
ty = offsetY + 100 * i;
gradMat.createGradientBox(rad * 2, rad * 2, 0, tx - rad, ty - rad);
p.graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios,
gradMat, SpreadMethod.PAD, InterpolationMethod.RGB, 0.5);
p.graphics.drawCircle(offsetX + 100 * j, offsetY + 100 * i, 20);
p.graphics.endFill();
}
}
p.graphics.endFill();
addChild(p);
//2
p = _createSurface(r);
p.rotationY = 90;
p.x = -_size * 0.5;
offsetX = -40;
offsetY = -40;
p.graphics.beginFill(0x000000);
for (i = 0; i < 2; i++) {
tx = offsetX + i * 80;
ty = offsetY + i * 80;
gradMat.createGradientBox(rad * 2, rad * 2, 0, tx - rad, ty - rad);
p.graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios,
gradMat, SpreadMethod.PAD, InterpolationMethod.RGB, 0.5);
p.graphics.drawCircle(tx, ty, 20);
p.graphics.endFill();
}
p.graphics.endFill();
addChild(p);
//5
p = _createSurface(r);
p.rotationY = 90 + 180;
p.x = - _size * 0.5 + _size;
offsetX = -50;
offsetY = -50;
for (i = 0; i < 2; i++) {
for ( j = 0; j < 2; j++) {
tx = offsetX + 100 * j;
ty = offsetY + 100 * i;
gradMat.createGradientBox(rad * 2, rad * 2, 0, tx - rad, ty - rad);
p.graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios,
gradMat, SpreadMethod.PAD, InterpolationMethod.RGB, 0.5);
p.graphics.drawCircle(tx, ty, rad);
p.graphics.endFill();
}
}
gradMat.createGradientBox(rad * 2, rad * 2, 0, -rad, - rad);
p.graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios,
gradMat, SpreadMethod.PAD, InterpolationMethod.RGB, 0.5);
p.graphics.drawCircle(0, 0, 20);
p.graphics.endFill();
addChild(p);
}
private function _createSurface(r:Rectangle):Surface{
var p:Surface = new Surface();
p.graphics.lineStyle(3, 0xaaaaaa);
p.graphics.beginGradientFill(GradientType.RADIAL, [0xFFFFFF,0xEFEFEF], [1.0, 1.0],[0, 255]);
//p.graphics.beginFill(0xFFFFFF);
p.graphics.drawRoundRect(r.x, r.y, r.width, r.height, 20, 20);
p.graphics.endFill();
return p;
}
private function _buildCube():void {
removeAllChildren();
}
private function removeAllChildren():void {
while (numChildren > 0) {
removeChildAt(0);
}
}
}
class Surface extends Shape {
}