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

forked from: Twitter Friend Location

Twiiterでフォローしているユーザーの現在地に登録されている情報で
都道府県に、配置します。
都道府県が記載されていないユーザーは、表示されません。
とりあえず、1000人まではサーチできるようにしていますが。
多いとそれだけ処理時間が長くなります。

最初かっこよくカメラ動かそうかとも思いましたが、めんどくさいので止めたw

@narutohyper
/**
 * Copyright tepe ( http://wonderfl.net/user/tepe )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/jmiS
 */

// forked from narutohyper's Twitter Friend Location
package {
/*

Twiiterでフォローしているユーザーの現在地に登録されている情報で
都道府県に、配置します。
都道府県が記載されていないユーザーは、表示されません。
とりあえず、1000人まではサーチできるようにしていますが。
多いとそれだけ処理時間が長くなります。

最初かっこよくカメラ動かそうかとも思いましたが、めんどくさいので止めたw

@narutohyper
*/

    import alternativ5.engine3d.materials.FillMaterial;
    import alternativ5.engine3d.materials.WireMaterial;

    import alternativ5.engine3d.primitives.Box;
    import alternativ5.engine3d.primitives.Sphere;
    import alternativ5.engine3d.core.Object3D;
    import alternativ5.engine3d.events.MouseEvent3D
    import alternativ5.engine3d.controllers.WalkController
    import alternativ5.engine3d.controllers.ObjectController
    import alternativ5.types.Point3D;
    import alternativ5.engine3d.core.Camera3D;

    import alternativ5.utils.KeyboardUtils

    import flash.display.*;
    import flash.events.*;
    import flash.net.*;
    import flash.text.*;
    import flash.system.*;

    import caurina.transitions.Tweener;
        
    [SWF(width = 465, height = 465, frameRate = 60,backgroundColor=0x000000)]
    public class SimpleDemo extends Sprite {
        private var prefectureArray:Array;
        private var eye:Sphere
        private var camera:Camera3D

        
        public function SimpleDemo():void {

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

            camera=template.camera
            camera.z=500


            //Controllerのインスタンスを作る
            var walkController:WalkController=new WalkController(this.stage,template.camera)
            walkController.lookAt(new Point3D(0,0,0));

            //キーボードのキー(Keyboard.KEY)を関連付ける(Bind)する    
            walkController.mouseEnabled=false
            walkController.bindKey(KeyboardUtils.PAGE_UP,    ObjectController.ACTION_UP);
            walkController.bindKey(KeyboardUtils.PAGE_DOWN,    ObjectController.ACTION_DOWN);
            walkController.bindKey(KeyboardUtils.E,    ObjectController.ACTION_UP);
            walkController.bindKey(KeyboardUtils.D,    ObjectController.ACTION_DOWN);            
            walkController.bindKey(KeyboardUtils.W,            ObjectController.ACTION_FORWARD);
            walkController.bindKey(KeyboardUtils.UP,        ObjectController.ACTION_FORWARD);
            walkController.bindKey(KeyboardUtils.Z,            ObjectController.ACTION_BACK);
            walkController.bindKey(KeyboardUtils.DOWN,    ObjectController.ACTION_BACK);
            walkController.bindKey(KeyboardUtils.A,            ObjectController.ACTION_YAW_LEFT);
            walkController.bindKey(KeyboardUtils.LEFT,    ObjectController.ACTION_YAW_LEFT);
            walkController.bindKey(KeyboardUtils.S,            ObjectController.ACTION_YAW_RIGHT);
            walkController.bindKey(KeyboardUtils.RIGHT,    ObjectController.ACTION_YAW_RIGHT);
            walkController.bindKey(KeyboardUtils.SHIFT,    ObjectController.ACTION_ACCELERATE);

            //移動スピードを設定する
            walkController.speed = 700;

            //初期位置を設定する
            walkController.coords=new Point3D(0,-4000,500);


            var base:Object3D = new Object3D();
            template.scene.root.addChild(base);
            //base.rotationX = -70 * Math.PI / 180;

            var areArray:Array=[
            ['北海道','hokkaido'],
            ['青森'    ,'aomori'],
            ['秋田'    ,'akita'],
            ['岩手'    ,'iwate'],
            ['山形'    ,'yamagata'],
            ['宮城'    ,'miyagi'],
            ['福島'    ,'fukushima'],
            ['茨城'    ,'ibaragi'],
            ['千葉'    ,'chiba'],
            ['栃木'    ,'tochigi'],
            ['群馬'    ,'gunma'],
            ['埼玉'    ,'saitama'],
            ['東京'    ,'tokyo'],
            ['神奈川','kanagawa'],
            ['新潟'    ,'nigata'],
            ['山梨'    ,'yamanashi'],
            ['長野'    ,'nagano'],
            ['富山'    ,'toyama'],
            ['石川'    ,'ishikawa'],
            ['福井'    ,'fukui'],
            ['静岡'    ,'shizuoka'],
            ['愛知'    ,'aichi'],
            ['岐阜'    ,'gifu'],
            ['三重'    ,'mie'],
            ['滋賀'    ,'shiga'],
            ['奈良'    ,'nara'],
            ['和歌山','wakayama'],
            ['京都'    ,'kyoto'],
            ['大阪'    ,'osaka'],
            ['兵庫'    ,'hyougo'],
            ['鳥取'    ,'tottori'],
            ['岡山'    ,'okayama'],
            ['島根'    ,'simane'],
            ['広島'    ,'hiroshima'],
            ['山口'    ,'yamaguchi'],
            ['香川'    ,'kagawa'],
            ['愛媛'    ,'ehime'],
            ['徳島'    ,'tokushima'],
            ['高知'    ,'kouchi'],
            ['福岡'    ,'fukuoka'],
            ['大分'    ,'oita'],
            ['宮崎'    ,'miyazaki'],
            ['熊本'    ,'kumamoto'],
            ['鹿児島','kagoshima'],
            ['佐賀'    ,'saga'],
            ['長崎'    ,'nagasaki'],
            ['沖縄'    ,'okinawa']
            ]

            prefectureArray=[];

            prefectureArray.push(new prefecture(this,base, 0,0,'北海道',770,100,200,200));
            prefectureArray.push(new prefecture(this,base, 1,0,'青森',720,250,100,60));
            prefectureArray.push(new prefecture(this,base, 2,0,'秋田',695,320,50,80));
            prefectureArray.push(new prefecture(this,base, 3,0,'岩手',745,320,50,80));
            prefectureArray.push(new prefecture(this,base, 4,0,'山形',695,400,50,80));
            prefectureArray.push(new prefecture(this,base, 5,0,'宮城',745,400,50,80));
            prefectureArray.push(new prefecture(this,base, 6,0,'福島',720,470,100,60));
            prefectureArray.push(new prefecture(this,base, 7,1,'茨城',745,535,50,70));
            prefectureArray.push(new prefecture(this,base, 8,1,'千葉',745,625,50,110));
            prefectureArray.push(new prefecture(this,base, 9,1,'栃木',695,520,50,40));
            prefectureArray.push(new prefecture(this,base,10,1,'群馬',645,520,50,40));
            prefectureArray.push(new prefecture(this,base,11,1,'埼玉',670,560,100,40));
            prefectureArray.push(new prefecture(this,base,12,1,'東京',695,600,50,40));
            prefectureArray.push(new prefecture(this,base,13,1,'神奈川',695,640,50,40));
            prefectureArray.push(new prefecture(this,base,14,2,'新潟',620,470,100,60));
            prefectureArray.push(new prefecture(this,base,15,2,'山梨',645,605,50,50));
            prefectureArray.push(new prefecture(this,base,16,2,'長野',595,565,50,130));
            prefectureArray.push(new prefecture(this,base,17,2,'富山',545,515,50,50));
            prefectureArray.push(new prefecture(this,base,18,2,'石川',500,485,40,110));
            prefectureArray.push(new prefecture(this,base,19,2,'福井',475,565,50,50));
            prefectureArray.push(new prefecture(this,base,20,3,'静岡',635,665,70,70));
            prefectureArray.push(new prefecture(this,base,21,3,'愛知',570,655,60,50));
            prefectureArray.push(new prefecture(this,base,22,3,'岐阜',535,585,70,90));
            prefectureArray.push(new prefecture(this,base,23,3,'三重',520,680,40,100));
            prefectureArray.push(new prefecture(this,base,24,4,'滋賀',475,620,50,60));
            prefectureArray.push(new prefecture(this,base,25,4,'奈良',475,680,50,60));
            prefectureArray.push(new prefecture(this,base,26,4,'和歌山',455,740,90,60));
            prefectureArray.push(new prefecture(this,base,27,4,'京都',430,595,40,70));
            prefectureArray.push(new prefecture(this,base,28,4,'大阪',430,670,40,80));
            prefectureArray.push(new prefecture(this,base,29,4,'兵庫',380,605,60,90));
            prefectureArray.push(new prefecture(this,base,30,5,'鳥取',315,580,70,40));
            prefectureArray.push(new prefecture(this,base,31,5,'岡山',315,625,70,50));
            prefectureArray.push(new prefecture(this,base,32,5,'島根',245,580,70,40));
            prefectureArray.push(new prefecture(this,base,33,5,'広島',245,625,70,50));
            prefectureArray.push(new prefecture(this,base,34,5,'山口',180,615,60,70));
            prefectureArray.push(new prefecture(this,base,35,6,'香川',340,700,80,40));
            prefectureArray.push(new prefecture(this,base,33,6,'愛媛',260,700,80,40));
            prefectureArray.push(new prefecture(this,base,37,6,'徳島',340,740,80,40));
            prefectureArray.push(new prefecture(this,base,38,6,'高知',260,740,80,40));
            prefectureArray.push(new prefecture(this,base,39,7,'福岡',145,685,90,50));
            prefectureArray.push(new prefecture(this,base,40,7,'大分',170,740,40,60));
            prefectureArray.push(new prefecture(this,base,41,7,'宮崎',170,805,40,70));
            prefectureArray.push(new prefecture(this,base,42,7,'熊本',125,750,50,80));
            prefectureArray.push(new prefecture(this,base,43,7,'鹿児島',125,820,50,60));
            prefectureArray.push(new prefecture(this,base,44,7,'佐賀',80,685,40,50));
            prefectureArray.push(new prefecture(this,base,45,7,'長崎',40,695,40,70));
            prefectureArray.push(new prefecture(this,base,46,7,'沖縄',50,830,60,40));

            

            var friendArray:Array=[]

            var inputBox:TextField=new TextField()
            inputBox.type=TextFieldType.INPUT 
            inputBox.width=200
            inputBox.height=20
            inputBox.x=10
            inputBox.y=10
            inputBox.selectable=true;
            inputBox.mouseEnabled=true;
            inputBox.background=true;
            inputBox.backgroundColor=0xFFFFFF
            inputBox.border
            
            var format:TextFormat=new TextFormat();
            format.color=0x000000
            format.size=12;
            format.font='_ゴシック';
            inputBox.defaultTextFormat=format
            inputBox.text='narutohyper'
            addChild(inputBox)

            //searchButton
            var bt:Sprite=new Sprite()
            bt.graphics.beginFill(0xCCCCCC,1)
            bt.graphics.drawRect(0,0,100,20)
            bt.x=220
            bt.y=10

            var label:TextField=new TextField()
            label.autoSize=TextFieldAutoSize.CENTER
            label.selectable=false;
            label.mouseEnabled=false;
            format=new TextFormat();
            format.color=0x000000
            format.size=12;
            format.font='_ゴシック';
            label.defaultTextFormat=format
            label.text='search'
            bt.addChild(label)
            addChild(bt)
            bt.addEventListener(MouseEvent.CLICK,init)


            var guideBox:TextField=new TextField()
            guideBox.autoSize=TextFieldAutoSize.LEFT
            guideBox.width=400
            guideBox.y=40
            guideBox.selectable=true;
            guideBox.mouseEnabled=true;
            format=new TextFormat();
            format.color=0xFFFFFF
            format.size=12;
            format.font='_等幅';
            guideBox.defaultTextFormat=format
            guideBox.text="TwitterIDを入力して、searchを押してください。\n";
            guideBox.appendText(" W↑    E上 \n");
            guideBox.appendText("←A S→ D下 \n");
            guideBox.appendText(" Z↓   \n");
            
            
            guideBox.appendText("十字キーでも操作できます。\n");
            addChild(guideBox);

            var dbg:TextField=new TextField()
            //dbg.autoSize=TextFieldAutoSize.LEFT
            dbg.width=400
            dbg.y=120
            dbg.selectable=true;
            dbg.mouseEnabled=true;
            dbg.multiline=true;
            format=new TextFormat();
            format.color=0xFFFFFF
            format.size=12;
            format.font='_ゴシック';
            dbg.defaultTextFormat=format
            addChild(dbg);


            function init():void {
                var userId:String=inputBox.text
                var loader:URLLoader = new URLLoader();
                var page:uint=1
                var maxPage:uint=11
                var next_cursor:Number=-1

                for (var i:uint=0;i<prefectureArray.length;i++) {
                    prefectureArray[i].init()
                }
                dbg.text="";
                loadXml()
                function loadXml():void {
                    //Twitterのstatusesはcrossdomain許可されていない為、セキュリティエラーで取得できない
                    //とりあえず串で対応
                    Security.loadPolicyFile("http://marubayashi.net/crossdomain.xml");
                    var url:String="http://marubayashi.net/tips/crossdomain-proxy.php?url="+"http://twitter.com/statuses/friends/"+userId+".xml?cursor="+next_cursor
                    dbg.appendText("読み込み ");
                    new LoaderContext(true)
                    loader.load(new URLRequest(url));

                    loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,onSecurityError);
                    loader.addEventListener(Event.OPEN,onOpen);
                    loader.addEventListener(Event.COMPLETE,onComplete);
                    loader.addEventListener(IOErrorEvent.IO_ERROR, errorEvent);
                }


                function onSecurityError(e:SecurityErrorEvent):void {
                    dbg.appendText("\nsecurityErrorHandler: " + e);
                    dbg.appendText("\n");
                }

                function onOpen(e:Event):void {
                    dbg.appendText("開始\n");
                }

                function onComplete(e:Event):void {
                    
                    dbg.appendText("終了\n");
                                        
                    loader.removeEventListener(Event.COMPLETE,onComplete );
                    loader.removeEventListener(IOErrorEvent.IO_ERROR, errorEvent);
                    next_cursor=XML(loader.data).next_cursor
                    var users:XMLList = XML(loader.data).users.user;
                    var pattern:RegExp
                    var matchId:int
                    var temp:uint

                    for each(var x:XML in users) {
                        matchId=-1;
                        for (var i:uint=0;i<areArray.length;i++) {
                            pattern = new RegExp(areArray[i][0]+'|'+areArray[i][1], "i");
                            if (pattern.exec(x.location)) {
                                matchId=i;
                                break;
                            }
                        }

                        if (matchId>=0) {
                            prefectureArray[matchId].addFriend(x.name,x.profile_image_url)
                        }
                        temp++
                    }


                    page++
                    if (maxPage>page && next_cursor) {
                        loadXml(userId)
                    } else {
                        dbg.text="";
                        //配置が終わったら、各県のキャラクターを分布させる
                        for (i=0;i<prefectureArray.length;i++) {
                            prefectureArray[i].setPosition()
                        }
                    }
                }

                function errorEvent(e:IOErrorEvent):void {
                    guideBox.appendText("ERROR"+e+"\n");
                    loader.removeEventListener(Event.COMPLETE,onComplete );
                    loader.removeEventListener(IOErrorEvent.IO_ERROR, errorEvent);
                    trace(e);
                }


            }



            template.onPreRender = function():void {
                //walkController.lookAt(eye.coords);
                walkController.processInput()
                //camera.coords=new Point3D(eye.x,eye.y-1000,1000)
            }

        }
        

    }
}



import alternativ5.engine3d.primitives.Plane;
import alternativ5.engine3d.primitives.Cone;
import alternativ5.engine3d.core.Sprite3D;
import alternativ5.engine3d.materials.FillMaterial;
import alternativ5.engine3d.materials.TextureMaterial;
import alternativ5.engine3d.materials.SpriteTextureMaterial;
import alternativ5.types.Texture;
import alternativ5.engine3d.events.MouseEvent3D

import flash.display.*;
import flash.text.*;
import flash.net.*;
import flash.system.LoaderContext;
import flash.geom.Matrix;
import flash.utils.escapeMultiByte;

import jp.progression.casts.CastDocument;
import jp.progression.commands.lists.LoaderList;
import jp.progression.commands.lists.SerialList;
import jp.progression.commands.net.LoadBitmapData;
import jp.progression.commands.net.LoadURL;
import jp.progression.data.Resource;
import jp.progression.data.getResourceById;

class prefecture extends Object3D{

    private var mainMc:SimpleDemo
    private var id:uint
    private var bmd:BitmapData
    private var friendList:Array
    private var friendSet:Object3D
    private var width:Number
    private var height:Number
    private var colorArray:Array=[0xB0CFEA,0xFFB0B0,0xB0F1C0,0xDBB6FF,0xFFD3B0,0xD9FFB0,0xFFD8FF,0xFFFDB0]
    private var prefectureName:String
    private var cone:*
    private var cone2:*
    private var bmdCounter:uint=0

    public function prefecture(_mainMc:SimpleDemo,_parentMc:Object3D,_id:uint,_areaid:uint,_name:String,_x:Number,_y:Number,_width:Number,_height:Number) {
        mainMc=_mainMc
        var s:uint=6
        friendList=[]
        prefectureName=_name
        width=_width*s-4*s
        height=_height*s-4*s
        var base:Plane = new Plane(width,height);
        base.cloneMaterialToAllSurfaces(new FillMaterial(colorArray[_areaid]));
        this.addChild(base)

        x=_x*s-850/2*s+50*s
        y=-_y*s+850/2*s

        _parentMc.addChild(this)

        mainMc.addEventListener(Event.ENTER_FRAME, onEnterFrame);

        function onEnterFrame(e:Event):void {
            if (cone) {
                cone.rotationZ+=1*Math.PI/180
            }
            if (cone2) {            
                cone2.rotationZ+=1*Math.PI/180
            }
        }

    }

    public function init():void {
        if (cone) {
            this.removeChild(cone);
            cone=null;
        }
        if (cone2) {
            this.removeChild(cone2);
            cone2=null;
        }

        for (var i:uint = 0; i < friendList.length; i++) {
            var res:Resource = getResourceById(friendList[i].filename);
            if (res) {
                res.dispose()
                res=null
            }
        }
        //2010/2/24メモリリーク修正
        if(bmd) {
            bmd.dispose()
        }


        friendList=[]

    }


    public function addFriend(_name:String,_filename:String):void {
        friendList.push({name:_name,filename:_filename})
    }

    public function addFriendBmd(i:uint,f:BitmapData,_scale:Number):void {
        bmd.draw(f,new Matrix(_scale,0,0,_scale,i%12*80,(bmd.height-80)-Math.floor(i/12)*80))
    }

    private static const LOADER_CONTEXT:LoaderContext = new LoaderContext(true);

    public function setPosition():void {
        var r:Number=0
        var pol:uint=12
        if (friendList.length==1 || friendList.length==2) {
            cone=new Sprite3D();
            bmd=new BitmapData(80*friendList.length,80,true,0x00000000)
            cone.z=80/2;
            addChild(cone)
            cone.material=new SpriteTextureMaterial(new Texture(bmd),1,true);

        } else if (friendList.length) {
            pol=(friendList.length<12)? friendList.length:12
            bmd=new BitmapData(80*pol,80*Math.ceil(friendList.length/pol),true,0x00000000)
            r=80/(2*Math.sin(Math.PI/pol))
            cone=new Cone(80*Math.ceil(friendList.length/pol),r,r,1,pol,false,true);
            cone.z=80*Math.ceil(friendList.length/pol)/2*0.7;
            cone.scaleX=cone.scaleY=cone.scaleZ=0.7
            addChild(cone)
            cone.setMaterialToSurface(new TextureMaterial(new Texture(bmd),1,false,true),'side');

            cone2=new Cone(80*Math.ceil(friendList.length/pol),r,r,1,pol,true,false);
            cone2.z=80*Math.ceil(friendList.length/pol)/2*0.7;
            cone2.scaleX=cone2.scaleY=cone2.scaleZ=0.7
            addChild(cone2)
            cone2.setMaterialToSurface(new FillMaterial(0x666666),'side');

        }
        //画像の読み込み
        
        new SerialList(null,
            function():void {
                var cmd:LoaderList = new LoaderList();
                for (var i:uint = 0; i < friendList.length; i++) {
                    cmd.addCommand(
                        new LoadBitmapData(new URLRequest(friendList[i].filename),
                            {
                                context: new LoaderContext(true),
                                catchError: function(target:Object, error:Error):void {
                                    target.executeComplete();
                                }
                            }
                        )
                    );
                }
                this.parent.insertCommand(cmd);
            }
            ,
            function():void {
                for (var i:uint = 0; i < friendList.length; i++) {
                    var s:Number
                    var res:Resource = getResourceById(friendList[i].filename);
                    var bmd:BitmapData = res.toBitmapData();
                    if (bmd) {
                        if (bmd.width>bmd.height) {
                            s=80/bmd.width
                        } else {
                            s=80/bmd.height
                        }
                        addFriendBmd(i,bmd,s)
                    }
                    
                }
            }
        ).execute();

    }

}



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 {
        atPostRender();
        _onPostRender();
        scene.calculate();
        atPreRender();
        _onPreRender();
    }
    
    /**
     * @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;
        }
    }
}