In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Media RSS Rubik's Cube

Media RSS based Rubik's cube.
* Not complete game, maybe someone has balls to finish it?
* I was never good with this toy any way.
* Forked from
* http://wonderfl.net/c/xOAv - cube
* http://wonderfl.net/c/luwz - mrss
/**
 * Copyright makc3d ( http://wonderfl.net/user/makc3d )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/1NBJ
 */

/**
 * Media RSS based Rubik's cube.
 * Not complete game, maybe someone has balls to finish it?
 * I was never good with this toy any way.
 * Forked from
 * http://wonderfl.net/c/xOAv - cube
 * http://wonderfl.net/c/luwz - mrss
 */
package {
	import alternativ5.engine3d.core.Object3D;
	import com.bit101.components.Label;

	import alternativ5.types.Point3D;
	import alternativ5.types.Matrix3D;
	import alternativ5.utils.*;

	import flash.display.Sprite;
	import flash.display.BitmapData;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.utils.*
	import flash.ui.Mouse;

	[SWF(width = 465, height = 465, frameRate = 24,backgroundColor=0x000000)]
	/**
	* 
		勝手に何でもAlternativa3Dで作っちゃおうのコーナー
	 
		3D始めるときっと作りたくなるルービックキューブです
		PV3では、以前に投稿されてましたが、Alternativa3Dでも作ってみました。

		3x3では、当たり前すぎなので、5x5にです。
		基本設定のキューブの数で、3x3~?x?に調整できますが、数を増やすと当然重くなります。
		
		ルービックキューブ以外をドラッグすると、ルービックキューブ全体を回転できます。
		ルービックキューブの同一面で2つのキューブ上をドラッグすると、ドラッグした方向に回転します。

		昔、AS2の頃に書いたコードひっぱりだして改造したんで、かなり力技な部分もありますm(_ _)m
		

	 * Alternativa3D を簡単に扱うためのベーシックテンプレート
	 * @author Yasu (clockmaker)
	 */
	public class SimpleDemo extends Sprite {

		public var dragFlag:Boolean=false;
		public var dragWey:Point3D;
		public var clickCubePosition:Point3D;
		public var clickFaceNormal:Point3D;
		public var nextCubePosition:Point3D;
		public var isCubeDrag:Boolean=false
		public var isOribiting:Boolean=false
		public var rotationFlag:Boolean=false;

		public var defColor:Object
		public var overColor:Object


		private var prevPosY:Number=0
		private var prevPosX:Number=0

		private var prevMouseY:Number=0
		private var prevMouseX:Number=0
		private var differenceX:Number=0
		private var differenceY:Number=0

		private var rubikCube:Object3D;
		private var cubes:Array;

		private var cb:ComboBox2, label:Label;
		private var colArray:Array = ["2", "3", "4", "5", "6", "7"];
		private var sizeArray:Array = [300, 200, 180, 150, 135, 120];
		private var frameSizeArray:Array = [20, 15, 12, 10, 10, 10];

		public function SimpleDemo():void {
			cb = new ComboBox2 (this, 240, 330, "3", colArray, init3D); cb.width = 40;
			label = new Label (this, 170, 330, "Cubes in edge:");
		}

		public function init3D():void {
			removeChild (cb); removeChild (label);

			// テンプレートを作成します
			FPS.init(this)

			var template:BasicTemplate = new BasicTemplate();
			addChild(template);

			//基本設定
			var col:uint=parseInt (String (cb.selectedItem)); //キューブの数 col x col
			var size:uint=sizeArray [cb.selectedIndex]; //一つのキューブの大きさ
			var frameSize:uint=frameSizeArray [cb.selectedIndex]; //枠の太さ
			var pitch:uint=10;				//回転スピード(90を割り切れる数字で)
			template.camera.z=-1500

			//配色
			defColor={}
			overColor={}

			defColor['def']		=0x111111
			defColor['red']		=0x990000
			defColor['blue']	=0x000099
			defColor['white']	=0x999999
			defColor['yellow']=0x999900
			defColor['green']	=0x009900
			defColor['orange']=0x994400

			//rolloverの配色
			overColor['def']		=0x000000
			overColor['red']		=0xFF0000
			overColor['blue']		=0x0000FF
			overColor['white']	=0xFFFFFF
			overColor['yellow']	=0xFFFF00
			overColor['green']	=0x00FF00
			overColor['orange']	=0xFF8800


			// ルービックキューブ(全体の入れ物)を作成します
			rubikCube=new Object3D();
			// ルービックキューブを3Dシーンのルートに追加します
			template.scene.root.addChild(rubikCube);
			rubikCube.rotationX=MathUtils.toRadian(30);
			rubikCube.rotationY=MathUtils.toRadian(30);

			// 各キューブを作成します
			// Cubeは、Boxクラスを継承したUserクラス
			cubes=new Array();
			for(var i:int=0;i<col;i++) {
				for(var n:int=0;n<col;n++) {
					for(var m:int=0;m<col;m++) {
						cubes.push(new Cube(this,rubikCube,col-1,size,frameSize,i,n,m));
					}
				}
			}

			//-----------------------------------------------
			//全体の操作
			//-----------------------------------------------
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);
			stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
			/*-------------------------------------------------------
				プリミティブのロールオーバー、クリックを有効にする為
				viewのbuttonModeとinteractiveをtrueにする
			-------------------------------------------------------*/
			template.view.buttonMode = true;
			template.view.interactive = true;

			// カメラの座標を中央に向かせる
			template.cameraContoller.lookAt(new Point3D());


			//回転に使う変数
			var moveCubes:Array=new Array();
			var angle:uint=0;
			var xRota:int=0;
			var yRota:int=0;
			var zRota:int=0;


			// Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
			// レンダリング前に実行したい処理を記述します。
			template.onPreRender = function():void {

				var box:*
				var str:String='';
				var action:String='';

				//キューブがDragされていなければ、全体を回す
				if(isOribiting && !isCubeDrag) {

					rubikCube.rotationY=prevPosY-MathUtils.toRadian(differenceX);
					rubikCube.rotationX=prevPosX+MathUtils.toRadian(differenceY);

				} else if(isCubeDrag) {
					if (nextCubePosition && !dragFlag) {
					//ドラッグで、2つのキューブを選択したら・・回転方向と位置を決める

						moveCubes=new Array();

						dragWey = Point3D.difference(clickCubePosition,nextCubePosition);
						dragWey.x=Math.round(dragWey.x)
						dragWey.y=Math.round(dragWey.y)
						dragWey.z=Math.round(dragWey.z)
						xRota=0;
						yRota=0;
						zRota=0;

						dragFlag=true

						//動きの方向を決める
						if (clickFaceNormal.y) {
							if (dragWey.z && !dragWey.x) {					//上・下面 縦;
								xRota=-dragWey.z*clickFaceNormal.y
							} else if (dragWey.x && !dragWey.z) {		//上・下面 横
								zRota=dragWey.x*clickFaceNormal.y
							}

						} else if (clickFaceNormal.z) {
							if (dragWey.y && !dragWey.x) {					//前・後面 縦
								xRota=dragWey.y*clickFaceNormal.z
							} else if (dragWey.x && !dragWey.y) {		//前・後面 横
								yRota=-dragWey.x*clickFaceNormal.z
							}

						} else if (clickFaceNormal.x) {
							if (dragWey.y && !dragWey.z) {					//左・右面 縦
								zRota=-dragWey.y*clickFaceNormal.x
							} else if (dragWey.z && !dragWey.y) {		//左・右面 横
								yRota=dragWey.z*clickFaceNormal.x
							}
						}

						//動かすキューブを抽出する
						for each(box in cubes) {
							var tempFlag:Boolean=false;
							if (clickFaceNormal.y) {
								if (dragWey.x && !dragWey.z && box.position().z==clickCubePosition.z) {
									tempFlag=true;
								} else if (dragWey.z && !dragWey.x && box.position().x==clickCubePosition.x) {
									tempFlag=true;
								}
							} else if (clickFaceNormal.z) {
								if (dragWey.x && !dragWey.y && box.position().y==clickCubePosition.y) {
									tempFlag=true;
								} else if (dragWey.y && !dragWey.x && box.position().x==clickCubePosition.x) {
									tempFlag=true;
								}
							} else if (clickFaceNormal.x) {
								if (dragWey.z && !dragWey.y && box.position().y==clickCubePosition.y) {
									tempFlag=true;
								} else if (dragWey.y && !dragWey.z && box.position().z==clickCubePosition.z) {
									tempFlag=true;
								}
							}

							if (tempFlag) {
								//色かえ
								box.over()
								moveCubes.push(box)
							}
						}

						angle=0
						rotationFlag=true

						for each(box in cubes) {
							box.doStopAction()
						}

						//回ってる間、Mouseを反応させない
						template.view.buttonMode = false;
						template.view.interactive = false;
					}
					//抽出終わり

				} else if (rotationFlag) {
					//実際に動かす
					angle+=pitch;
					for each (var key:* in moveCubes) {

						//回転情報の作成
						var mtr:Matrix3D=new Matrix3D()
						mtr.rotate(MathUtils.toRadian(xRota/2*pitch),MathUtils.toRadian(yRota/2*pitch),MathUtils.toRadian(zRota/2*pitch));

						//キューブの位置を変更
						var pt1:Point3D=key.coords;
						pt1.transform(mtr);
						key.x=pt1.x
						key.y=pt1.y
						key.z=pt1.z

						//ボックスの各頂点を回す。
						//(rotationX,Y,Zを使うと、軸が回転するので、ややこしくなる。この方が手っ取り早い)
						var pt2:Point3D
						for each(var vt:* in key.vertices) {
							pt2=vt.coords
							pt2.transform(mtr);
							vt.x=pt2.x
							vt.y=pt2.y
							vt.z=pt2.z
						}

					}
				}


			}
			//Prerender終わり


			template.onPostRender = function():void {
				if (rotationFlag) {
					if (angle>=90) {
						//90度回ったら終了
						rotationFlag=false
						template.view.buttonMode = true;
						template.view.interactive = true;
						for each(var box:* in cubes) {
							box.doStartAction()
						}
					}
				}
			}



		}
		//コンストラクタ終わり


		//-----------------------------------------------
		//全体の操作
		//-----------------------------------------------

		private function onStageMouseDown(e:MouseEvent=null):void {
			isOribiting = true;
			prevMouseX = e.stageX;
			prevMouseY = e.stageY;
			differenceX = 0;
			differenceY = 0;

			//ルービックキューブの回転情報を記憶
			prevPosY=rubikCube.rotationY
			prevPosX=rubikCube.rotationX

		}

		private function onStageMouseUp(e:MouseEvent=null):void {
			isOribiting = false;

			if (dragFlag) {
				dragFlag=false
				for each(var box:* in cubes) {
					box.def()
				}
			}
			isCubeDrag=false
			nextCubePosition=null

		}

		private function onStageMouseMove(e:MouseEvent=null):void {
			differenceX = e.stageX - prevMouseX;
			differenceY = e.stageY - prevMouseY;

		}


	}
}




//------------------------------------------------------------------------
//キューブクラス
//------------------------------------------------------------------------
import alternativ5.engine3d.materials.FillMaterial;
import alternativ5.engine3d.materials.TextureMaterial;
import alternativ5.engine3d.primitives.Box;
import alternativ5.engine3d.events.MouseEvent3D
import alternativ5.types.Point3D;
import alternativ5.types.Texture;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Loader;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.system.LoaderContext;


class Cube extends Box{

	private static var loading:Boolean;
	private var _feed:String = "http://api.flickr.com/services/feeds/photos_public.gne?tags=parrot&format=rss_200";
	private var media:Namespace = new Namespace("http://search.yahoo.com/mrss/");
	private var ct:ColorTransform = new ColorTransform (2, 2, 2, 1);
	private function onImageLoaded($images:Array):void {
		$images.length = 6;
		var ldr:Array = [];
		for (var i:int = 0; i < $images.length; ++i) {
			ldr[i] = new Loader;
			//Loaderで読み込んだ画像を後でBitmapDataに書き込む場合
			//第二引数にnew LoaderContext(true)を指定する必要があります
			ldr[i].load(new URLRequest($images[i]), new LoaderContext(true));
			
			ldr[i].x = (i % 2) * (465 - 75);
			ldr[i].y = Math.floor(i / 2) * 85;
			ldr[i].name = i.toString ();
			ldr[i].contentLoaderInfo.addEventListener(Event.COMPLETE, function _load(e:Event):void {
				var tgt:Loader = e.currentTarget.loader;
				e.currentTarget.removeEventListener(Event.COMPLETE, _load);
				main.addChildAt (tgt.content, 0);
				tgt.content.x = tgt.x;
				tgt.content.y = tgt.y;
				// draw into textures
				i = parseInt (tgt.name);
				var cols:int = textures [i].length;
				var w:int = BitmapData (textures [0] [0] [0] [0]).width;
				for (var j:int = 0; j < cols; j++) {
					for (var k:int = 0; k < cols; k++) {
						var m:Matrix = new Matrix;
						if ((i == 0) || (i == 2) || (i == 5)) {
							m.translate ( -w * j, w * (k - cols + 1));
						} else {
							m.translate (w * (j - cols + 1), w * (k - cols + 1));
						}
						var bd:BitmapData = BitmapData (textures [i] [j] [k] [0]);
						var r:Rectangle = bd.rect; bd.fillRect (r, 0);
						r.inflate ( -1, -1); bd.fillRect (r, 0xFFFFFF);
						bd.draw (tgt.content, m, null, "multiply");
						BitmapData (textures [i] [j] [k] [1]).draw (bd, null, ct);
					}
				}
			});
		}
	}

	private static var textures:Array = [];

	private var main:SimpleDemo
	private var size:Number
	private var textureDef:Array
	private var textureOver:Array
	private var textureMaterials:Array
	private var textureFaces:Array
	private var overFlag:Boolean=false

	public function Cube(mc:*,rubikCube:Object3D,col:uint,_size:Number,_frameSize:uint,posX0:int,posY0:int,posZ0:int) {
		main=mc;
		size=_size;

		super(size, size, size);

		var posX:Number = posX0 - col / 2;
		var posY:Number = posY0 - col / 2;
		var posZ:Number = posZ0 - col / 2;

		this.x=(posX*size)
		this.y=(posY*size)
		this.z=(posZ*size)


		//textureを作成して、面に割り付ける
////////		var bmd:BitmapData=new BitmapData(size, size,false,0x000000);
		var frame:Rectangle=new Rectangle(_frameSize,_frameSize,size-_frameSize*2,size-_frameSize*2);

		var defColor:Object=main.defColor
		var overColor:Object=main.overColor

		if (!loading) { loading = true;
			// make textures
			var w:int = 75 / (col + 1), f:Number = w / size;
			frame.x *= f; frame.y *= f; frame.width *= f; frame.height *= f;
			var def:Array = ['red', 'orange', 'white', 'yellow', 'blue', 'green'];
			for (var i:int = 0; i < 6; i++) {
				textures [i] = [];
				for (var j:int = 0; j <= col; j++) {
					textures [i] [j] = [];
					for (var k:int = 0; k <= col; k++) {
						var bmd1:BitmapData = new BitmapData (w, w, false, defColor['def']);
						var bmd2:BitmapData = bmd1.clone ();
						bmd1.fillRect (frame, defColor[def[i]]);
						bmd2.fillRect (frame, overColor[def[i]]);
						textures [i] [j] [k] = [bmd1, bmd2];
					}
				}
			}
			// load media rss
            var ldr:URLLoader = new URLLoader;
            ldr.addEventListener(Event.COMPLETE, function _load(e:Event):void {
                ldr.removeEventListener(Event.COMPLETE, _load);
                onImageLoaded(XML(ldr.data)..media::thumbnail.@url.toXMLString().split('\n'));
            });
            ldr.load(new URLRequest(_feed));
		}

		var defMaterial:FillMaterial=new FillMaterial(defColor['def'],1)
		this.cloneMaterialToAllSurfaces(defMaterial);

		textureDef=[]
		textureOver=[]
		textureMaterials=[]
		textureFaces=[]

		if (posX>0) {
			textureDef[0]=new Texture(textures [0] [posY0] [posZ0] [0])
			textureOver[0]=new Texture(textures [0] [posY0] [posZ0] [1])
			textureFaces[0]='right';
			textureMaterials[0]=new TextureMaterial(textureDef[0],1,true,true)
			this.setMaterialToSurface(textureMaterials[0],'right');

		} else if (posX<0) {
			textureDef[0]=new Texture(textures [1] [posY0] [posZ0] [0])
			textureOver[0]=new Texture(textures [1] [posY0] [posZ0] [1])
			textureFaces[0]='left';
			textureMaterials[0]=new TextureMaterial(textureDef[0],1,true,true)
			this.setMaterialToSurface(textureMaterials[0],'left');

		}

		if (posZ>0) {
			textureDef[1]=new Texture(textures [2] [posX0] [posY0] [0])
			textureOver[1]=new Texture(textures [2] [posX0] [posY0] [1])
			textureFaces[1]='top';
			textureMaterials[1]=new TextureMaterial(textureDef[1],1,true,true)
			this.setMaterialToSurface(textureMaterials[1],'top');
		} else if (posZ<0) {
			textureDef[1]=new Texture(textures [3] [posX0] [posY0] [0])
			textureOver[1]=new Texture(textures [3] [posX0] [posY0] [1])
			textureFaces[1]='bottom';
			textureMaterials[1]=new TextureMaterial(textureDef[1],1,true,true)
			this.setMaterialToSurface(textureMaterials[1],'bottom');
		}

		if (posY>0) {
			textureDef[2]=new Texture(textures [4] [posX0] [posZ0] [0])
			textureOver[2]=new Texture(textures [4] [posX0] [posZ0] [1])
			textureFaces[2]='back';

			textureMaterials[2]=new TextureMaterial(textureDef[2],1,true,true)
			this.setMaterialToSurface(textureMaterials[2],'back');
		} else if (posY<0) {
			textureDef[2]=new Texture(textures [5] [posX0] [posZ0] [0])
			textureOver[2]=new Texture(textures [5] [posX0] [posZ0] [1])
			textureFaces[2]='front';

			textureMaterials[2]=new TextureMaterial(textureDef[2],1,true,true)
			this.setMaterialToSurface(textureMaterials[2],'front');
		}

		//textureを作成して、面に割り付ける ここまで


		rubikCube.addChild(this)
		doStartAction()

	}



	public function doStartAction():void{
		this.addEventListener(MouseEvent3D.MOUSE_DOWN, onCubeMouseDown);
		//this.addEventListener(MouseEvent3D.MOUSE_UP, onCubeMouseUp);				//画面全体のeventで処理するので、いらない
		this.addEventListener(MouseEvent3D.MOUSE_OUT, onCubeMouseOut);
		this.addEventListener(MouseEvent3D.MOUSE_OVER, onCubeMouseOver);
		this.addEventListener(MouseEvent3D.MOUSE_MOVE, onCubeMouseMove);
	}

	public function doStopAction():void {
		this.removeEventListener(MouseEvent3D.MOUSE_DOWN, onCubeMouseDown);
		//this.addEventListener(MouseEvent3D.MOUSE_UP, onCubeMouseUp);				//画面全体のeventで処理するので、いらない
		this.removeEventListener(MouseEvent3D.MOUSE_OUT, onCubeMouseOut);
		this.removeEventListener(MouseEvent3D.MOUSE_OVER, onCubeMouseOver);
		this.addEventListener(MouseEvent3D.MOUSE_MOVE, onCubeMouseMove);
	}


	public function over():void {
		//textureをrolloverに変える
		if (textureFaces[0]) {
			textureMaterials[0]=new TextureMaterial(textureOver[0],1,true,true)
			this.setMaterialToSurface(textureMaterials[0],textureFaces[0]);
		}

		if (textureFaces[1]) {
			textureMaterials[1]=new TextureMaterial(textureOver[1],1,true,true)
			this.setMaterialToSurface(textureMaterials[1],textureFaces[1]);
		}

		if (textureFaces[2]) {
			textureMaterials[2]=new TextureMaterial(textureOver[2],1,true,true)
			this.setMaterialToSurface(textureMaterials[2],textureFaces[2]);
		}
		overFlag=true
	}

	public function def():void {
		//textureをdefaultに戻す
		if (textureFaces[0]) {
			textureMaterials[0]=new TextureMaterial(textureDef[0],1,true,true)
			this.setMaterialToSurface(textureMaterials[0],textureFaces[0]);
		}

		if (textureFaces[1]) {
			textureMaterials[1]=new TextureMaterial(textureDef[1],1,true,true)
			this.setMaterialToSurface(textureMaterials[1],textureFaces[1]);
		}

		if (textureFaces[2]) {
			textureMaterials[2]=new TextureMaterial(textureDef[2],1,true,true)
			this.setMaterialToSurface(textureMaterials[2],textureFaces[2]);
		}
		overFlag=false
	}





	public function position():Point3D {
		var result:Point3D = new Point3D();
		//回転した値には、微妙にゴミが入るので丸める
		result.x=Math.round(x/size*2);
		result.y=Math.round(y/size*2);
		result.z=Math.round(z/size*2);
		return result;
	}


	public function onCubeMouseOver(e:MouseEvent3D=null):void {
		if (!main.isCubeDrag && !main.rotationFlag && !main.isOribiting) {
			this.over()
		} else if (!main.rotationFlag) {
			//次にrollOverした、Cubeで回転方向を決める
			//回転中はドラッグを感知させない
			if (!main.nextCubePosition) {
				main.nextCubePosition=this.position()
			}
		}
	}

	public function onCubeMouseOut(e:MouseEvent3D=null):void {
		this.def()
	}

	public function onCubeMouseDown(e:MouseEvent3D=null):void {
		//clickした情報を、SimpleDemo(親)の変数に入れる
		main.clickCubePosition=this.position()
		main.clickFaceNormal=e.face.normal;
		main.clickFaceNormal.x=Math.round(main.clickFaceNormal.x);
		main.clickFaceNormal.y=Math.round(main.clickFaceNormal.y);
		main.clickFaceNormal.z=Math.round(main.clickFaceNormal.z);

		main.isCubeDrag=true
		main.dragFlag=false;
	}


	public function onCubeMouseMove(e:MouseEvent3D=null):void {
		if (!main.isCubeDrag && !main.rotationFlag && !main.isOribiting) {
			this.over()
		}
	}


}





import alternativ5.engine3d.controllers.CameraController;
import alternativ5.engine3d.core.Camera3D;
import alternativ5.engine3d.core.Object3D;
import alternativ5.engine3d.core.Scene3D;
import alternativ5.engine3d.display.View;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.Event;


/**
 * BasicTemplate for Alternativa3D
 * Alternativa3Dを扱いやすくするためのテンプレートです
 * @author Yasu
 */
class BasicTemplate extends Sprite{
	/**
	 * シーンインスタンスです。
	 */
	public var scene:Scene3D;
	/**
	 * ビューインスタンスです。
	 */
	public var view:View;
	/**
	 * カメラインスタンスです。
	 */
	public var camera:Camera3D;
	/**
	 * カメラコントローラーです。
	 */
	public var cameraContoller:CameraController;
	
	private var _viewWidth:int;
	private var _viewHeight:int;
	private var _scaleToStage:Boolean;

	/**
	 * 新しい BasicTemplate インスタンスを作成します。
	 * @param	viewWidth
	 * @param	viewHeight
	 * @param	scaleToStage
	 */
	public function BasicTemplate(viewWidth:int=640, viewHeight:int=480, scaleToStage:Boolean = true) {
		_viewWidth = viewWidth;
		_viewHeight = viewHeight;
		_scaleToStage = scaleToStage;
		
		// Creating scene
		scene = new Scene3D();
		scene.splitAnalysis = false; // not analysis for performance
		scene.root = new Object3D();
		
		// Adding camera
		camera = new Camera3D();
		camera.z = -1000;
		scene.root.addChild(camera);
		
		// camera contoller
		cameraContoller = new CameraController(this);
		cameraContoller.camera = camera;
		
		// set view
		view = new View();
		view.camera = camera;
		addChild(view);
		
		// stage
		if (stage) init();
		else addEventListener(Event.ADDED_TO_STAGE, init);
	}
	
	/**
	 * 初期化されたときに実行されるイベントです。
	 * 初期化時に実行したい処理をオーバーライドして記述します。
	 */
	protected function atInit():void {}
	
	/**
	 * 初期化されたときに実行されるイベントです。
	 * 初期化時に実行したい処理を記述します。
	 */
	private var _onInit:Function = function():void { };
	public function get onInit():Function { return _onInit; }
	public function set onInit(value:Function):void {
		_onInit = value;
	}
	
	/**
	 * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
	 * レンダリング前に実行したい処理をオーバーライドして記述します。
	 */
	protected function atPreRender():void {}
	
	/**
	 * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
	 * レンダリング前に実行したい処理を記述します。
	 */
	private var _onPreRender:Function = function():void{};
	public function get onPreRender():Function { return _onPreRender; }
	public function set onPreRender(value:Function):void {
		_onPreRender = value;
	}
	
	/**
	 * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
	 * レンダリング後に実行したい処理をオーバーライドして記述します。
	 */
	protected function atPostRender():void {
	}
	
	/**
	 * Event.ENTER_FRAME 時に実行されるレンダリングのイベントです。
	 * レンダリング後に実行したい処理を記述します。
	 */
	protected var _onPostRender:Function = function():void{};
	public function get onPostRender():Function { return _onPostRender; }
	public function set onPostRender(value:Function):void {
		_onPostRender = value;
	}
	
	/**
	 * レンダリングを開始します。
	 */
	public function startRendering():void {
		addEventListener(Event.ENTER_FRAME, onRenderTick);
	}
	/**
	 * レンダリングを停止します。
	 */
	public function stopRendering():void {
		removeEventListener(Event.ENTER_FRAME, onRenderTick);
	}
	
	/**
	 * シングルレンダリング(レンダリングを一回だけ)を実行します。
	 */
	public function singleRender():void {
		onRenderTick();
	}
	
	/**
	 * @private
	 */
	private function init(e:Event = null):void {
		stage.scaleMode = StageScaleMode.NO_SCALE;
		stage.align = StageAlign.TOP_LEFT;
		stage.quality = StageQuality.HIGH;

		// resize
		stage.addEventListener(Event.RESIZE, onResize);
		onResize(null);
		
		// render
		startRendering();
		
		atInit();
		_onInit();
		
	}
	
	/**
	 * @private
	 */
	private function onRenderTick(e:Event = null):void {
		atPreRender();
		_onPreRender();
		scene.calculate();
		atPostRender();
		_onPostRender();
	}
	
	/**
	 * @private
	 */
	private function onResize(event:Event = null):void {
		if (_scaleToStage) {
			view.width = stage.stageWidth;
			view.height = stage.stageHeight;
		}else {
			view.width = _viewWidth;
			view.height = _viewHeight;
		}
	}
}

import com.bit101.components.ComboBox;
import flash.display.DisplayObjectContainer;
import flash.events.Event;

/**
 * How the hell do you subscribe to select event?
 */
class ComboBox2 extends ComboBox {
	private var onSelectCallback:Function
	public function ComboBox2 (parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number = 0, defaultLabel:String = "", items:Array = null, callBack:Function = null) {
		super (parent, xpos, ypos, defaultLabel, items); onSelectCallback = callBack;
	}
	override protected function onSelect (event:Event):void {
		super.onSelect (event); if (onSelectCallback != null) onSelectCallback ();
	}
}