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

XZゲーム用テンプレート

主に自分用のテンプレート

素材
- First Seed Material
-- http://www.tekepon.net/fsm/
Get Adobe Flash player
by o_healer 21 Feb 2011
/**
 * Copyright o_healer ( http://wonderfl.net/user/o_healer )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/zCVT
 */

/*
 XZ平面を移動するゲーム用のテンプレート
 - Box2Dを使う版
*/

/*
 今はMAPの要素数は64x64が限界
 - DisplacementMapFilteerの移動値の関係
 - 拡張する場合、以下の対応が必要(128x128を例にする)
 -- m_BitmapData_Listの左上に用意した画像を、64*TILE_LENだけズラした位置にも描画
 --- 左上、右上、左下、右下で4つ同じものができる
 -- m_Bitmapdata_MoveBaseの移動値をそれに合わせる
 --- 左上の区画はそのまま。それ以外の区画は、その区画における左上隅に移動するように設定。
*/


package {
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;
    import flash.net.*;
    import flash.system.*;
    import flash.text.*;

    //Box2D
    import Box2D.Dynamics.*;
    import Box2D.Collision.*;
    import Box2D.Collision.Shapes.*;
    import Box2D.Common.*;
    import Box2D.Common.Math.*;
    import Box2D.Dynamics.Joints.*;

    [SWF(width="465", height="465", frameRate="30", backgroundColor="0x004400")]
    public class GameMain extends Sprite {
        //==Const==

        //画像ファイル名
//*
        static public const URL_BLOCKS:String = "http://assets.wonderfl.net/images/related_images/c/c2/c22a/c22a6efab573c0397fe9cd987fb44701fe3416af";
        static public const URL_PLAYER:String = "http://assets.wonderfl.net/images/related_images/0/0f/0fb1/0fb141ba90fe1f9c9e8d82c83bb28ab27abc52b0";
/*/
        static public const URL_BLOCKS:String = "Blocks.png";
        static public const URL_PLAYER:String = "Player.png";
//*/

        //画面サイズ
        static public const VIEW_W:int = 465;
        static public const VIEW_H:int = 465;

        //1マスの大きさ
        static public const PANEL_LEN:int = 32;

        //画像サイズ
        static public const PANEL_W:int = 24;
        static public const PANEL_H:int = 32;
        static public const PANEL_NUM_X:int = 3;
        static public const PANEL_NUM_Y:int = 4;

        //マップ要素
        static public var MapIndexIter:int = 0;
        static public const O:int = MapIndexIter++;
        static public const W:int = MapIndexIter++;
        static public const P:int = MapIndexIter++;

        //マップ
        static public const MAP:Array = [
            [W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W],
            [W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W],
            [W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W],
            [W,O,O,O,O,O,W,W,W,O,O,O,O,O,W,W,W,O,O,O,O,O,O,O,O,O,O,O,W,W,W,W],
            [W,O,O,O,O,O,W,W,W,O,O,O,O,O,W,W,W,O,O,O,O,O,O,O,O,O,O,O,W,W,W,W],
            [W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,W,W,W,W],
            [W,O,O,O,O,O,W,W,W,O,O,O,O,O,W,W,W,O,O,O,O,O,O,O,O,O,O,O,W,W,W,W],
            [W,O,O,O,O,O,W,W,W,O,O,O,O,O,W,W,W,O,O,O,O,O,O,O,O,O,O,O,W,W,W,W],
            [W,W,W,O,W,W,W,W,W,W,W,O,W,W,W,W,W,O,O,O,O,O,O,O,O,O,O,O,W,W,W,W],
            [W,W,W,O,W,W,W,W,W,W,W,O,W,W,W,W,W,O,O,O,O,O,O,O,O,O,O,O,W,W,W,W],
            [W,O,O,O,O,O,W,W,W,O,O,O,O,O,W,W,W,O,O,O,O,O,O,O,O,O,O,O,W,W,W,W],
            [W,O,O,O,O,O,W,W,W,O,O,O,O,O,W,W,W,O,O,O,O,O,O,O,O,O,O,O,W,W,W,W],
            [W,O,O,P,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,W,W,W,W],
            [W,O,O,O,O,O,W,W,W,O,O,O,O,O,W,W,W,O,O,O,O,O,O,O,O,O,O,O,W,W,W,W],
            [W,O,O,O,O,O,W,W,W,O,O,O,O,O,W,W,W,O,O,O,O,O,O,O,O,O,O,O,W,W,W,W],
            [W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W],
            [W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W],
            [W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W],
        ];

        //マップのパネル数
        static public const MAP_NUM_X:int = MAP[0].length;
        static public const MAP_NUM_Y:int = MAP.length;
        //マップの大きさ
        static public const MAP_W:int = MAP_NUM_X * PANEL_LEN;
        static public const MAP_H:int = MAP_NUM_Y * PANEL_LEN;

        //Box2Dと実際の表示の比率(Box2Dに大きすぎる値を入れると上手く動かなかったりする)
        static public const PHYS_SCALE:Number = 10;
        static public function PHYS_to_IMAGE(in_Val:Number):Number{return in_Val * PHYS_SCALE;}
        static public function IMAGE_to_PHYS(in_Val:Number):Number{return in_Val / PHYS_SCALE;}
        //Box2Dの画面外の余白
        static public const BOX2D_RANGE_OFFSET:int = 100;


        //==Var==

        //Pseudo Singleton
        static public var Instance:GameMain;

        //マップ(プレイヤーなどを地面に置き換えたりしたもの)
        public var m_Map:Vector.<Vector.<int> >;

        //プレイヤーの初期位置
        public var m_PlayerX:int = 2.5*PANEL_LEN;//一応それっぽい位置に初期化
        public var m_PlayerY:int = 2.5*PANEL_LEN;

        //レイヤー
        public var m_Layer_Root:Sprite = new Sprite();//Root
        public var  m_Layer_Bot:Sprite = new Sprite();//地面用レイヤー
        public var   m_Layer_Bot_Floor:Sprite = new Sprite();//地形の地面用レイヤー
        public var   m_Layer_Bot_FloorObj:Sprite = new Sprite();//地面に置かれたOBJ用レイヤー
        public var   m_Layer_Bot_FloorEffect:Sprite = new Sprite();//地面に描くエフェクト用レイヤー
        public var  m_Layer_Mid:Sprite = new Sprite();//通常表示用レイヤー
        public var   m_Layer_Mid_Wall:Sprite = new Sprite();//壁用レイヤー
        public var   m_Layer_Mid_Sort:Sprite = new Sprite();//Yの値でソートされる通常OBJ用レイヤー
        public var  m_Layer_Top:Sprite = new Sprite();//上に重なる地形用レイヤー
        public var  m_Layer_Debug:Sprite = new Sprite();//デバッグ描画用

        //地形画像
        public var m_BitmapData_Floor:BitmapData = new BitmapData(MAP_W, MAP_H, true, 0x00000000);
        public var m_BitmapData_Wall:BitmapData  = new BitmapData(MAP_W, MAP_H, true, 0x00000000);//MAPの外に表示が出るなら、もう少し大きくすべきか
        public var m_BitmapData_Ceil:BitmapData  = new BitmapData(MAP_W, MAP_H, true, 0x00000000);


        //プレイヤー
        public var m_Player:Player;


        //Box2D
        public var m_Box2D_World:b2World;


        //==Function==

        //Init
        public function GameMain(){
            var x:int;
            var y:int;

            //Pseudo Singleton
            {
                Instance = this;
            }

            //Common
            {
                stage.scaleMode = StageScaleMode.NO_SCALE;
                stage.align = StageAlign.TOP_LEFT;
            }

            //Static Init
            {
                ImageManager.Init();
                Player.Initialize();
            }

            //MAP => m_Map
            {
                m_Map = new Vector.<Vector.<int> >(MAP_NUM_Y);
                for(y = 0; y < MAP_NUM_Y; y++){
                    m_Map[y] = new Vector.<int>(MAP_NUM_X);
                    var PosY:int = (y+0.5) * PANEL_LEN;
                    for(x = 0; x < MAP_NUM_X; x++){
                        var PosX:int = (x+0.5) * PANEL_LEN;
                        var index:int = MAP[y][x];

                        switch(index){
                        case P:
                            index = O;//プレイヤーの居た位置は地面扱いする
                            m_PlayerX = PosX;
                            m_PlayerY = PosY;
                            break;
                        }

                        m_Map[y][x] = index;
                    }
                }
            }

            //Box2D
            {
                //考慮する領域
                var worldAABB:b2AABB = new b2AABB();
                worldAABB.lowerBound.Set(IMAGE_to_PHYS(-BOX2D_RANGE_OFFSET), IMAGE_to_PHYS(-BOX2D_RANGE_OFFSET));
                worldAABB.upperBound.Set(IMAGE_to_PHYS(MAP_W+BOX2D_RANGE_OFFSET), IMAGE_to_PHYS(MAP_H+BOX2D_RANGE_OFFSET));
                //重力ベクトル
                var gravity:b2Vec2 = new b2Vec2(0, 0);
                //Sleep
                var useSleep:Boolean = true;
                //物理world
                m_Box2D_World = new b2World(worldAABB, gravity, useSleep);
            }

            //地形コリジョン
            {
                Init_Terrain_Collision();
            }

            //Layer
            {
                addChild(m_Layer_Root);
                {
                    m_Layer_Root.addChild(m_Layer_Bot);
                    {
                        m_Layer_Root.addChild(m_Layer_Bot_Floor);
                        m_Layer_Root.addChild(m_Layer_Bot_FloorObj);
                        m_Layer_Root.addChild(m_Layer_Bot_FloorEffect);
                    }

                    m_Layer_Root.addChild(m_Layer_Mid);
                    {
                        m_Layer_Mid.addChild(m_Layer_Mid_Wall);
                        m_Layer_Mid.addChild(m_Layer_Mid_Sort);
                    }

                    m_Layer_Root.addChild(m_Layer_Top);

                    m_Layer_Root.addChild(m_Layer_Debug);
                }
            }

            //地形
            {
                ImageManager.Map_to_Bitmap(
                    m_Map,
                    m_BitmapData_Ceil,
                    m_BitmapData_Wall,
                    m_BitmapData_Floor
                );

                var bmp:Bitmap;

                //Floor
                {
                    bmp = new Bitmap(m_BitmapData_Floor);
                    m_Layer_Bot_Floor.addChild(bmp);
                }

                //Wall
                {
                    bmp = new Bitmap(m_BitmapData_Wall);
                    m_Layer_Mid_Wall.addChild(bmp);
                }

                //Ceil
                {
                    bmp = new Bitmap(m_BitmapData_Ceil);
                    bmp.y -= PANEL_LEN;
                    m_Layer_Top.addChild(bmp);
                }
            }

            //プレイヤー
            {
                m_Player = new Player();

                m_Layer_Mid_Sort.addChild(m_Player);
            }

            //Update
            {
                addEventListener(Event.ENTER_FRAME, Update);
            }

            //画像ロード開始
            {
                const LoadFunc:Function = function(in_URL:String, in_OnLoad:Function):void{
                    var loader:Loader = new Loader();
                    loader.load(new URLRequest(in_URL), new LoaderContext(true));//画像のロードを開始して
                    loader.contentLoaderInfo.addEventListener(
                        Event.COMPLETE,//ロードが完了したら
                        function(e:Event):void{
                            in_OnLoad(loader.content);//初期化に入る
                        }
                    );
                }

                LoadFunc(URL_BLOCKS, OnLoadEnd_Blocks);
                LoadFunc(URL_PLAYER, OnLoadEnd_Player);
            }

            //残りはResetと同じ処理
            {
                Reset();
            }

/*
            //Debug
            {
                var debugDraw:b2DebugDraw = new b2DebugDraw();
                debugDraw.m_sprite = m_Layer_Debug;//this;
                debugDraw.m_drawScale = PHYS_SCALE;
                debugDraw.m_fillAlpha = 0.6;
                debugDraw.m_lineThickness = 1;
                debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit;
                m_Box2D_World.SetDebugDraw(debugDraw);
            }
//*/
        }

        //Reset
        public function Reset():void{
            //プレイヤー
            {
                m_Player.SetPos(m_PlayerX, m_PlayerY);
            }
        }

        //Init : Terrain Collision
        public function Init_Terrain_Collision():void{
            var x:int;
            var y:int;
            var r:Rectangle;

            //コリジョンリスト
            var RectList:Vector.<Rectangle> = new Vector.<Rectangle>();
            {
                //現在の行のコリジョン
                var RectList_Now:Vector.<Rectangle> = new Vector.<Rectangle>(MAP_NUM_X);
                //結合するため、一時的に溜めておく
                var RectList_Pre:Vector.<Rectangle> = new Vector.<Rectangle>(MAP_NUM_X);

                for(y = 0; y < MAP_NUM_Y; y++){
                    r = null;

                    //まずはこの行のまとめられるところをまとめる
                    for(x = 0; x < MAP_NUM_X; x++){
                        var index:int = m_Map[y][x];

                        if(index == W){
                            if(r == null){
                                r = new Rectangle(x*PANEL_LEN, y*PANEL_LEN, PANEL_LEN, PANEL_LEN);
                                RectList_Now[x] = r;
                            }else{
                                r.width += PANEL_LEN;
                            }
                        }else{
                            r = null;
                        }
                    }

                    //前回の結果と統合できるなら統合する
                    for(x = 0; x < MAP_NUM_X; x++){
                        if(RectList_Pre[x] != null){//前回の結果と
                            if(RectList_Now[x] != null){//今回の結果で同じ始点のものがあり
                                if(RectList_Pre[x].width == RectList_Now[x].width){//幅が同じなら
                                    //統合する
                                    RectList_Pre[x].height += PANEL_LEN;
                                    RectList_Now[x] = null;
                                    continue;
                                }
                            }

                            //前回の結果が統合できない場合、もう統合することもないのでResultに入れてしまう
                            RectList.push(RectList_Pre[x]);
                        }

                        //今回の結果を前回の結果の方に移す
                        RectList_Pre[x] = RectList_Now[x];
                        RectList_Now[x] = null;
                    }
                }

                //残っているやつをResultに移す
                for(x = 0; x < MAP_NUM_X; x++){
                    if(RectList_Pre[x] != null){
                        RectList.push(RectList_Pre[x]);
                    }
                }
            }

            //実際に作成
            {
                //まずは地形用のBodyを一つだけ作成
                var body:b2Body;
                {
                    body = m_Box2D_World.CreateBody(new b2BodyDef());
                }

                //作成するShapeのベースを作成
                var shapeDef:b2PolygonDef;
                {
                    shapeDef = new b2PolygonDef();
                    shapeDef.density = 0;//Fix
                }

                //あとはリストの形状を追加していく
                var w:Number;
                var h:Number;
                var center:b2Vec2 = new b2Vec2();
                var ColNum:int = RectList.length;
                for(var i:int = 0; i < ColNum; i++){
                    r = RectList[i];

                    w = IMAGE_to_PHYS(r.width/2);
                    h = IMAGE_to_PHYS(r.height/2);
                    center.x = IMAGE_to_PHYS(r.x) + w;
                    center.y = IMAGE_to_PHYS(r.y) + h - IMAGE_to_PHYS(PANEL_H/2);//見た目に合わせて、少し位置をズラす

                    shapeDef.SetAsOrientedBox(w, h, center);
                    body.CreateShape(shapeDef);
                }

                //一応、追加したShapeに合わせてMassを計算(Fixなので不要かもしれない)
                body.SetMassFromShapes();
            }

/*
            //Debug
            var sprite:Sprite = new Sprite();
            m_Layer_Debug.addChild(sprite);
            var g:Graphics = sprite.graphics;
            g.lineStyle(3,0x00FFFF,1.0);
            for(i = 0; i < ColNum; i++){
                r = RectList[i];

                g.drawRect(r.x, r.y, r.width, r.height);
            }
//*/
        }

        //OnLoad : Blocks
        public function OnLoadEnd_Blocks(in_Graphic:DisplayObject):void{
            //Init ImageManager
            {
                ImageManager.SetImage(in_Graphic);//それを保持した後
            }

            //今の表示のスクリーンショットを撮っておいて、α減衰させつつ画像表示に移行させてみる
            {
                var bmd:BitmapData = new BitmapData(VIEW_W, VIEW_H, false, 0x000000);
                bmd.draw(m_Layer_Root, new Matrix(1,0,0,1, m_Layer_Root.x,m_Layer_Root.y));

                var bmp:Bitmap = new Bitmap(bmd);
                addChild(bmp);

                addEventListener(Event.ENTER_FRAME, function f(e:Event):void{
                    var DeltaAlpha:Number = 5 * 1.0/30.0;
                    bmp.alpha -= DeltaAlpha;
                    if(bmp.alpha <= 0){
                        removeChild(bmp);
                        removeEventListener(Event.ENTER_FRAME, f);
                    }
                });
            }

            //ブロック描画
            {
                ImageManager.Map_to_Bitmap(
                    m_Map,
                    m_BitmapData_Ceil,
                    m_BitmapData_Wall,
                    m_BitmapData_Floor
                );
            }
        }

        //OnLoad : Player
        public function OnLoadEnd_Player(in_Graphic:DisplayObject):void{
            var index_x:int;
            var index_y:int;
            var bmd:BitmapData;
            var mtx:Matrix = new Matrix(1,0,0,1, 0,0);
            var rect:Rectangle = new Rectangle(0,0, PANEL_W,PANEL_H);

            //プレイヤー画像
            {
                for(index_x = 0; index_x < PANEL_NUM_X; index_x++){
                    for(index_y = 0; index_y < PANEL_NUM_Y; index_y++){
                        bmd = Player.m_BitmapDataList[index_y][index_x];
                        //Clear
                        bmd.fillRect(rect, 0x00000000);
                        //Draw
                        mtx.tx = -index_x*PANEL_W;
                        mtx.ty = -index_y*PANEL_H;
                        bmd.draw(in_Graphic, mtx);
                    }
                }
            }
        }


        //Update
        public function Update(e:Event=null):void{
            //今回進める時間
            var DeltaTime:Number = 1.0/30.0;

            //物理まわりの更新
            Update_Phys(DeltaTime);

            //Player
            m_Player.Update(DeltaTime);

            //Camera
            Update_Camera();
        }

        //物理まわりの更新
        public function Update_Phys(in_DeltaTime:Number):void{
            //マウスのところに移動
            //m_MouseJoint.SetTarget(new b2Vec2(IMAGE_to_PHYS(mouseX), IMAGE_to_PHYS(mouseY)));

            //物理エンジンをDeltaTimeだけ進める
            m_Box2D_World.Step(in_DeltaTime, 10);

            //
            for(var b:b2Body = m_Box2D_World.m_bodyList; b; b = b.m_next){
                //画像との同期
                if(b.m_userData != null){
                    var sprite:Sprite = b.m_userData as Sprite;
                    sprite.x = PHYS_to_IMAGE(b.GetPosition().x);
                    sprite.y = PHYS_to_IMAGE(b.GetPosition().y);
                    //b.m_userData.m_VX = PHYS_to_IMAGE(b.m_linearVelocity.x);
                    //b.m_userData.m_VY = PHYS_to_IMAGE(b.m_linearVelocity.y);

                    sprite.rotation = b.GetAngle() * 180/Math.PI;
                }

                //擬似摩擦
                {
                    const Ratio:Number = 0.9;//本当はDeltaTime依存の値にした方が良い
                    b.GetLinearVelocity().x *= Ratio;
                    b.GetLinearVelocity().y *= Ratio;
                    b.SetAngularVelocity(b.GetAngularVelocity() * Ratio);
                }
            }
        }

        //Update : Camera
        public function Update_Camera():void{
            var PlayerX:int = m_Player.x;
            var PlayerY:int = m_Player.y;

            //移動量
            var CameraMoveX:int = 0;
            var CameraMoveY:int = 0;
            {
                //現在のカメラでのプレイヤー相対位置
                var RelPlayerX:Number = PlayerX + m_Layer_Root.x;
                var RelPlayerY:Number = PlayerY + m_Layer_Root.y;

                //中央からの差がそのまま移動量
                CameraMoveX = VIEW_W/2 - RelPlayerX;
                CameraMoveY = VIEW_H/2 - RelPlayerY;
            }

            //目標値
            var RootX:int = m_Layer_Root.x + CameraMoveX;
            var RootY:int = m_Layer_Root.y + CameraMoveY;
            {
                //端制限
                if(RootX < -MAP_W + VIEW_W){
                    RootX = -MAP_W + VIEW_W;
                }
                if(RootX > 0){
                    RootX = 0;
                }
                if(RootY < -MAP_H + VIEW_H + PANEL_LEN){//天井を1パネル上にズラしているので、その分カメラの範囲も狭める
                    RootY = -MAP_H + VIEW_H + PANEL_LEN;
                }
                if(RootY > 0){
                    RootY = 0;
                }
            }

            m_Layer_Root.x = RootX;
            m_Layer_Root.y = RootY;
        }

        //#IsGameOver
        public function IsEnd():Boolean{
            //return (m_Mode != MODE_MAIN);
            return false;
        }
    }
}


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

//Box2D
import Box2D.Dynamics.*;
import Box2D.Collision.*;
import Box2D.Collision.Shapes.*;
import Box2D.Common.*;
import Box2D.Common.Math.*;
import Box2D.Dynamics.Joints.*;

class ImageManager
{
    //==Const==

    //Alias
    static public const PANEL_LEN:int = GameMain.PANEL_LEN;

    //地形のタイルの大きさ
    static public const TILE_LEN:int = PANEL_LEN/2;

    //考慮するBitmapの最大の大きさ(DisplacementMapFilterの制約上、0x80以上の移動が必要なものはムリ)
    static public const MAX_W:int = 0x80 * TILE_LEN;//PANEL_LENに換算すると、0x40=64個が限界
    static public const MAX_H:int = 0x80 * TILE_LEN;

    //Dispの基本移動で左上隅に移動した後、実際のタイルを参照するための移動値
    //タイルの並びは以下の通り(Fは床なので天井用のDISPでは使わない)
    //YYFFXX
    //YYFFXX
    //OOUU__
    //OOUU__
    //LLWWRR
    //LLWWRR
    //__DD__
    //__DD__
    //LUCURU
    //LUCURU
    //LDCDRD
    //LDCDRD
    static public const DISP_Y:uint = 0x0000;
    static public const DISP_F:uint = 0x0100;
    static public const DISP_X:uint = 0x0200;
    static public const DISP_O:uint = 0x0001;
    static public const DISP_U:uint = 0x0101;
    static public const DISP_L:uint = 0x0002;
    static public const DISP_W:uint = 0x0102;
    static public const DISP_R:uint = 0x0202;
    static public const DISP_D:uint = 0x0103;
    static public const DISP_WLU:uint = 0x0004;
    static public const DISP_WCU:uint = 0x0104;
    static public const DISP_WRU:uint = 0x0204;
    static public const DISP_WLD:uint = 0x0005;
    static public const DISP_WCD:uint = 0x0105;
    static public const DISP_WRD:uint = 0x0205;

    //Dispでタイルに置き換えるための基本移動値
    static public var m_Bitmapdata_MoveBase:BitmapData = new BitmapData(MAX_W, MAX_H, false, 0x000000);

    //Dispで置き換えるタイル画像の一覧
    static public const m_BitmapData_List:BitmapData = new BitmapData(MAX_W, MAX_H, true, 0xFF440000);

    //01のMAPの境界の値を求めるためのConv
    static public const FILTER_CONV_CEIL:ConvolutionFilter = new ConvolutionFilter(
        3,3,//Num
        [
            -0x01, 0x10,-0x02,
             0x30, 0xAF,-0x30,
            -0x04,-0x10,-0x08,
        ],
        1,//Divisor
        -0x50//Bias
    );

    //01のMAPの境界の値を求めるためのConv
    static public const FILTER_CONV_WALL:ConvolutionFilter = new ConvolutionFilter(
        3,3,//Num
        [
            0, 0, 0,
            1, 4,-1,
            0,-4, 0,
        ],
        1,//Divisor
        -0x10//Bias
    );
    static public const FILTER_CONV_WALL_SPREAD:ConvolutionFilter = new ConvolutionFilter(
        1,3,//Num
        [
            0,
            1,
            3,
        ]
    );//Matrixを一つ上にズラして、ColorTransformでオフセットを加えて描画した方が汎用性は高いが

    //Convで求めた値を、Dispで使う値に変換するためのパレット
    static public var CONV_to_DISP_CEIL:Array = new Array(256);
    static public var CONV_to_DISP_WALL:Array = new Array(256);
    static public var ZERO_PALETTE:Array = new Array(256);

    //Util
    static public const MTX_x2:Matrix = new Matrix(2,0,0,2);
    static public const MTX_x4:Matrix = new Matrix(4,0,0,4);
//    static public const MTX_xTile:Matrix = new Matrix(TILE_LEN,0,0,TILE_LEN);
//    static public const MTX_xTileHalf:Matrix = new Matrix(TILE_LEN/2,0,0,TILE_LEN/2);
    static public const POS_ZERO:Point = new Point(0,0);

    //Debug
    static public var DISP_DEBUG:Array = new Array(256);


    //==Function==

    //初期化
    static public function Init():void
    {
        var i:int;
        var x:int;
        var y:int;

        //Disp用の基本移動値
        //m_Bitmapdata_MoveBase
        {
            for(x = 0; x < MAX_W; x++){
                var index_x:int = x%0x80;
                var g:uint = 0x80 - index_x;

                for(y = 0; y < MAX_H; y++){
                    var index_y:int = y%0x80;
                    var b:uint = 0x80 - index_y;

                    var val:uint = (g << 8) | (b << 0);
                    m_Bitmapdata_MoveBase.setPixel(x, y, val);
                }
            }
        }

        //Convの値をDisp用の値に変換するためのパレット
        //CONV_to_DISP_CEIL
        for(i = 0; i < 256; i++){
            switch(i & 0xF0){
            case 0x20: CONV_to_DISP_CEIL[i] = DISP_L; break;
            case 0x40: CONV_to_DISP_CEIL[i] = DISP_U; break;
            case 0x60: CONV_to_DISP_CEIL[i] = DISP_D; break;
            case 0x80: CONV_to_DISP_CEIL[i] = DISP_R; break;

            case 0x10:
            case 0x30:
            case 0x70:
            case 0x90: CONV_to_DISP_CEIL[i] = DISP_Y; break;

            case 0x50:
                if(i == 0x50){CONV_to_DISP_CEIL[i] = DISP_W;}
                else         {CONV_to_DISP_CEIL[i] = DISP_X;}
                break;

            case 0x00: CONV_to_DISP_CEIL[i] = DISP_O;

            //上以外は使わないが、一応初期化
            default:  CONV_to_DISP_CEIL[i] = DISP_O; break;
            }
        }

        //CONV_to_DISP_WALL
        for(i = 0; i < 256; i++){
            switch(i){
            case 0x20: CONV_to_DISP_WALL[i] = DISP_WLD; break;
            case 0x30: CONV_to_DISP_WALL[i] = DISP_WCD; break;
            case 0x40: CONV_to_DISP_WALL[i] = DISP_WRD; break;

            case 0x60: CONV_to_DISP_WALL[i] = DISP_WLU; break;
            case 0x90: CONV_to_DISP_WALL[i] = DISP_WCU; break;
            case 0xC0: CONV_to_DISP_WALL[i] = DISP_WRU; break;

//            case 0x0D: CONV_to_DISP_WALL[i] = DISP_WLD_H; break;
//            case 0x1D: CONV_to_DISP_WALL[i] = DISP_WCD_H; break;
//            case 0x2D: CONV_to_DISP_WALL[i] = DISP_WRD_H; break;

            default: CONV_to_DISP_WALL[i] = DISP_O; break;
            }
        }

        //ZERO_PALETTE
        for(i = 0; i < 256; i++){
            ZERO_PALETTE[i] = 0;
        }

        //Dispで置き換えるタイルの一覧
        //m_BitmapData_List
        {
            //以下のような並びになるように描画する
            //YYFFXX
            //YYFFXX
            //OOUU__
            //OOUU__
            //LLWWRR
            //LLWWRR
            //__DD__
            //__DD__

            //ただし、画像をロードするまで実際の描画はムリなので、ひとまず仮で描画しておく
            //- ロード失敗時の描画を兼ねる

            //Y
            m_BitmapData_List.fillRect(new Rectangle(0,0,TILE_LEN,TILE_LEN), 0xFFFFFFFF);
            m_BitmapData_List.fillRect(new Rectangle(2,2,TILE_LEN-4,TILE_LEN-4), 0xFF330000);

            //F
            m_BitmapData_List.fillRect(new Rectangle(TILE_LEN,0,TILE_LEN,TILE_LEN), 0xFF888888);

            //X
            m_BitmapData_List.fillRect(new Rectangle(2*TILE_LEN,0,TILE_LEN,TILE_LEN), 0xFF550000);
            m_BitmapData_List.fillRect(new Rectangle(2*TILE_LEN,0,2,2), 0xFFFFFFFF);//LU
            m_BitmapData_List.fillRect(new Rectangle(3*TILE_LEN-2,0,2,2), 0xFFFFFFFF);//RU
            m_BitmapData_List.fillRect(new Rectangle(2*TILE_LEN,TILE_LEN-2,2,2), 0xFFFFFFFF);//LD
            m_BitmapData_List.fillRect(new Rectangle(3*TILE_LEN-2,TILE_LEN-2,2,2), 0xFFFFFFFF);//RD

            //O
            m_BitmapData_List.fillRect(new Rectangle(0,TILE_LEN,TILE_LEN,TILE_LEN), 0x00000000);

            //U
            m_BitmapData_List.fillRect(new Rectangle(TILE_LEN,TILE_LEN,TILE_LEN,2), 0xFFFFFFFF);
            //L
            m_BitmapData_List.fillRect(new Rectangle(0,2*TILE_LEN,2,TILE_LEN), 0xFFFFFFFF);
            //R
            m_BitmapData_List.fillRect(new Rectangle(TILE_LEN*3-2,2*TILE_LEN,2,TILE_LEN), 0xFFFFFFFF);
            //D
            m_BitmapData_List.fillRect(new Rectangle(TILE_LEN,4*TILE_LEN-2,TILE_LEN,2), 0xFFFFFFFF);

            //
            m_BitmapData_List.fillRect(new Rectangle(0,4*TILE_LEN,3*TILE_LEN,2*TILE_LEN), 0xFF888888);
            m_BitmapData_List.fillRect(new Rectangle(0,4*TILE_LEN,3*TILE_LEN,1.5*TILE_LEN), 0xFFCCCCCC);
        }

        //DISP_DEBUG
        {
            for(i = 0; i < 256; i++){
                switch(i){
                case 00: DISP_DEBUG[i] = 0xFF0000; break;
                case 01: DISP_DEBUG[i] = 0x00FF00; break;
                case 02: DISP_DEBUG[i] = 0x0000FF; break;
                default: DISP_DEBUG[i] = 0x000000; break;
                }
            }
        }
    }

    //画像設定
    static public function SetImage(in_Graphic:DisplayObject):void
    {
        //以下のような並びになるように描画する
        //YYFFXX
        //YYFFXX
        //OOUU__
        //OOUU__
        //LLWWRR
        //LLWWRR
        //__DD__
        //__DD__

        var mtx:Matrix = new Matrix();
        var len:int = 16;
        var rect:Rectangle = new Rectangle(0,0,len,len);

        //Base
        m_BitmapData_List.draw(in_Graphic, mtx);

        //O
        m_BitmapData_List.fillRect(new Rectangle(0,TILE_LEN,TILE_LEN,TILE_LEN), 0x00000000);
    }

    //MAPの要素を元に地形を描画してBitmapDataに描き込む処理
    static public function Map_to_Bitmap(
        in_Map:Vector.<Vector.<int> >,
        out_BitmapData_Ceil:BitmapData,
        out_BitmapData_Wall:BitmapData,
        out_BitmapData_Floor:BitmapData
    ):void
    {
        var NumX:int = in_Map[0].length;
        var NumY:int = in_Map.length;

        //まずはMAPの要素を、処理しやすいようにBitmapDataに格納する
        var bmd_ori:BitmapData = new BitmapData(NumX, NumY, false, 0x000000);
        {
            for(var x:int = 0; x < NumX; x++){
                for(var y:int = 0; y < NumY; y++){
                    bmd_ori.setPixel(x, y, in_Map[y][x]);//Blueの値としてIndexが入る
                }
            }
        }

        //作業用のBitmapを用意
        var bmd_util1:BitmapData = new BitmapData(NumX * PANEL_LEN, NumY * PANEL_LEN, false, 0x000000);
        var bmd_util2:BitmapData = new BitmapData(NumX * PANEL_LEN, NumY * PANEL_LEN, false, 0x000000);
        var rect_dot:Rectangle = new Rectangle(0,0, NumX, NumY);
        var rect_2dot:Rectangle = new Rectangle(0,0, 2*NumX, 2*NumY);
        var rect_4dot:Rectangle = new Rectangle(0,0, 4*NumX, 4*NumY);
        var rect_panel:Rectangle = new Rectangle(0,0, NumX * PANEL_LEN, NumY * PANEL_LEN);
        const DOT_to_PANEL:Matrix = new Matrix(PANEL_LEN,0,0,PANEL_LEN);

        //Ceil
        {
            //debug
            //out_BitmapData_Ceil.paletteMap(bmd_ori, rect_dot, POS_ZERO, ZERO_PALETTE,DISP_DEBUG,DISP_DEBUG);

/*
            W W W W W W W W
            W W W O O W W W
            W W W O O W W W
            W O O O O O O W
            W O O O O O O W
            W W W O O W W W
            W W W O O W W W
            W W W W W W W W
*/

            //まずは「壁=1」「それ以外=0」とする
            //ori => util1
            {
                bmd_util1.fillRect(rect_dot, 0);//初回なので不要だが一応
                bmd_util1.threshold(bmd_ori, rect_dot, POS_ZERO, "==", GameMain.W, 0xFF000001, 0xFF);
                //セットする値は「1」だが、、αが0だと何もセットされないので「0xFF000000」も加える
            }

            //debug
            //out_BitmapData_Ceil.paletteMap(bmd_util1, rect_panel, POS_ZERO, ZERO_PALETTE,DISP_DEBUG,DISP_DEBUG);

/*
            1 1 1 1 1 1 1 1
            1 1 1 O O 1 1 1
            1 1 1 O O 1 1 1
            1 O O O O O O 1
            1 O O O O O O 1
            1 1 1 O O 1 1 1
            1 1 1 O O 1 1 1
            1 1 1 1 1 1 1 1
*/
            //それを4倍にする
            //util1 => util2
            {
                bmd_util2.fillRect(rect_panel, 1);//範囲外は壁とする
                bmd_util2.draw(bmd_util1, MTX_x4, null, null, rect_4dot);
            }

            //debug
//            out_BitmapData_Ceil.paletteMap(bmd_util2, rect_panel, POS_ZERO, ZERO_PALETTE,DISP_DEBUG,DISP_DEBUG);

/*//面倒なので2倍のやつで示す
            1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
            1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
            1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1
            1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1
            1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1
            1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1
            1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1
            1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1
            1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1
            1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1
            1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1
            1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1
            1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1
            1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1
            1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
            1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
*/

            //壁と地面の境界付近を専用のパネルにするため、ConvolutionFilterで計算する
            //util2 => util1
            {
                bmd_util1.applyFilter(bmd_util2, rect_4dot, POS_ZERO, FILTER_CONV_CEIL);
            }

/*//「0x」は省略
            50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
            50 50 50 50 50 08 68 6C 6C 64 04 50 50 50 50 50
            50 50 50 50 50 88 00 00 00 00 24 50 50 50 50 50
            50 50 50 50 50 8A 00 00 00 00 25 50 50 50 50 50
            50 50 50 50 50 8A 00 00 00 00 25 50 50 50 50 50
            50 08 68 6C 6C 9E 00 00 00 00 3D 6C 6C 64 04 50
            50 88 00 00 00 00 00 00 00 00 00 00 00 00 24 50
            50 8A 00 00 00 00 00 00 00 00 00 00 00 00 25 50
            50 8A 00 00 00 00 00 00 00 00 00 00 00 00 25 50
            50 82 00 00 00 00 00 00 00 00 00 00 00 00 21 50
            50 02 42 43 43 7B 00 00 00 00 17 43 43 41 01 50
            50 50 50 50 50 8A 00 00 00 00 25 50 50 50 50 50
            50 50 50 50 50 8A 00 00 00 00 25 50 50 50 50 50
            50 50 50 50 50 82 00 00 00 00 21 50 50 50 50 50
            50 50 50 50 50 02 42 43 43 41 01 50 50 50 50 50
            50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50
*/

            //Convの値をDisp用の値に変換する
            //util1 => util2
            {
                bmd_util2.paletteMap(bmd_util1, rect_4dot, POS_ZERO, ZERO_PALETTE,ZERO_PALETTE,CONV_to_DISP_CEIL);
            }

            //debug
//            out_BitmapData_Ceil.paletteMap(bmd_util2, rect_panel, POS_ZERO, ZERO_PALETTE,DISP_DEBUG,DISP_DEBUG);

/*
            W W W W W W W W W W W W W W W W
            W W W W W X D D D D X W W W W W
            W W W W W R O O O O L W W W W W
            W W W W W R O O O O L W W W W W
            W W W W W R O O O O L W W W W W
            W X D D D Y O O O O Y D D D X W
            W R O O O O O O O O O O O O L W
            W R O O O O O O O O O O O O L W
            W R O O O O O O O O O O O O L W
            W R O O O O O O O O O O O O L W
            W X U U U Y O O O O Y U U U X W
            W W W W W R O O O O L W W W W W
            W W W W W R O O O O L W W W W W
            W W W W W R O O O O L W W W W W
            W W W W W X U U U U X W W W W W
            W W W W W W W W W W W W W W W W
*/

            //Dispの事前準備
            //util2 => util1
            {
                //基本的な移動値を加える(これが左上隅への移動値になり、上で求めた値がそこからパネル位置への移動値となる)
                bmd_util2.draw(m_Bitmapdata_MoveBase, MTX_x2, null, BlendMode.ADD, rect_4dot);

                //パネルの大きさになるように拡大する(すでに2倍しているので、PANEL_LEN/2倍する)
/*
                bmd_util1.draw(bmd_util2, MTX_xTileHalf, null, BlendMode.NORMAL, rect_panel);
                //→うまくいかなかった(いきなり8倍するのはダメ?)
/*/
                bmd_util1.draw(bmd_util2, MTX_x2, null, BlendMode.NORMAL, rect_panel);//x8
                bmd_util2.draw(bmd_util1, MTX_x2, null, BlendMode.NORMAL, rect_panel);//x16
                bmd_util1.draw(bmd_util2, MTX_x2, null, BlendMode.NORMAL, rect_panel);//x32
//*/
            }

            //DisplacementMapFilterをかけて、実際の表示を描く
            //util1 => trg
            {
                var FILTER_DISP_CEIL:DisplacementMapFilter = new DisplacementMapFilter(
                    bmd_util1,
                    null,//POS_ZERO,
                    BitmapDataChannel.GREEN,
                    BitmapDataChannel.BLUE,
                    0x100*TILE_LEN, 0x100*TILE_LEN,
                    DisplacementMapFilterMode.CLAMP
                );

                out_BitmapData_Ceil.applyFilter(m_BitmapData_List, rect_panel, POS_ZERO, FILTER_DISP_CEIL);
            }

            //debug
//            out_BitmapData_Ceil.copyPixels(m_BitmapData_List, rect_panel, POS_ZERO);
//            out_BitmapData_Ceil.paletteMap(bmd_util1, rect_panel, POS_ZERO, null,null,DISP_DEBUG);
//            out_BitmapData_Ceil.paletteMap(bmd_util2, rect_panel, POS_ZERO, null,null,DISP_DEBUG);
//            out_BitmapData_Ceil.copyPixels(m_Bitmapdata_MoveBase, rect_panel, POS_ZERO);
//            out_BitmapData_Ceil.copyPixels(bmd_util2, rect_panel, POS_ZERO);
//            out_BitmapData_Ceil.copyPixels(bmd_util1, rect_panel, POS_ZERO);
        }//end ceil

        //Floor
        {
            //ひとまず地面だけ対応(将来的には穴の対応もしたい)

            //WをDISP_O、それ以外をDISP_Fにする
            //ori => util1
            {
                bmd_util1.fillRect(rect_dot, DISP_F);
                bmd_util1.threshold(bmd_ori, rect_dot, POS_ZERO, "==", GameMain.W, 0xFF000000 | DISP_O, 0xFF);
            }

            //debug
            //out_BitmapData_Floor.paletteMap(bmd_util1, rect_panel, POS_ZERO, ZERO_PALETTE,DISP_DEBUG,DISP_DEBUG);//All Yellow

            //Dispの事前準備
            //util1 => util2
            {
                bmd_util2.draw(bmd_util1, MTX_x2, null, BlendMode.NORMAL, rect_panel);//x2

                bmd_util2.draw(m_Bitmapdata_MoveBase, null, null, BlendMode.ADD, rect_panel);

                bmd_util1.draw(bmd_util2, MTX_x4, null, BlendMode.NORMAL, rect_panel);//x8
                bmd_util2.draw(bmd_util1, MTX_x4, null, BlendMode.NORMAL, rect_panel);//x32
            }

            //debug
//            out_BitmapData_Floor.paletteMap(bmd_util2, rect_panel, POS_ZERO, ZERO_PALETTE,DISP_DEBUG,DISP_DEBUG);//All Yellow

            //DisplacementMapFilterをかけて、実際の表示を描く
            //util1 => trg
            {
                var FILTER_DISP_FLOOR:DisplacementMapFilter = new DisplacementMapFilter(
                    bmd_util2,
                    null,//POS_ZERO,
                    BitmapDataChannel.GREEN,
                    BitmapDataChannel.BLUE,
                    0x100*TILE_LEN, 0x100*TILE_LEN,
                    DisplacementMapFilterMode.CLAMP
                );

                out_BitmapData_Floor.applyFilter(m_BitmapData_List, rect_panel, POS_ZERO, FILTER_DISP_FLOOR);
            }
        }//end Floor

        //Wall
        {
            //Wを0x10に、それ以外を0x00にする(将来的には穴を0x01にする)
            //ori => util1
            {
                bmd_util1.fillRect(rect_dot, 0);
                bmd_util1.threshold(bmd_ori, rect_dot, POS_ZERO, "==", GameMain.W, 0xFF000010, 0xFF);
            }

            //Debug
            //out_BitmapData_Wall.paletteMap(bmd_util1, rect_panel, POS_ZERO, ZERO_PALETTE,DISP_DEBUG,DISP_DEBUG);//All Red
            //out_BitmapData_Wall.paletteMap(bmd_util1, rect_panel, POS_ZERO, ZERO_PALETTE,ZERO_PALETTE,DISP_DEBUG);//Wall=Black, Else=Red

            //2倍にする
            //util1 => util2
            {
                bmd_util2.draw(bmd_util1, MTX_x2, null, BlendMode.NORMAL, rect_2dot);//x2
            }

            //壁を生成する部分だけを非ゼロの値になるようにする
            //util2 => util1
            {
                bmd_util1.applyFilter(bmd_util2, rect_2dot, POS_ZERO, FILTER_CONV_WALL);
            }

            //さらに上に伸ばす
            //util1 => util2
            {
                bmd_util2.applyFilter(bmd_util1, rect_2dot, POS_ZERO, FILTER_CONV_WALL_SPREAD);
            }

            //Debug
            //out_BitmapData_Wall.paletteMap(bmd_util2, rect_panel, POS_ZERO, ZERO_PALETTE,ZERO_PALETTE,DISP_DEBUG);

            //求めた値をDisp用の値に変換する
            //util2 => util1
            {
                bmd_util1.paletteMap(bmd_util2, rect_2dot, POS_ZERO, ZERO_PALETTE,ZERO_PALETTE, CONV_to_DISP_WALL);
            }

            //Debug
            //out_BitmapData_Wall.paletteMap(bmd_util1, rect_panel, POS_ZERO, ZERO_PALETTE,DISP_DEBUG,DISP_DEBUG);

            //Dispの事前準備
            //util1 => util1
            {
                bmd_util1.draw(m_Bitmapdata_MoveBase, null, null, BlendMode.ADD, rect_panel);

                bmd_util2.draw(bmd_util1, MTX_x4, null, BlendMode.NORMAL, rect_panel);//x8
                bmd_util1.draw(bmd_util2, MTX_x4, null, BlendMode.NORMAL, rect_panel);//x32
            }

            //DisplacementMapFilterをかけて、実際の表示を描く
            //util1 => trg
            {
                var FILTER_DISP_WALL:DisplacementMapFilter = new DisplacementMapFilter(
                    bmd_util1,
                    null,//POS_ZERO,
                    BitmapDataChannel.GREEN,
                    BitmapDataChannel.BLUE,
                    0x100*TILE_LEN, 0x100*TILE_LEN,
                    DisplacementMapFilterMode.CLAMP
                );

                out_BitmapData_Wall.applyFilter(m_BitmapData_List, rect_panel, POS_ZERO, FILTER_DISP_WALL);
            }
        }//end Wall
    }
}


//#Player
class Player extends Sprite
{
    //==Const==

    //アニメーション用定数
    static public const ANIM_DIR_U:int = 0;
    static public const ANIM_DIR_R:int = 1;
    static public const ANIM_DIR_D:int = 2;
    static public const ANIM_DIR_L:int = 3;

    //アニメーション用パラメータ
    static public const ANIM_CYCLE:Number = 1.0;
    static public const ANIM_ITER:Array = [0,1,2,1];
    static public const ANIM_NUM:int = ANIM_ITER.length;


    //==Static==

    //画像
    static public var m_BitmapDataList:Array;

    //Init
    static public function Initialize():void{
        //m_BitmapDataList
        {
            m_BitmapDataList = new Array(GameMain.PANEL_NUM_Y);
            for(var y:int = 0; y < GameMain.PANEL_NUM_Y; y++){
                m_BitmapDataList[y] = new Array(GameMain.PANEL_NUM_X);
                for(var x:int = 0; x < GameMain.PANEL_NUM_X; x++){
                    m_BitmapDataList[y][x] = new BitmapData(GameMain.PANEL_W, GameMain.PANEL_H, true, 0x80FFFFFF);
                }
            }
        }
    }


    //==Var==

    //グラフィック
    public var m_Bitmap:Bitmap = new Bitmap();
    //アニメーションの方向
    public var m_AnimDir:int = 0;
    //アニメーション用タイマー
    public var m_AnimTimer:Number = 0.0;

    //死亡フラグ
    public var m_IsDead:Boolean = false;

    //コリジョン
    public var m_Body:b2Body;

    //==Function==

    //Init
    public function Player(){
        //プレイヤーグラフィック
        {
            m_Bitmap.x = -GameMain.PANEL_W/2;
            m_Bitmap.y = -GameMain.PANEL_H*3/4;
            addChild(m_Bitmap);
        }

        //コリジョン
        {
            //Shape Def
            var shapeDef:b2CircleDef;
            {
                shapeDef = new b2CircleDef();
                shapeDef.radius = GameMain.IMAGE_to_PHYS(GameMain.PANEL_W/2 * 0.8);
                shapeDef.density = 1;//tekitou
            }

            //Body Def
            var bodyDef:b2BodyDef;
            {
                bodyDef = new b2BodyDef();
                bodyDef.position.Set(GameMain.IMAGE_to_PHYS(this.x), GameMain.IMAGE_to_PHYS(this.y));
                bodyDef.fixedRotation = true;
            }

            //Body
            var body:b2Body;
            {
                body = GameMain.Instance.m_Box2D_World.CreateBody(bodyDef);
                body.CreateShape(shapeDef);
                body.SetMassFromShapes();
                body.m_userData = this;
            }

            m_Body = body;
        }
    }

    //Init : Pos
    public function SetPos(in_X:int, in_Y:int):void{
/*
        this.x = in_X;
        this.y = in_Y;
//*/
        m_Body.SetXForm(new b2Vec2(GameMain.IMAGE_to_PHYS(in_X), GameMain.IMAGE_to_PHYS(in_Y)), 0);
    }

    //Update
    public function Update(in_DeltaTime:Number):void{
        //死亡・ゴール時は何もしない
        if(GameMain.Instance.IsEnd()){
            return;
        }

        //移動
        Update_Move(in_DeltaTime);

        //グラフィック
        Update_Graphic(in_DeltaTime);

        //死亡チェック
        Check_Dead();
    }

    //Update : Graphic
    public function Update_Graphic(in_DeltaTime:Number):void{
        //m_AnimTimer
        {
            m_AnimTimer += in_DeltaTime;
            if(m_AnimTimer > ANIM_CYCLE){m_AnimTimer -= ANIM_CYCLE;}
        }

        //m_AnimTimer => iter
        var iter:int;
        {
            iter = ANIM_ITER[int(ANIM_NUM * m_AnimTimer/ANIM_CYCLE)];
        }

        m_Bitmap.bitmapData = m_BitmapDataList[m_AnimDir][iter];
    }

    //Check : Dead
    public function Check_Dead():void{
        //Check
        {
            if(m_IsDead){
                return;
            }
        }

/*
        //マップより下に行っていたら落下死する
        if(this.y > GameMain.MAP_H+GameMain.PANEL_LEN){
            //ゲームオーバー処理
            {
                GameMain.Instance.OnDead_Fall();
            }

            //フラグ
            {
                m_IsDead = true;
            }
        }
//*/
    }

    //Update : Move
    public function Update_Move(in_DeltaTime:Number):void{
//*
        //マウスで動かす
        const MOVE_POW:Number = 1000.0;

        const GAP_MIN:Number = GameMain.PANEL_W/2;
        const GAP_MAX:Number = GameMain.PANEL_LEN*1.5;

        var Gap:Vector3D = new Vector3D(
            GameMain.Instance.mouseX - (this.x + GameMain.Instance.m_Layer_Root.x),
            GameMain.Instance.mouseY - (this.y + GameMain.Instance.m_Layer_Root.y)
        );
        var GapLen:Number = Gap.length;

        if(GapLen < GAP_MIN){
            Gap.x = Gap.y = 0;
        }else{
            Gap.x /= GapLen;
            Gap.y /= GapLen;

            if(GapLen < GAP_MAX){
                Gap.x *= (GapLen - GAP_MIN) / (GAP_MAX - GAP_MIN);
                Gap.y *= (GapLen - GAP_MIN) / (GAP_MAX - GAP_MIN);
            }
        }

        var PowX:Number = GameMain.IMAGE_to_PHYS(MOVE_POW * Gap.x);
        var PowY:Number = GameMain.IMAGE_to_PHYS(MOVE_POW * Gap.y);

        m_Body.WakeUp();
        m_Body.m_force.x += PowX;
        m_Body.m_force.y += PowY;

        //ついでに向きもここで更新
        {
            var AbsGapX:Number = Math.abs(Gap.x);
            var AbsGapY:Number = Math.abs(Gap.y);

            if(AbsGapY < AbsGapX){
                if(Gap.x > 0){
                    m_AnimDir = ANIM_DIR_R;
                }else{
                    m_AnimDir = ANIM_DIR_L;
                }
            }else{
                if(Gap.y > 0){
                    m_AnimDir = ANIM_DIR_D;
                }else{
                    m_AnimDir = ANIM_DIR_U;
                }
            }
        }
//*/
    }

    //Utility
//    public function Lerp(in_Src:Number, in_Dst:Number, in_Ratio:Number):Number{
//        return (in_Src * (1 - in_Ratio)) + (in_Dst * in_Ratio);
//    }
}