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

アクトレイヤー(ActLayer)

遠近レイヤーを利用した2Dアクションの実験

操作方法
・十字キー(Arrow)
 ・移動(Move)&ジャンプ(Jump)
Get Adobe Flash player
by o_healer 26 Mar 2012
/**
 * 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/2cah
 */

/*
 「試作:アクトレイヤー(Test : Act Layer)」
 ・遠近レイヤーを利用した2Dアクションの実験

 操作方法
 ・十字キー(Arrow)
  ・移動(Move)&ジャンプ(Jump)
*/


/*
 メモ
 ・以下の問題の対応を保留してるのでかなりテキトーな仕上がり

 ・「1ドットずつ当たり判定をとって移動」という移動形式のため、Nearの地形が2倍で動くとめり込む可能性がある
  →Near側で1ドットずつ動くことにして、MainとFarでの移動を半減させる
  →プレイヤーの速度を倍加させることでMainベースであるかのように見せる
   →ステージの端でカメラが止まってしまうと倍速で動いているのが分かってしまう
    →実験なので端を作らないことでひとまず誤魔化す
     →端になってないとプレイヤーの初期位置の計算がわりと面倒
      →これもさらに適当に設定して誤魔化す
  →MAPが肥大化しすぎるのでカメラの端補正を切ることにした
 ・遠景に乗る際にがたつく
  ・こちらも対応が面倒なので修正は保留
*/

package {
    import flash.display.*;
    import flash.events.*;
    import flash.filters.*;
    import flash.geom.*;
    import flash.net.*;
    import flash.system.*;
    import flash.text.*;
 
    [SWF(width="465", height="465", frameRate="30", backgroundColor="0x000000")]
    public class GameMain extends Sprite {

        //==Const==
//*
        static public const URL_BLOCKS:String = "http://assets.wonderfl.net/images/related_images/e/e4/e466/e4667aa771860a2002c45728da23c52285814e86";
        static public const URL_PLAYER:String = "http://assets.wonderfl.net/images/related_images/9/93/9300/9300948516d99cd5853f485210378622249f0d7a";
/*/
        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;

        //マップ
        static public var m_MapIter:int = 0;
        static public const O:int = m_MapIter++;//空白
        static public const W:int = m_MapIter++;//壁
        static public const X:int = m_MapIter++;//トゲ(未対応)
        static public const P:int = m_MapIter++;//プレイヤー
        static public const G:int = m_MapIter++;//ゴール

        static public const MAP:Array = [
            [//Main
                [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,W,W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O],
                [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,W,W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O],
                [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,W,W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O],
                [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,W,W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O],
                [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,W,W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O],
                [W,W,W,O,O,W,W,W,W,W,W,W,W,W,W,W,O,W,W,W,W,W,W,O,O,W,W,O,W,W,W,W,W,W,W,O,O,O,O,O,O,O,O,O,O,O],
                [W,O,O,O,O,O,O,O,O,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,O,O,O,O,O,O,O,O,O],
                [W,W,W,W,W,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,O,O,O,O,O,O,O,O,O],
                [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,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O],
                [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,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O],
                [W,O,O,O,O,O,O,O,O,O,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,O,O,O,O,O,O,O,O],
                [W,O,O,O,O,O,O,O,O,O,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,O,O,O,O,O,O,O,O],
                [W,O,O,O,O,O,O,O,O,O,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,O,O,O,O,O,O,O,O],
                [W,W,O,W,W,O,W,W,W,O,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,O,O,W,O,O,O,O,O],
                [W,O,O,O,O,O,O,O,O,O,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,O,O,O,O,O,O,O,O],
                [W,W,W,W,W,W,O,O,O,O,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,O,O,O,O,O,O,O,O],
                [W,O,O,O,O,O,O,O,O,O,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,O,O,O,O,O,O,O,O],
                [W,O,O,O,O,O,O,O,O,O,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,O,O,O,O,O,O,O,O],
                [W,O,O,O,O,O,O,O,O,O,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,O,O,O,O,O,O,O,O],
                [W,O,O,O,O,O,O,O,O,O,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,O,O,O,O,O,O,O,O],
                [W,O,O,O,O,O,O,O,O,O,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,O,O,O,O,O,O,O,O],
                [W,W,W,W,W,W,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,O,O,O,O,O,O,O,O],
                [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,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O],
                [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,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O],
                [W,O,O,O,O,O,O,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,O,O,O,O,O,O,O,O,O,O,O],
                [W,O,O,O,O,O,O,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,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,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,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,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,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,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,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,O,O,O,O,O,O,O],
            ],
            [//Near
                [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,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,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,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,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,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,O,O,O,O,O,O,O,O,O,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,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,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,O,O,O,O,O,O,O,O,O,W,O],
                [O,O,O,O,O,O,W,W,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,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,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,W,O,O,O,O],
                [O,W,O,W,O,W,O,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,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,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,O,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,O,O,O,O,O,O,O,O,O,O,O,O,O,O],
                [O,O,O,O,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,O,O,O,O,O,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,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,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,O,O,O,O,O,O,O,O,O,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,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,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,O,O,O,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,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,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,O,O,O,O,W,O,O,O,O,O,O],
                [O,O,O,O,O,O,O,O,O,O,O,O,O,O,W,W,O,W,O,O,W,O,O,O,O,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,O,O,O,O,W,W,W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,W,O,O,O,O,O,O,O,O],
                [O,P,O,O,O,O,O,O,O,O,O,O,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,O],
                [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,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,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,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,O,O,O,O,O,O,O,O],
            ],
            [//Far
                [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,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,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,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,O,O,O,O,O,O,O,O,O,O,O,O,O,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,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,O,O,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,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,O,O,O,O,O,O,O,O,O,O,O,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,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,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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],
                [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,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,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,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,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,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,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,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,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,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,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,O,O,O,O,O,O,O,O,O,O,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,O,O,O,O,O,O,O,O,O,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,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,O,O,O,O,O,O,O,O,O,O,O,O,O,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,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,W,O,W,O,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,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,W,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,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,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,O,O,O,O,O,O,O,O,O,O,O,O,O,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,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,O,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,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,O,O,O,O,O,O,O,O,O,O,O,O,O,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],
                [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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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],
                [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,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,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,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,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,O,O,O],
            ],
        ];

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

        //モード
        static public var ModeIter:int = 0;
        static public const MODE_MAIN:int    = ModeIter++;
        static public const MODE_GOAL:int    = ModeIter++;
        static public const MODE_GAME_OVER:int    = ModeIter++;


        //==Var==

        //Pseudo Singleton
        static public var Instance:GameMain;

        //レイヤー
        public var m_Layer_Root:Sprite = new Sprite();
        public var  m_Layer_BG:Sprite = new Sprite();
        public var   m_Layer_Main:Sprite = new Sprite();
        public var  m_Layer_Player:Sprite = new Sprite();

        //画像
        public var m_BitmapData_BG:BitmapData = new BitmapData(VIEW_W, VIEW_H, false, 0x000000);
        public var m_BitmapData_Block_Main:BitmapData    = new BitmapData(PANEL_LEN * MAP[0][0].length, PANEL_LEN * MAP[0].length, true, 0x00000000);
        public var m_BitmapData_Block_Near:BitmapData    = new BitmapData(PANEL_LEN * MAP[1][0].length, PANEL_LEN * MAP[1].length, true, 0x00000000);
        public var m_BitmapData_Block_Far:BitmapData    = new BitmapData(PANEL_LEN * MAP[2][0].length/2, PANEL_LEN * MAP[2].length/2, true, 0x00000000);
        public var m_Bitmap_Block_Main:Bitmap;
        public var m_Bitmap_Block_Near:Bitmap;
        public var m_Bitmap_Block_Far:Bitmap;

        //プレイヤー
        public var m_Player:Player = new Player();

        //ゴール
        public var m_Goal:Goal;

        //テキスト
        public var m_Text:TextField = new TextField();

        //モード
        public var m_Mode:int = MODE_MAIN;

        //==Function==

        //Init
        public function GameMain():void {
            //Pseudo Singleton
            {
                Instance = this;
            }

            //背景色
            {
                addChild(new Bitmap(m_BitmapData_BG));
            }

            //Layer
            {
                //Root
                addChild(m_Layer_Root);

                {
                    //背景
                    m_Layer_Root.addChild(m_Layer_BG);

                    //プレイヤー
                    m_Layer_Root.addChild(m_Layer_Player);
                }
            }

            //背景
            {
                m_Bitmap_Block_Far = new Bitmap(m_BitmapData_Block_Far);
//                m_Bitmap_Block_Far.scaleX = 0.5001;//0.5だと消失
//                m_Bitmap_Block_Far.scaleY = 0.5001;
                m_Layer_BG.addChild(m_Bitmap_Block_Far);

                m_Bitmap_Block_Main = new Bitmap(m_BitmapData_Block_Main);
                //m_Layer_BG.addChild(m_Bitmap_Block_Main);
                m_Layer_BG.addChild(m_Layer_Main);
                m_Layer_Main.addChild(m_Bitmap_Block_Main);

                m_Bitmap_Block_Near = new Bitmap(m_BitmapData_Block_Near);
                m_Bitmap_Block_Near.scaleX = 2;
                m_Bitmap_Block_Near.scaleY = 2;
                m_Layer_BG.addChild(m_Bitmap_Block_Near);
            }

            //プレイヤー
            {
                m_Layer_Player.addChild(m_Player);
            }

            //Goal
            {
                m_Goal = new Goal();
                //m_Layer_BG.addChild(m_Goal);
                m_Layer_Main.addChild(m_Goal);
//*
                //決め打ち
                m_Goal.SetPos(
                    (2+0.5) * PANEL_LEN,
                    (20+0.5) * PANEL_LEN
                );
//*/
            }

            //MAPに応じた処理
            {
                var x:int;
                var y:int;
                for(y = 0; y < MAP[1].length; y++){
                    for(x = 0; x < MAP[1][0].length; x++){
                        switch(MAP[1][y][x]){
                        case P:
                            //プレイヤーの位置指定
                            m_Player.SetPos(
                                (x+0.5) * PANEL_LEN*2,
                                (y+0.5) * PANEL_LEN*2
                            );
                            break;
                        }
                    }
                }
                for(y = 0; y < MAP[0].length; y++){
                    for(x = 0; x < MAP[0][0].length; x++){
                        switch(MAP[0][y][x]){
                        case G:
                            //ゴールの位置指定
                            m_Goal.SetPos(
                                (x+0.5) * PANEL_LEN*2,
                                (y+0.5) * PANEL_LEN*2
                            );
                            break;
                        }
                    }
                }
            }

            //Text
            {
                m_Text.selectable = false;
                m_Text.autoSize = TextFieldAutoSize.LEFT;
                m_Text.defaultTextFormat = new TextFormat('Verdana', 60, 0xFFFF00, true);
                m_Text.text = '';
                m_Text.filters = [new GlowFilter(0xFF0000)];

                addChild(m_Text);
            }

            //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);
            }
//*/
        }

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

            //ブロック描画
            {
                ImageManager.DrawBlocks(MAP[0], m_BitmapData_Block_Main, 1,   true);
                ImageManager.DrawBlocks(MAP[1], m_BitmapData_Block_Near, 1,   true);
                ImageManager.DrawBlocks(MAP[2], m_BitmapData_Block_Far,  0.5, true);//false
            }
        }

        public function OnLoadEnd_Player(in_Graphic:DisplayObject):void{
            //プレイヤー
            {
                var mtx:Matrix = new Matrix(1,0,0,1, 0,0);

                for(var i:int = 0; i < Player.GRAPHIC_NUM; i++){
                    var bmd:BitmapData = m_Player.m_BitmapDataList[i];
                    //Clear
                    bmd.fillRect(bmd.rect, 0x00000000);
                    //Draw
                    mtx.tx = -i*24;
                    mtx.ty = -PANEL_LEN;
                    bmd.draw(in_Graphic, mtx);
                }
            }
        }

        //Update
        public function Update(e:Event=null):void{
            var DeltaTime:Number = 1.0 / stage.frameRate;

            //Player
            {
                m_Player.Update(DeltaTime);
            }

            //Goal
            {
                m_Goal.Update();
            }

            //Camera
            {
                Update_Camera();
            }
        }

        //Update : Camera
        public function Update_Camera():void{
            var CAMERA_W:int = stage.stageWidth;
            var CAMERA_H:int = stage.stageHeight;

            var PlayerX:int = m_Player.x;
            var PlayerY:int = m_Player.y;

            var CameraLX:int = PlayerX - CAMERA_W*0.5;
            var CameraUY:int = PlayerY - CAMERA_H*0.5;

            var RootX:int;
            {
                RootX = -CameraLX;
//                if(RootX < -PANEL_LEN * MAP[0][0].length + CAMERA_W){
//                    RootX = -PANEL_LEN * MAP[0][0].length + CAMERA_W;
//                }
//                if(RootX > 0){
//                    RootX = 0;
//                }
            }

            var RootY:int;
            {
                RootY = -CameraUY;
//                if(RootY < -PANEL_LEN * MAP[0].length + CAMERA_H){
//                    RootY = -PANEL_LEN * MAP[0].length + CAMERA_H;
//                }
//                if(RootY > 0){
//                    RootY = 0;
//                }
            }

//*
            //常に中心
            m_Layer_Root.x = RootX;
            m_Layer_Root.y = RootY;
/*/
            //補間
            var ratio:Number = 0.2;
            m_Layer_Root.x = Lerp(m_Layer_Root.x, RootX, ratio);
            m_Layer_Root.y = Lerp(m_Layer_Root.y, RootY, ratio);
//*/
            //地上時などにレイヤーのズレが気になるので補正
//            m_Layer_Root.x -= PANEL_LEN/2;
            m_Layer_Root.x -= 20;
//            m_Layer_Root.y -= 24;
            m_Layer_Root.y += 8;

            //多重レイヤー
/*
            m_Bitmap_Block_Near.x = m_Layer_Root.x;
            m_Bitmap_Block_Near.y = m_Layer_Root.y;
            m_Bitmap_Block_Far.x = -m_Layer_Root.x/2;
            m_Bitmap_Block_Far.y = -m_Layer_Root.y/2;
/*/
            //m_Bitmap_Block_Main.x = -m_Layer_Root.x/2;
            //m_Bitmap_Block_Main.y = -m_Layer_Root.y/2;
            m_Layer_Main.x = -m_Layer_Root.x/2;
            m_Layer_Main.y = -m_Layer_Root.y/2;
            m_Bitmap_Block_Far.x = -m_Layer_Root.x*3/4;
            m_Bitmap_Block_Far.y = -m_Layer_Root.y*3/4;
//*/
        }

        //Goal
        public function OnGoal():void{
            //Mode
            {
                m_Mode = MODE_GOAL;
            }

            //Text
            {
                //Text
                m_Text.text = 'Clear';

                //Centering
                m_Text.x = (stage.stageWidth - m_Text.width) / 2;
                m_Text.y = (stage.stageHeight - m_Text.height) / 2;
            }
        }

        //Game Over : Damage
        public function OnDead_Damage():void{
            //Mode
            {
                m_Mode = MODE_GAME_OVER;
            }

            //Text
            {
                //Text
                m_Text.text = 'Game Over';

                //Centering
                m_Text.x = (stage.stageWidth - m_Text.width) / 2;
                m_Text.y = (stage.stageHeight - m_Text.height) / 2;
            }
        }

        //Game Over : Fall
        public function OnDead_Fall():void{
            //Mode
            {
                m_Mode = MODE_GAME_OVER;
            }

            //Text
            {
                //Text
                m_Text.text = 'Game Over';

                //Centering
                m_Text.x = (stage.stageWidth - m_Text.width) / 2;
                m_Text.y = (stage.stageHeight - m_Text.height) / 2;
            }
        }

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

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


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


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

    //移動速度
    static public const VEL_X:Number = 200.0;

    //ジャンプ速度
    static public const JUMP_VEL:Number = 390.0;

    //重力
    static public const GRAVITY:Number = 500.0;

    //最高下降速度
    static public const FALL_VEL_MIN:Number = 1000.0;

    //アニメーション用パラメータ
    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 public const GRAPHIC_NUM:int = 3;


    //==Var==

    //移動まわりのパラメータ
    public var m_Pos:Point = new Point(0,0);
    public var m_Vel:Point = new Point(0,0);

    //入力
    public var m_InputL:Boolean = false;
    public var m_InputR:Boolean = false;
    public var m_InputU:Boolean = false;

    //表示画像
    public var m_Bitmap:Bitmap = new Bitmap();//これの中身を差し替えることでアニメーションさせる

    //アニメーション用タイマー
    public var m_AnimTimer:Number = 0.0;

    //アニメーション用画像リスト
    public var m_BitmapDataList:Array = new Array(GRAPHIC_NUM);

    //接地フラグ
    public var m_GroundFlag:Boolean = false;

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


    //==Function==

    //Init
    public function Player(){
        //Input
        {
            addEventListener(
                Event.ADDED_TO_STAGE,//ステージに追加されたら
                function(e:Event):void{
                    //キー入力を見る
                    stage.addEventListener(KeyboardEvent.KEY_DOWN, OnKeyDown);
                    stage.addEventListener(KeyboardEvent.KEY_UP, OnKeyUp);
                }
            );
        }

        //プレイヤーグラフィックの仮画像
        {
            var shape:Shape = new Shape();
            var g:Graphics = shape.graphics;
            g.lineStyle(0,0,0);
            g.beginFill(0xFFFFFF, 1.0);
            g.drawCircle(24/2, GameMain.PANEL_LEN-24/2, 24/2);
            g.endFill();


            for(var i:int = 0; i < GRAPHIC_NUM; i++){
                m_BitmapDataList[i] = new BitmapData(24, GameMain.PANEL_LEN, true, 0x00000000);
                m_BitmapDataList[i].draw(shape);
            }
        }

        //表示画像の登録
        {
            m_Bitmap.x = -24/2;
            m_Bitmap.y = -GameMain.PANEL_LEN/2;
            addChild(m_Bitmap);
        }
    }

    //Init : Pos
    public function SetPos(in_X:int, in_Y:int):void{
        this.x = m_Pos.x = in_X;
        this.y = m_Pos.y = in_Y;
    }

    //Update : Input
    private function OnKeyDown(event:KeyboardEvent):void{
        if(event.keyCode == Keyboard.LEFT){    m_InputL = true;}
        if(event.keyCode == Keyboard.RIGHT){m_InputR = true;}
        if(event.keyCode == Keyboard.UP){    m_InputU = true;}
    }
    private function OnKeyUp(event:KeyboardEvent):void{
        if(event.keyCode == Keyboard.LEFT){    m_InputL = false;}
        if(event.keyCode == Keyboard.RIGHT){m_InputR = false;}
        if(event.keyCode == Keyboard.UP){    m_InputU = false;}
    }

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

        //移動
        Update_Move(in_DeltaTime);

        //アニメーション
        Update_Anim(in_DeltaTime);

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

    //Update : Anim
    public function Update_Anim(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[iter];
    }

    //Check : Dead
    public function Check_Dead():void{
        //Check
        {
            if(m_IsDead){
                return;
            }
        }
/*
        //マップより下に行っていたら落下死する
        if(this.y > GameMain.PANEL_LEN*GameMain.MAP[0].length+GameMain.PANEL_LEN){
            //ゲームオーバー処理
            {
                GameMain.Instance.OnDead_Fall();
            }

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

    //Update : Move
    public function Update_Move(in_DeltaTime:Number):void{
        //入力
        {
            //X
            {
                var TrgVX:Number = 0.0;
                if(m_InputR){TrgVX =  VEL_X; this.scaleX =  1;}
                if(m_InputL){TrgVX = -VEL_X; this.scaleX = -1;}

                var ratio:Number = 0.5;
                m_Vel.x = Lerp(m_Vel.x, TrgVX, ratio);
            }

            //Jump
            {
                if(m_InputU && m_GroundFlag){
                    m_Vel.y = -JUMP_VEL;
                }
            }
        }

        //重力
        {
            m_Vel.y += GRAVITY * in_DeltaTime;

            //速度制限
            if(m_Vel.y > FALL_VEL_MIN){
                m_Vel.y = FALL_VEL_MIN;
            }
        }

        //目標位置
        var DstX:Number;
        var DstY:Number;
        {
            DstX = (m_Pos.x) + (m_Vel.x * in_DeltaTime);
            DstY = (m_Pos.y) + (m_Vel.y * in_DeltaTime);
        }

        //移動を試みる
        //・端数制御のためにちょっと特殊なことをしているが、基本的にはただ単にX移動→Y移動してるだけ
        //・壁判定まわりはかなりムダが多い(高速化の余地が多い)が、ひとまずこれで

        //X移動
        {
            var TryX:int = m_Pos.x;
            if(TryX != int(DstX)){
                for(;;){
                    //++
                    if(TryX < DstX){
                        TryX++;
                    }else{
                        TryX--;
                    }

                    //壁があるならその手前で中断
                    if(IsWall(TryX, m_Pos.y)){
                        DstX = m_Pos.x;//壁の手前になるように位置補正(=端数切捨て)
                        m_Vel.x = 0;
                        break;
                    }

                    //移動できたようなので更新(主に上の位置補正のための記憶用)
                    m_Pos.x = TryX;

                    //Dstまで辿りついたら終了
                    if(TryX == int(DstX)){
                        break;
                    }
                }
            }
            m_Pos.x = DstX;
        }

        //Y移動
        {
            m_GroundFlag = false;//更新のためリセット

            var TryY:int = m_Pos.y;
            if(TryY != int(DstY)){
                for(;;){
                    //++
                    if(TryY < DstY){
                        TryY++;
                    }else{
                        TryY--;
                    }

                    //壁があるならその手前で中断
                    if(IsWall(m_Pos.x, TryY)){
                        if(DstY > m_Pos.y){m_GroundFlag = true;}
                        DstY = m_Pos.y;//壁の手前になるように位置補正(=端数切捨て)
                        m_Vel.y = 0;
                        break;
                    }

                    //移動できたようなので更新(主に上の位置補正のための記憶用)
                    m_Pos.y = TryY;

                    //Dstまで辿りついたら終了
                    if(TryY == int(DstY)){
                        break;
                    }
                }
            }
            m_Pos.y = DstY;
        }

        //反映
        {
            this.x = m_Pos.x;
            this.y = m_Pos.y;
        }
    }

    //壁があるかどうか
    public function IsWall(in_X:int, in_Y:int):Boolean{
        //プレイヤーを中心とする四角形の四隅が壁にめり込まないようにする
        //・移動方向によって判定を省略して高速化できるはずだが、対応は保留
        //・同じく、Indexが変わらなければ判定をスキップできるはずだが、こちらも保留
        var i:int;
        var PosX:int;
        var PosY:int;
        var IndexX:int;
        var IndexY:int;

        //四角形用のオフセット
        const OffsetX:int = 24/2;
        const OffsetY:int = (GameMain.PANEL_LEN-2)/2;

        //Main
        var BaseX_Main:int = in_X - GameMain.Instance.m_Layer_Main.x;
        var BaseY_Main:int = in_Y - GameMain.Instance.m_Layer_Main.y;
        for(i = 0; i < 4; i++){
            PosX = BaseX_Main + (((i&1)==0)? OffsetX: -OffsetX);
            PosY = BaseY_Main + (((i&2)==0)? OffsetY: -OffsetY);

            IndexX = PosX / GameMain.PANEL_LEN;
            IndexY = PosY / GameMain.PANEL_LEN;

            //範囲チェック
            {
                //画面外は空白とみなす
                if(IndexX < 0){continue;}
                if(IndexX >= GameMain.MAP[0][0].length){continue;}
                if(IndexY < 0){continue;}
                if(IndexY >= GameMain.MAP[0].length){continue;}
            }

            //該当箇所が壁ならtrueを返して終了
            switch(GameMain.MAP[0][IndexY][IndexX]){
            case GameMain.W:
                return true;
            }
        }

        //Near
        var BaseX_Near:int = in_X - GameMain.Instance.m_Bitmap_Block_Near.x;
        var BaseY_Near:int = in_Y - GameMain.Instance.m_Bitmap_Block_Near.y;
        for(i = 0; i < 4; i++){
            PosX = BaseX_Near + (((i&1)==0)? OffsetX: -OffsetX);
            PosY = BaseY_Near + (((i&2)==0)? OffsetY: -OffsetY);

            IndexX = PosX / GameMain.PANEL_LEN / 2;
            IndexY = PosY / GameMain.PANEL_LEN / 2;

            //範囲チェック
            {
                //画面外は空白とみなす
                if(IndexX < 0){continue;}
                if(IndexX >= GameMain.MAP[1][0].length){continue;}
                if(IndexY < 0){continue;}
                if(IndexY >= GameMain.MAP[1].length){continue;}
            }

            //該当箇所が壁ならtrueを返して終了
            switch(GameMain.MAP[1][IndexY][IndexX]){
            case GameMain.W:
                return true;
            }
        }

        //Far
        var BaseX_Far:int = in_X - GameMain.Instance.m_Bitmap_Block_Far.x;
        var BaseY_Far:int = in_Y - GameMain.Instance.m_Bitmap_Block_Far.y;
        for(i = 0; i < 9; i++){
            PosX = BaseX_Far + (((i%3)==0)? OffsetX: ((i%3)==1)? 0: -OffsetX);
            PosY = BaseY_Far + ((int(i/3)==0)? OffsetY: (int(i/3)==1)? 0: -OffsetY);

            IndexX = 2 * PosX / GameMain.PANEL_LEN;
            IndexY = 2 * PosY / GameMain.PANEL_LEN;

            //範囲チェック
            {
                //画面外は空白とみなす
                if(IndexX < 0){continue;}
                if(IndexX >= GameMain.MAP[2][0].length){continue;}
                if(IndexY < 0){continue;}
                if(IndexY >= GameMain.MAP[2].length){continue;}
            }

            //該当箇所が壁ならtrueを返して終了
            switch(GameMain.MAP[2][IndexY][IndexX]){
            case GameMain.W:
                return true;
            }
        }

        //四隅に壁が見つからなかったら壁はないと判断
        return false;
    }

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


//#Goal
class Goal extends Sprite
{
    //==Constt==

    static public const GOAL_RANGE:int = 8;


    //==Function==

    //Init
    public function Goal():void{
        //Graphic
        {
            addChild(ImageManager.CreateGoalGraphic());
        }
    }

    //SetPos
    public function SetPos(in_X:int, in_Y:int):void{
        this.x = in_X;
        this.y = in_Y;
    }

    //Update
    public function Update():void{
        //プレイヤーが一定範囲に来たらゴールとする

        //そもそもすでにゴールしてたら何も処理しない
        {
            if(GameMain.Instance.IsEnd()){
                return;
            }
        }

        //プレイヤーとの距離が一定以上離れていたら何も処理しない
        {
            var p:DisplayObjectContainer;

            var AbsX:Number = this.x;
            var AbsY:Number = this.y;
            for(p = this.parent; p != null; p = p.parent){
                AbsX += p.x;
                AbsY += p.y;
            }

            var AbsPlayerX:Number = GameMain.Instance.m_Player.x;
            var AbsPlayerY:Number = GameMain.Instance.m_Player.y;
            for(p = GameMain.Instance.m_Player.parent; p != null; p = p.parent){
                AbsPlayerX += p.x;
                AbsPlayerY += p.y;
            }

            var GapX:Number = AbsPlayerX - AbsX;
            var GapY:Number = AbsPlayerY - AbsY;

            var Distance:Number = Math.sqrt(GapX*GapX + GapY*GapY);

            if(Distance > GOAL_RANGE){
                return;
            }
        }

        //上のチェックに全てクリアしたらゴールしたものとして処理する
        {
            GameMain.Instance.OnGoal();
        }
    }
}


//#ImageManager
class ImageManager
{
    //==Const==

    //#Graphic
    static public var m_GraphicIndexIter:int = 0;

    static public const GRAPHIC_INDEX_BG:int            = m_GraphicIndexIter++;

    static public const GRAPHIC_INDEX_WALL:int            = m_GraphicIndexIter++;
    static public const GRAPHIC_INDEX_WALL_X:int        = m_GraphicIndexIter++;
    static public const GRAPHIC_INDEX_WALL_Y:int        = m_GraphicIndexIter++;
    static public const GRAPHIC_INDEX_WALL_XorY:int        = m_GraphicIndexIter++;
    static public const GRAPHIC_INDEX_WALL_XandY:int    = m_GraphicIndexIter++;

    static public const GRAPHIC_INDEX_NEEDLE:int        = m_GraphicIndexIter++;
    static public const GRAPHIC_INDEX_NEEDLE_X:int        = m_GraphicIndexIter++;
    static public const GRAPHIC_INDEX_NEEDLE_Y:int        = m_GraphicIndexIter++;
    static public const GRAPHIC_INDEX_NEEDLE_XY:int        = m_GraphicIndexIter++;

    static public const GRAPHIC_INDEX_NUM:int            = m_GraphicIndexIter;


    //#enum:Quater
    static public const LU:int = 0;
    static public const RU:int = 1;
    static public const LD:int = 2;
    static public const RD:int = 3;

    //#enum:Pos
    static public const POS_X:int = 0;
    static public const POS_Y:int = 1;


    //#Graphic
    static public var m_BitmapData_View:BitmapData;

    //#Mapping
    static public var GRAPHIC_INDEX_TO_POS:Array;


    //#Palette
    static public var m_Palette_ForView:Array;


    //#Utility
    static public const POS_ZERO:Point = new Point(0,0);


    //==Function==

    //#Init
    static public function Init(in_Graphic:DisplayObject):void{
        var x:int, y:int, i:int;

        //m_BitmapData_View
        {
            m_BitmapData_View = new BitmapData(256, 256, true, 0x00000000);
            m_BitmapData_View.draw(in_Graphic);
        }

        //GRAPHIC_INDEX_TO_POS
        {//GRAPHIC_INDEX_~から画像の位置へのマッピング(さらにどの隅での処理かも含む)(そして左から何マス目、上から何マス目、という指定)
            GRAPHIC_INDEX_TO_POS = new Array(GRAPHIC_INDEX_NUM);

            //[LU][RU][LD][RD]

            GRAPHIC_INDEX_TO_POS[GRAPHIC_INDEX_BG]            = [[3,2], [3,2], [3,2], [3,2]];

            GRAPHIC_INDEX_TO_POS[GRAPHIC_INDEX_WALL]        = [[1,1], [1,1], [1,1], [1,1]];
            GRAPHIC_INDEX_TO_POS[GRAPHIC_INDEX_WALL_X]        = [[0,1], [2,1], [0,1], [2,1]];
            GRAPHIC_INDEX_TO_POS[GRAPHIC_INDEX_WALL_Y]        = [[1,0], [1,0], [1,2], [1,2]];
            GRAPHIC_INDEX_TO_POS[GRAPHIC_INDEX_WALL_XorY]    = [[0,0], [2,0], [0,2], [2,2]];
            GRAPHIC_INDEX_TO_POS[GRAPHIC_INDEX_WALL_XandY]    = [[3,0], [4,0], [3,1], [4,1]];

            GRAPHIC_INDEX_TO_POS[GRAPHIC_INDEX_NEEDLE]        = [[3,3], [4,3], [3,4], [4,4]];
            GRAPHIC_INDEX_TO_POS[GRAPHIC_INDEX_NEEDLE_X]    = [[0,4], [2,4], [0,4], [2,4]];
            GRAPHIC_INDEX_TO_POS[GRAPHIC_INDEX_NEEDLE_Y]    = [[1,3], [1,3], [1,5], [1,5]];
            GRAPHIC_INDEX_TO_POS[GRAPHIC_INDEX_NEEDLE_XY]    = [[0,3], [2,3], [0,5], [2,5]];
        }

        //m_Palette_ForView
        {
            m_Palette_ForView = new Array(256);

            var index_graphic:int = GRAPHIC_INDEX_BG;
            for(i = 0; i < 256; i++){
                //区切りごとにindexを変更。次の区切りまではその値をセット
                switch(i){
                case 0:
                case 6:
                case 18:
                case 24:
                    index_graphic = GRAPHIC_INDEX_BG; break;
                case 3:
                case 21:
                    index_graphic = GRAPHIC_INDEX_NEEDLE_Y; break;
                case 9:
                case 15:
                    index_graphic = GRAPHIC_INDEX_NEEDLE_X; break;
                case 12:
                    index_graphic = GRAPHIC_INDEX_NEEDLE_XY; break;
                case 27:
                    index_graphic = GRAPHIC_INDEX_NEEDLE; break;
                case 54:
                case 63:
                    index_graphic = GRAPHIC_INDEX_WALL_XorY; break;
                case 60:
                case 69:
                    index_graphic = GRAPHIC_INDEX_WALL_X; break;
                case 72:
                    index_graphic = GRAPHIC_INDEX_WALL_Y; break;
                case 78:
                    index_graphic = GRAPHIC_INDEX_WALL_XandY; break;
                case 80:
                    index_graphic = GRAPHIC_INDEX_WALL; break;
                }

                m_Palette_ForView[i] = index_graphic;
            }
        }
    }

    //#Draw : BG
    static public function DrawBG(in_NumX:int, in_NumY:int, out_BitmapData_View:BitmapData):void
    {
        var x:int, y:int, i:int;
        var mtx:Matrix = new Matrix();
        var rect:Rectangle = new Rectangle(0,0, 16,16);
        var NumX:int = in_NumX;
        var NumY:int = in_NumY;

        for(y = 0; y < NumY; y++){
            for(x = 0; x < NumX; x++){
                for(i = 0; i < 4; i++){
                    rect.x = x * 32 + 16 * ((i&1)>>0);
                    rect.y = y * 32 + 16 * ((i&2)>>1);

                    var index:int = GRAPHIC_INDEX_BG;

                    //#view
                    mtx.tx = rect.x - 16 * GRAPHIC_INDEX_TO_POS[index][i][POS_X];
                    mtx.ty = rect.y - 16 * GRAPHIC_INDEX_TO_POS[index][i][POS_Y];
                    out_BitmapData_View.draw(m_BitmapData_View, mtx, null, null, rect);
                }
            }
        }
    }

    //#Draw : Blocks
    static public function DrawBlocks(in_Map:Array, out_BitmapData_View:BitmapData, in_Scl:Number, in_IsBackTransparent:Boolean):void
    {
        var x:int, y:int, i:int;
        var mtx:Matrix = new Matrix();
        mtx.scale(in_Scl, in_Scl);

        var NumX:int = in_Map[0].length;
        var NumY:int = in_Map.length;

        //Map => Bitmap_Base
        //Mapの要素を元に、「0:空白」「1:トゲ」「2:壁」というBitmapを生成
        var BitmapData_Base:BitmapData;
        {
            BitmapData_Base = new BitmapData(NumX, NumY, false, 0x000000);
            for(y = 0; y < NumY; y++){
                for(x = 0; x < NumX; x++){
                    var index:int = 0;//default(O, P, G)
                    {
                        switch(in_Map[y][x]){
                        case GameMain.W:
                            index = 2;
                            break;
                        case GameMain.X:
                            index = 1;
                            break;
                        }
                    }

                    BitmapData_Base.setPixel(x, y, index);
                }
            }
        }

        //Bitmap_Base => Bitmap_LU,Bitmap_RU,Bitmap_LD,Bitmap_RD
        //Bitmap_Baseを元に、四隅の隣接状況をそれぞれ求める(Uniqueな値になるようにする)
        var BitmapData_Quater:Array = new Array(4);
        {
            //Create Filter
            const filter:Array = [
                new ConvolutionFilter(3,3,
                    [//LU
                        1,  3,  0,
                        9, 27,  0,
                        0,  0,  0,
                    ]
                ),
                new ConvolutionFilter(3,3,
                    [//RU
                        0,  3,  1,
                        0, 27,  9,
                        0,  0,  0,
                    ]
                ),
                new ConvolutionFilter(3,3,
                    [//LD
                        0,  0,  0,
                        9, 27,  0,
                        1,  3,  0,
                    ]
                ),
                new ConvolutionFilter(3,3,
                    [//RD
                        0,  0,  0,
                        0, 27,  9,
                        0,  3,  1,
                    ]
                ),
            ];

            for(i = 0; i < 4; i++){
                //Init
                BitmapData_Quater[i] = new BitmapData(NumX, NumY, false, 0x000000);

                //Apply Filter
                BitmapData_Quater[i].applyFilter(BitmapData_Base, BitmapData_Base.rect, POS_ZERO, filter[i]);
            }
        }

        //Bitmap_LU,Bitmap_RU,Bitmap_LD,Bitmap_RD => ForView
        //Uniqueな値から、対応するIndexへと変換する
        var BitmapData_ForView:Array = new Array(4);
        {
            for(i = 0; i < 4; i++){
                //Init
                BitmapData_ForView[i] = new BitmapData(NumX, NumY, false, 0x000000);

                //Apply Palette
                BitmapData_ForView[i].paletteMap(BitmapData_Quater[i], BitmapData_Quater[i].rect, POS_ZERO, null, null, m_Palette_ForView);
            }
        }


        //Draw
        //上で求めたIndexに基づき描画
        {
            var rect:Rectangle = new Rectangle(0,0, 16*in_Scl,16*in_Scl);

            for(y = 0; y < NumY; y++){
                for(x = 0; x < NumX; x++){
                    for(i = 0; i < 4; i++){
                        rect.x = x * 32 + 16 * ((i&1)>>0);
                        rect.y = y * 32 + 16 * ((i&2)>>1);
                        rect.x *= in_Scl;
                        rect.y *= in_Scl;

                        index = BitmapData_ForView[i].getPixel(x, y);

                        if(in_IsBackTransparent && index == GRAPHIC_INDEX_BG){
                            continue;
                        }

                        //#view
                        mtx.tx = rect.x - 16 * GRAPHIC_INDEX_TO_POS[index][i][POS_X] * in_Scl;
                        mtx.ty = rect.y - 16 * GRAPHIC_INDEX_TO_POS[index][i][POS_Y] * in_Scl;
                        out_BitmapData_View.draw(m_BitmapData_View, mtx, null, null, rect);
                    }
                }
            }
        }
    }

    //Image : Goal
    static public function CreateGoalGraphic():Sprite{
        //
        const W:int = 48;
        const H:int = 64;
        const BLUR_VAL:int = 20;

        //
        var result:Sprite = new Sprite();

        //基本画像
        var bmd:BitmapData = new BitmapData(W, H, true, 0x00000000);
        var bmp:Bitmap = new Bitmap(bmd);
        {
            //白い楕円の上半分を描画
            const RAD_W:int = 12;//W/2-BLUR_VAL;
            const RAD_H:int = 32;//H-BLUR_VAL;

            var shape:Shape = new Shape();
            var g:Graphics = shape.graphics;
            g.lineStyle(0, 0x000000, 0.0);
            g.beginFill(0xFFFFFF, 1.0);
            g.drawEllipse(W/2-RAD_W, H-RAD_H, RAD_W*2, RAD_H*2);
            g.endFill();

//            shape.filters = [new GlowFilter(0xFFFFFF,1.0, 2*BLUR_VAL,2*BLUR_VAL)];
//            shape.filters = [new GlowFilter(0xFFFFFF,1.0, 1,2*BLUR_VAL,255), new GlowFilter(0xFFFFFF,1.0, 2*BLUR_VAL,1,255)];

            bmd.draw(shape);

            shape.filters = [new BlurFilter(BLUR_VAL, BLUR_VAL)];
            bmd.draw(shape);
            bmd.draw(shape);

            result.addChild(bmp);
        }

        //発光っぽくする
        {
            //フィルターを追加
//            bmp.filters = [new GlowFilter(0xFFFFFF, 1.0, 2*BLUR_VAL,2*BLUR_VAL)];

            //フィルターで下に広がるのを防止するためのマスク
            var msk:Bitmap = new Bitmap(new BitmapData(W, H, false, 0xFFFFFF));
            result.mask = msk;
            result.addChild(msk);

            //加算化
            bmp.blendMode = BlendMode.ADD;
        }

        //位置調整
        {
            result.x = -W/2;
            result.y = -H+16;
        }

        return result;
    }
}