[PV3D] 3D Grid でイテレーターパターンを勉強。
pv3d.orgの 3DGrid でイテレーターパターンを勉強中。
イテレーターが回る事によって、先にクリックしたPlaneが次に選択したPlaneの位置に入ります。
/**
* Copyright user_x ( http://wonderfl.net/user/user_x )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/gPfg
*/
//forked from http://pv3d.org/2009/02/01/3d-grid/
//pv3d.orgの 3DGrid でイテレーターパターンを勉強中。
//イテレーターが回る事によって、先にクリックしたPlaneが次に選択したPlaneの位置に入ります。
package {
import de.polygonal.ds.Array3;
import de.polygonal.ds.Iterator;
import flash.display.DisplayObject;
import flash.display.Shape;
import flash.events.Event;
import flash.events.MouseEvent;
import gs.TweenMax;
import org.papervision3d.events.InteractiveScene3DEvent;
import org.papervision3d.materials.MovieMaterial;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.view.BasicView;
[SWF(width="900", height="480", backgroundColor="#ffffff", frameRate="60")]
public class Main extends BasicView
{
private static const GRID_COLS:int = 3;
private static const GRID_X_SPACING:Number = 200;
private static const CENTER_X_OFFSET:Number = GRID_COLS * GRID_X_SPACING / 2 - GRID_X_SPACING / 2;
private static const GRID_ROWS:int = 4;
private static const GRID_Y_SPACING:Number = 200;
private static const CENTER_Y_OFFSET:Number = GRID_ROWS * GRID_Y_SPACING / 2 - GRID_Y_SPACING / 2;
private static const GRID_LAYERS:int = 2;
private static const GRID_Z_SPACING:Number = 200;
private static const CENTER_Z_OFFSET:Number = GRID_LAYERS * GRID_Z_SPACING / 2 - GRID_Z_SPACING / 2;
private var grid:Array3 = new Array3(GRID_COLS, GRID_ROWS, GRID_LAYERS);
private var selectedPlane:Plane;
private var cameraPitch:Number = 90;
private var cameraYaw:Number = 270;
private var cameraTarget:DisplayObject3D = DisplayObject3D.ZERO;
private var previousMouseX:Number = 0;
private var isOrbiting:Boolean = false;
public function Main()
{
viewport.interactive = true; //AbstractView クラスのプロパティ viewport のインタラクティブを true にする。
createGrid();
startRendering();
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
private function createGrid():void
{
for(var i:int = 0; i < GRID_COLS; i++)
{
for(var j:int = 0; j < GRID_ROWS; j++)
{
for(var k:int = 0; k < GRID_LAYERS; k++)
{
var randomColor:Number = Math.random() * 0xffffff;
var shape:Shape = new Shape();
with(shape)
{
graphics.beginFill(randomColor);
graphics.drawRect(0, 0, 50, 50);
graphics.endFill();
}
var material:MovieMaterial = new MovieMaterial(shape);
//animated needs to be true to tween the color
material.animated = true;
material.doubleSided = true;
material.interactive = true;
var plane:Plane = new Plane(material, 100, 100);
plane.name = "plane_" + i + "_" + j + "_" + k;
//trace("plane : " + plane);
plane.x = i * GRID_X_SPACING - CENTER_X_OFFSET;
plane.y = j * GRID_Y_SPACING - CENTER_Y_OFFSET;
plane.z = k * GRID_Z_SPACING - CENTER_Z_OFFSET;
plane.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, plane_objectClickHandler);
//push planes references into our collection
grid.set(i, j, k, plane);
scene.addChild(plane);
}
}
}
}
private function plane_objectClickHandler(event:InteractiveScene3DEvent):void
{
var clickedPlane:Plane = Plane(event.target);
if(selectedPlane != clickedPlane)
{
if (selectedPlane) TweenMax.to(selectedPlane, 1, { scale:1, rotationY:0 , x:clickedPlane.x , y:clickedPlane.y, z:clickedPlane.z } );
selectedPlane = Plane(event.target);
TweenMax.to(selectedPlane, 1, { scale:6, rotationY:180, x:600, y:300, z: -200 } );
var randomColor:Number = Math.random() * 0xffffff;
//loop through our grid using the iterator of Array3
var time:Number = .1;
var itr:Iterator = grid.getIterator();
//コレクションの中の最初のアイテムにイテレーターを移動させる。
itr.start();
while(itr.hasNext())
{
time += .05; // イテレーターがコレクションの中の次のアイテム(要素)をチェックする速度。これはTeenMax.toのtimeに入る。
// ie,各 Plane の変色が 伝播する速度。
if(itr.data != null)
{
var plane:Plane = Plane(itr.data);
trace("plane : " + plane);
//We don't tween the color of the selectedPlane
if(plane != selectedPlane)
{
//tint the color of the movie asset in the material
var movieClip:DisplayObject = MovieMaterial(plane.material).movie;
TweenMax.to(movieClip, time, {tint:randomColor});
}
}
//
itr.next();
}
}
}
private function mouseDownHandler(event:MouseEvent):void
{
isOrbiting = true;
}
private function mouseUpHandler(event:MouseEvent):void
{
isOrbiting = false;
}
override protected function onRenderTick(event:Event=null):void //BasicView の protected メソッド onRenderTick をオーバーライド。
{
if(isOrbiting)
{
var differenceX:Number = viewport.containerSprite.mouseX - previousMouseX;
cameraYaw += differenceX;
cameraYaw %= 360;
camera.orbit(cameraPitch, cameraYaw, true, camera.target);
}
previousMouseX = viewport.containerSprite.mouseX;
super.onRenderTick(event);
}
}
}