Beautifl - Flash Gallery

Thumbnail : forked from: Wonderfl Tower Defense
forked from: Wonderfl Tower Defense
beginners_high 2010-09-07 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

//forked from o8que's Wonderfl Tower Defense
//初ワンダフルで大好きなタワーディフェンスゲーム!をフォーク
//フォーク元とだいぶ内容が違ってきたので、o8que氏の説明書きを変更させてもらいました(2010.10.6)

/* ------------------------------------------------------
 * The Gate TD
 *  ~forked from o8que's [Wonderfl Tower Defense] ~
 * ------------------------------------------------------
 * [タワーの特徴]
 * Gun     : 安価で地対空両用。レベル5で最大級の射程。
 * Gatling : 連射が速く地対空両用。安定したダメージ源になる。
 * Cannon  : 範囲攻撃で高威力。空中に攻撃できない。
 * Venom   : 対地。毒の威力は移動速度に比例。毒状態の敵が死ぬと周囲に感染。
 * Voltex  : 射程内全体へスロウ効果。地対空両用で威力も高めだが高価。
 * AntiFly : 高威力の対空専用。現行は貫通弾。<修正予定>
 * Base    : 土台。タワーを置けない土地にはまず土台を。設置後は売却不能。
 * 
 * [敵の特徴]
 * << Feeble >>
 * Normal  : 特にこれといった特徴はない。
 * Swarm   : 体力はかなり低いザコだが、大量に出現する。
 * Fast    : 移動が速い。油断すると一気に攻め込まれるぞ。
 * Flying  : 飛行型。地形を無視するのでタワー配置に注意。
 * << Tough >>
 * Immune  : ノロマだが体力が高い。スロウと毒を無効化。
 * Zombie  : 常に傷を再生しながら侵攻してくる。火力で対抗せよ。
 * Fupa    : 破壊すると羽化して飛行タイプに変化。
 * Detour  : 飛行型。左右に迂回するので侵攻経路がやっかい。
 * << Scary >>
 * Shell   : 通称3段ロケット。体力が減ると脱皮し、毒やスロウを破棄する。
 * Split   : 破壊すると移動の速いザコ4体に分裂する。
 * Fade    : 透明化してタワーの攻撃から逃れる。透明中も範囲攻撃は当たる。
 * Decoyer : 飛行型。オトリ弾を発射し、攻撃を拡散させてくるぞ。
 * << Insane >>
 * Fury    : 砲撃や毒でダメージを受けるたびに加速。最大速度はヤバイ。
 * Wall    : 体力が特大。毒とスロウ無効、わずかに再生能力もある。
 * Ghost   : 透明化する飛行型。移動は遅めだが危険な敵。 
 * Random  : (未作成)
 * 
 *            
 * [スキル](予定)
 * 敵メイキングが落ち着いたら着手。
 * 時間でチャージされ発動可能になるスキルを12種から3つまで装備。
 * チャージをオフにするとほかのスキル回復が早まる。
 * 
 * [ゲート](予定)
 * スキルの仕組みの目処が立ったら着手。ずいぶん先になりそう。
 * ゲートに接触した敵は能力がUP、獲得できる得点とお金もUP。
 * 
 * ------------------------------------------------------
 * [HotKey]
 * 1-7   : select a tower to place
 * 7     : select a base to build
 * 0,ESC : cancel a selection
 * U     : upgrade the selected tower
 * S     : sell the selected tower
 * M     : show menu window
 * N     : send the next wave
 * ------------------------------------------------------
 * [今後の予定]
 * ・アップグレードタイム(1~2秒)の導入
 * ・スキル能力の準備と実装(勉強するがすごく大変そう)
 * ・ゲートシステムの準備と実装(たぶん簡単)
 * ・そのうちステージセレクトで5ステージつくりたい(勉強する)
 * ・最後にゴールを自分で配置する仕組み
 * ・バランス調整
 *
 *
 *
 *
 */

/* ---------------------------------------------------------------------------------------------------------
 * Main
 * ---------------------------------------------------------------------------------------------------------
 */
package {
    import com.bit101.components.PushButton;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.ui.Keyboard;
    import flash.utils.Dictionary;
    
    public class Main extends Sprite {
        // 各状態を表す定数
        public static const STATE_READY:int = 0;
        public static const STATE_PLAYING:int = 1;
        public static const STATE_MENU:int = 2;
        public static const STATE_GAMEOVER:int = 3;
        
        private var _states:Vector.<IState>;    // 状態のコレクション
        private var _currentState:IState;        // 現在の状態の参照
        private var _previousState:IState;        // 一つ前の状態の参照
        
        private var _world:World;                // フィールド・タワー・敵等を表示する画面
        private var _frontend:Frontend;            // ステータス・メニュー等を表示するウインドウ
        private var _waveManager:WaveManager;    // Waveを管理・表示するウインドウ
        private var _nextWaveButtonHandler:Function;
        
        public function get world():World { return _world; }
        public function get waveManager():WaveManager { return _waveManager; }
        
        public function Main() {
            graphics.beginFill(0x000000);
            graphics.drawRect(0, 0, 465, 465);
            graphics.endFill();
            
            // 外部アセットを読み込んだ後に初期化を開始する
            var imagePaths:Dictionary = ImageFactory.getExternalImagePaths();
            var imageHolder:Dictionary = ImageFactory.load();
            var preloader:Preloader = new Preloader(this, imagePaths, imageHolder);
            preloader.addEventListener(Event.COMPLETE, initialize);
        }
        
        // 全体の初期化
        private function initialize(e:Event):void {
            e.target.removeEventListener(Event.COMPLETE, initialize);
            HotKey.setStage(this.stage);
            EnemyType.initialize();
            BornAbility.initialize();
            AccelerateAbility.initialize();
            
            // 各状態の初期化
            _states = new Vector.<IState>();
            _states[Main.STATE_READY] = new ReadyState(this);
            _states[Main.STATE_PLAYING] = new PlayingState(this);
            _states[Main.STATE_MENU] = new MenuState(this);
            _states[Main.STATE_GAMEOVER] = new GameoverState(this);
            
            // 画面の初期化
            addChild(_world = new World( -9, 12));
            addChild(_frontend = new Frontend(0, 0));
            _frontend.addChild(_waveManager = new WaveManager(0, 415, _world));
            
            // 各ボタンの初期化と、対応するホットキーを設定する
            var window:Sprite = _frontend.addChild(ImageFactory.createWindow(365, 415, 100, 50)) as Sprite;
            var menuButton:PushButton = new PushButton(window, 5, 4, "Menu (M)", onClickMenuButton);
            var nextWaveButton:PushButton = new PushButton(window, 5, 26, "Next Wave (N)", onClickNextWaveButton);
            menuButton.width = nextWaveButton.width = 90;
            
            HotKey.bind(Keyboard.M, onClickMenuButton);
            HotKey.bind(Keyboard.N, onClickNextWaveButton);
            
            // 初期状態の設定
            _currentState = _states[Main.STATE_GAMEOVER];
            _currentState.enter();
            
            addEventListener(Event.ENTER_FRAME, mainLoop);
        }
        private function onClickMenuButton(e:MouseEvent = null):void { changeState(Main.STATE_MENU); }
        private function onClickNextWaveButton(e:MouseEvent = null):void { _nextWaveButtonHandler(); }
        private function mainLoop(e:Event):void { _currentState.update(); }
        
        // NextWaveボタンを押した時の処理を設定する
        public function setNextWaveButtonHandler(handler:Function = null):void {
            _nextWaveButtonHandler = (handler != null) ? handler : doNothing;
        }
        private function doNothing():void { }
        
        // ゲームの状態を変更する
        public function changeState(stateType:int):void {
            _previousState = _currentState;
            
            _currentState.exit();
            _currentState = _states[stateType];
            _currentState.enter();
        }
        
        // ゲームの状態を一つ前の状態に戻す
        public function revertToPreviousState():void {
            _currentState.exit();
            _currentState = _previousState;
            _currentState.enter();
        }
    }
}
/* ----------------------------------------------------------------------------------------------------------------------
 * IState
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    //public 
    interface IState {
        function enter():void;
        function update():void;
        function exit():void;
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * GameoverState
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import com.bit101.components.PushButton;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import net.wonderfl.score.basic.BasicScoreForm;
    import net.wonderfl.score.basic.BasicScoreRecordViewer;
    
    //public 
    class GameoverState implements IState {
        private var _main:Main;
        private var _gameoverScreen:Sprite;
        private var _instructionWindow:Sprite;
        private var _isBeginning:Boolean;
        
        private var _scoreForm:BasicScoreForm;
        private var _ranking:BasicScoreRecordViewer;
        
        public function GameoverState(main:Main) {
            _main = main;
            _gameoverScreen = createGameoverScreen();
            _instructionWindow = createInstructionWindow();
            _isBeginning = true;
        }
        
        private function createGameoverScreen():Sprite {
            var screen:Sprite = new Sprite();
            screen.graphics.beginFill(0x000000, 0.5);
            screen.graphics.drawRect(0, 0, 465, 465);
            screen.graphics.endFill();
            new PushButton(screen, 182, 182, "Start Game", onClickStartButton);
            return screen;
        }
        private function onClickStartButton(e:MouseEvent):void { _main.changeState(Main.STATE_READY); }
        
        private function createInstructionWindow():Sprite {
            var container:Sprite = new Sprite();
            
            var window1:Sprite = container.addChild(ImageFactory.createWindow(180, 60, 190, 70)) as Sprite;
            window1.addChild(ImageFactory.createInstructionText(5, 7, 190, 24, "Select a tower to build\nby clicking right button.", 12));
            window1.addChild(ImageFactory.createInstructionText(5, 39, 190, 24, "設置したいタワーを、\n右のボタンから選択できます。", 12));
            
            var window2:Sprite = container.addChild(ImageFactory.createWindow(30, 220, 190, 70)) as Sprite;
            window2.addChild(ImageFactory.createInstructionText(5, 7, 190, 24, "Click on the map\nto build the selected tower.", 12));
            window2.addChild(ImageFactory.createInstructionText(5, 39, 190, 24, "マップをクリックすると、\n選択したタワーを設置できます。", 12));
            
            var window3:Sprite = container.addChild(ImageFactory.createWindow(240, 270, 190, 70)) as Sprite;
            window3.addChild(ImageFactory.createInstructionText(5, 7, 190, 24, "Click on a tower on the map\nto upgrade or sell it.", 12));
            window3.addChild(ImageFactory.createInstructionText(5, 39, 190, 24, "マップ上のタワーをクリックすると、\nレベルアップや売却を行えます。", 12));
            
            var window4:Sprite = container.addChild(ImageFactory.createWindow(170, 380, 190, 70)) as Sprite;
            window4.addChild(ImageFactory.createInstructionText(5, 7, 190, 24, "Press \"Next Wave\" button\nto send the next wave.", 12));
            window4.addChild(ImageFactory.createInstructionText(5, 39, 190, 24, "「Next Wave」ボタンを押すと、\nゲームを進めることができます。", 12));
            
            return container;
        }
        
        
        public function enter():void {
            _main.addChild(_gameoverScreen);
            
            if (_isBeginning) {
                _main.addChild(_instructionWindow);
            }else {
                if (_scoreForm != null) { _gameoverScreen.removeChild(_scoreForm); }
                _scoreForm = new BasicScoreForm(_gameoverScreen, 92, 10, GameData.instance.score, "Score", showRanking);
                showRanking(false);
            }
        }
        private function showRanking(b:Boolean):void {
            if (_ranking != null) { _gameoverScreen.removeChild(_ranking); }
            _ranking = new BasicScoreRecordViewer(_gameoverScreen, 122, 215, "Ranking", 99, true, null);
        }
        
        public function update():void { }
        
        public function exit():void {
            if (_isBeginning) {
                _main.removeChild(_instructionWindow);
                _instructionWindow = null;
            }
            _isBeginning = false;
            _main.removeChild(_gameoverScreen);
            
            _main.world.clear();
            _main.waveManager.initialize();
            GameData.instance.initialize();
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * ReadyState
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    //public 
    class ReadyState implements IState {
        private var _main:Main;
        
        public function ReadyState(main:Main) {
            _main = main;
        }
        
        public function enter():void {
            _main.setNextWaveButtonHandler(startPlaying);
            HotKey.enable();
        }
        private function startPlaying():void { _main.changeState(Main.STATE_PLAYING); }
        
        public function update():void {
            _main.world.update();
        }
        
        public function exit():void {
            HotKey.disable();
            _main.setNextWaveButtonHandler(_main.waveManager.sendNextWave);
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * PlayingState
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    //public 
    class PlayingState implements IState {
        private var _main:Main;
        
        public function PlayingState(main:Main) {
            _main = main;
        }
        
        public function enter():void {
            GameData.instance.sellingRatio = 0.8;
            HotKey.enable();
        }
        
        public function update():void {
            _main.world.update();
            _main.waveManager.update();
            
            // ライフが0になるか、全ての敵を倒したら、ゲームオーバー
            if ((GameData.instance.lives <= 0) || (_main.world.numEnemies() == 0 && _main.waveManager.finished())) {
                _main.changeState(Main.STATE_GAMEOVER);
            }
        }
        
        public function exit():void {
            HotKey.disable();
            GameData.instance.sellingRatio = 1;
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * MenuState
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import com.bit101.components.PushButton;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    
    //public 
    class MenuState implements IState {
        private var _main:Main;
        private var _menuScreen:Sprite;
        
        public function MenuState(main:Main) {
            _main = main;
            _menuScreen = createMenuScreen();
        }
        
        private function createMenuScreen():Sprite {
            var screen:Sprite = new Sprite();
            screen.graphics.beginFill(0x000000, 0.5);
            screen.graphics.drawRect(0, 0, 465, 465);
            screen.graphics.endFill();
            
            var window:Sprite = screen.addChild(ImageFactory.createWindow(122, 172, 120, 95)) as Sprite;
            window.addChild(ImageFactory.createWindow(0, 0, 120, 25));
            window.addChild(ImageFactory.createSimpleText(0, 0, 120, 25, "Menu", 12, 0xffffff));
            new PushButton(window, 10, 35, "Resume", onClickResumeButton);
            new PushButton(window, 10, 65, "Give up", onClickGiveUpButton);
            return screen;
        }
        private function onClickResumeButton(e:MouseEvent):void { _main.revertToPreviousState(); }
        private function onClickGiveUpButton(e:MouseEvent):void { _main.changeState(Main.STATE_GAMEOVER); }
        
        public function enter():void { _main.addChild(_menuScreen); }
        
        public function update():void { }
        
        public function exit():void { _main.removeChild(_menuScreen); }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * World
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    
    //public 
    class World extends Sprite {
        private var _nodes:Vector.<Vector.<Node>>;
        private var _starts:Vector.<Start>;
        private var _goals:Vector.<Goal>;
        
        private var _towers:Vector.<Tower>;
        private var _bullets:Vector.<Bullet>;
        private var _groundEnemies:Vector.<Enemy>;
        private var _flyingEnemies:Vector.<Enemy>;
        
        private var _towerLayer:Sprite;
        private var _enemyLayer:Sprite;
        private var _bulletLayer:Sprite;
        private var _effectLayer:Sprite;
        private var _cursor:Cursor;
        
        public function getNode(col:int, row:int):Node { return _nodes[row][col]; }

        public function getStartingPos(startIndex:int):TileBasedPoint {
            return _starts[startIndex].getRandomSpawningPosition();
        }

        public function numEnemies():int { return _groundEnemies.length + _flyingEnemies.length; }

        //----------------------------------------------------------------------        
        //ワールド画面の設置 (画面の開始位置は受け取る) 【F】
        public function World(posx:int, posy:int) {
            x = posx;
            y = posy;
            
            //初期化用パブリックファンクション【F】
            initializeNodes();
            initializeStarts();
            initializeGoals();
            
            _towers = new Vector.<Tower>();
            _bullets = new Vector.<Bullet>();
            _groundEnemies = new Vector.<Enemy>();
            _flyingEnemies = new Vector.<Enemy>();
            
            addChild(new Bitmap(ImageFactory.getImage("World")));
            addChild(_towerLayer = new Sprite());
            addChild(_enemyLayer = new Sprite());
            addChild(_bulletLayer = new Sprite());
            addChild(_effectLayer = new Sprite());
            addChild(_cursor = new Cursor(this));
            _enemyLayer.mouseChildren = _bulletLayer.mouseChildren = false;
            _enemyLayer.mouseEnabled = _bulletLayer.mouseEnabled = false;
            
            //画面上をクリックされたら、基本はタワー配置操作とし、いろいろチェックして対応【F】
            addEventListener(MouseEvent.CLICK, addTower);
        }
        
        private function initializeNodes():void {
            _nodes = new Vector.<Vector.<Node>>();
            for (var row:int = 0; row < Const.NODE_ROWS; row++) {
                _nodes[row] = new Vector.<Node>();
                for (var col:int = 0; col < Const.NODE_COLS; col++) {
                    _nodes[row][col] = new Node(col, row, Config.NODE_TYPE[row][col]);
                }
            }
        }
        
        private function initializeStarts():void {
            _starts = Config.getStarts();
        }
        
        private function initializeGoals():void {
            _goals = Config.getGoals();
            for (var i:int = 0; i < _goals.length; i++) {
                var goal:Goal = _goals[i];
                goal.setNode(_nodes[goal.tileY][goal.tileX]);
                goal.search(this);
            }
        }


    //----------------------------------------------------------------------
    //World.update の設定【F】

        public function update():void {
            var i:int;
            //まず存在している各タワーのupdate (タワークラスのPbFc)【F】
            for (i = 0; i < _towers.length; i++) {
                _towers[i].update();
            }
            //(敵数になるまで)i番目の敵のupdate(エネミークラスのPbFc)【F】
            for (i = 0; i < _groundEnemies.length; i++) {
                var groundEnemy:Enemy = _groundEnemies[i];
                _nodes[groundEnemy.tileY][groundEnemy.tileX].numEnemy--;
                _groundEnemies[i].update(this);
                _nodes[groundEnemy.tileY][groundEnemy.tileX].numEnemy++;
            }
            
            for (i = 0; i < _flyingEnemies.length; i++) {
                _flyingEnemies[i].update(this);
            }
            
            //弾丸の数だけupdate(bulletクラスのPbFc)【F】
            for (i = 0; i < _bullets.length; i++) {
                _bullets[i].update();
            }
            //カーソルもupdate【F】
            _cursor.update(mouseX - Const.CURSOR_OFFSET, mouseY - Const.CURSOR_OFFSET);
        }
        
        
        // すべてのタワー・弾・敵を消去する
        public function clear():void {
            var i:int;
            for (i = _towers.length - 1; i >= 0; i--) { 
                removeTower(_towers[i], true); }
            for (i = 0; i < _goals.length; i++) { _goals[i].search(this); }
            for (i = _groundEnemies.length - 1; i >= 0; i--) { removeEnemy(_groundEnemies[i]); }
            for (i = _flyingEnemies.length - 1; i >= 0; i--) { removeEnemy(_flyingEnemies[i]); }
            for (i = _bullets.length - 1; i >= 0; i--) { removeBullet(_bullets[i]); }
            initializeNodes();
            initializeStarts();
            initializeGoals();
        }
        
        //----------------------------------------------------
        // マウスイベント:タワーを(設置できるなら)設置する【F】
        
        public function addTower(e:MouseEvent):void {
            var position:TileBasedPoint = TileBasedPoint.createFromWorldPos(mouseX - Const.CURSOR_OFFSET, mouseY - Const.CURSOR_OFFSET);
            position.setTilePos(position.tileX, position.tileY);
            //クリックイベントでタイルポジションを取得しておく【F】

                var nearestGoal:Goal;
                var blocking:Boolean = false;
                var tower:Tower = new Tower(position.x, position.y, GameData.instance.selectedTower.type, this);
                var type:TowerType = tower.type;
        
            //お金やタイル状態的にタワー設置可能をを調べる(キャンビルド)をまず実行【F】
            if (canBuildTower(position.tileX, position.tileY)) {
                // 以下キャンビルドOK時の処理【F】
                var i:int, j:int;                 
                // タワーが設置される場所をタワー建設不能にする【F】
                if (!type.towerbase){
                for (var row:int = 0; row < 2; row++) {
                    for (var col:int = 0; col < 2; col++) {
                        var node:Node = _nodes[position.tileY + row][position.tileX + col];
                        node.placeable = false} ;
                    }
                }
                // ベースが設置される場所を通行不能&ベース建設不能&タワー建設可能にする【F】
                // 以下の経路探査操作はベース設置時のみ【F】
                if (type.towerbase){
                for(row = 0; row < 2; row++) {
                   for (col = 0; col < 2; col++) {
                        node = _nodes[position.tileY + row][position.tileX + col];
                        node.passable = node.buildable = false;
                        node.placeable =true } ;
                }                      
                // 全ての経路の最探索
                for (i = 0; i < _goals.length; i++) {
                    _goals[i].search(this);
                }                
                // 全てのスタート、全ての敵(地上)、のゴールを更新
                // ブロッキングが発生していたら中断
                for (i = 0; !blocking && (i < _starts.length); i++) {
                    var start:Start = _starts[i];
                    if (start.forFlying) { continue; }
                    nearestGoal = getNearestGoalFrom(start.posX, start.posY, false);
                    if (!nearestGoal.hasPath(start.tileX,start.tileY)) { blocking = true; }
                }
                for (i = 0; !blocking && (i < _groundEnemies.length); i++) {
                    var enemy:Enemy = _groundEnemies[i];
                    nearestGoal = getNearestGoalFrom(enemy.posX, enemy.posY, false);
                    enemy.setGoal(nearestGoal);
                    if (!enemy.hasPathToGoal()) { blocking = true; }
                }             
                }   // ベース設置時のみここまで【F】
                
                // ブロッキングが発生していたら、
                // 全ての変更を元に戻してタワー設置失敗で終了
                // そうでなければ、実際にタワーを設置する
                // ベースじゃない通常タワーはblocking=常にfalseで通過【F】
                if (blocking) {
                    _cursor.blockingAlart();                    
                    // 通行不能にした場所を元に戻す
                    for (row = 0; row < 2; row++) {
                        for (col = 0; col < 2; col++) {
                            node = _nodes[position.tileY + row][position.tileX + col];

                            node.passable = node.buildable = true;
                            node.placeable = false;
                        }
                    }
                    // 全ての経路を元に戻す
                    for (i = 0; i < _goals.length; i++) {
                        _goals[i].revertToPrevious();
                    }
                    // 全ての敵(地上)のゴールを更新
                    for (i = 0; i < _groundEnemies.length; i++) {
                        _groundEnemies[i].setGoal(getNearestGoalFrom(_groundEnemies[i].posX, _groundEnemies[i].posY, false));
                    }
                }else {
                    _towers.push(tower);
                    _towerLayer.addChild(tower);
                    //ベースはワールド設置時にクリック透過。選択&売却不能。
                    if (type.towerbase){ tower.mouseEnabled = false }
                    GameData.instance.gold -= tower.type.getStatus(tower.level).cost;
                }
            }
        }
                    
        // そもそも建築できる場所なのかファンクション 【F】
        public function canBuildTower(tilex:int, tiley:int):Boolean {
            var selectedTower:Tower = GameData.instance.selectedTower;
            var _type:TowerType = selectedTower.type;
            
            // タワー選択ボタンを選択中か、十分な所持金があるか調べる
            if (selectedTower == null || selectedTower.active || (GameData.instance.gold < selectedTower.type.getStatus(selectedTower.level).cost)) { return false; } 
            // 引数で指定した場所にタワーが建てられるか調べる
            for (var row:int = 0; row < 2; row++) {
                for (var col:int = 0; col < 2; col++) {
                    var node:Node = _nodes[tiley + row][tilex + col];                       
                    if (_type.towerbase){            
                        if (!node.buildable || (node.numEnemy > 0)) { return false; }
                    }else{
                        if (!node.placeable ) { return false; }                   
                    }
                }
            }            
            return true;
        }


        //----------------------------------------------------
        // タワーのターゲットを探してそれを返す(いなければnullを返す)
        public function findTarget(posx:Number, posy:Number, range:int, ground:Boolean, air:Boolean):Enemy {
            var i:int, enemy:Enemy, diffX:Number, diffY:Number;
            var rangeSq:int = range * range;
            
            // 地上に攻撃できるなら、地上の敵のターゲットを探す
            if (ground) {
                for (i = 0; i < _groundEnemies.length; i++) {
                    enemy = _groundEnemies[i];
                    diffX = posx - enemy.posX;
                    diffY = posy - enemy.posY;
                    if (diffX * diffX + diffY * diffY < rangeSq) {
                        if (enemy.targetable) { return enemy }
                    }
                }
            }
            
            // 空中に攻撃できるなら、飛んでいる敵のターゲットを探す
            if (air) {
                for (i = 0; i < _flyingEnemies.length; i++) {
                    enemy = _flyingEnemies[i];
                    diffX = posx - enemy.posX;
                    diffY = posy - enemy.posY;
                    if (diffX * diffX + diffY * diffY < rangeSq) {
                        if (enemy.targetable) { return enemy }                    }
                }
            }
            
            // ターゲットが見つからなければnull
            return null;
        }
        

        //----------------------------------------------------
        // 引数で指定した位置から最も近いゴールを返す
        private function getNearestGoalFrom(posx:Number, posy:Number, flying:Boolean):Goal {
            var nearest:Goal = _goals[0];
            for (var i:int = 1; i < _goals.length; i++) {
                if (_goals[i].getCost(posx, posy, flying) < nearest.getCost(posx, posy, flying)) {
                    nearest = _goals[i];
                }
            }
            return nearest;
        }
        
        //----------------------------------------------------
        // タワーを消去する 
        //引数補足「clear=true:画面初期化」「clear=false(void):売却」
        public function removeTower(tower:Tower, clear:Boolean = false):void {
            var position:TileBasedPoint = TileBasedPoint.createFromWorldPos(tower.x, tower.y);
            for (var row:int = 0; row < 2; row++) {
                for (var col:int = 0; col < 2; col++) {
                    var node:Node = _nodes[position.tileY + row][position.tileX + col];
                    //元々が通路型の土地だったら …clearなら土台も消え通行可能TTF、売却なら土台が残っていて通行不可能FFT
                    if(Config.NODE_TYPE[position.tileY + row][position.tileX + col] == 0) {
                       node.passable = node.buildable = clear ; node.placeable = (!clear);
                    }
                    //元々が壁型の土地だったら 
                    if(Config.NODE_TYPE[position.tileY + row][position.tileX + col] == 1) {
                       node.passable = false; node.buildable = clear ; node.placeable = true;
                    }
                }
            }
            
            // ブロッキングを考慮せずに
            // 全ての経路の最探索と、全ての敵(地上)のゴールを更新
            // clear()時は最探索する必要
            if (!clear) {
                var i:int;
                for (i = 0; i < _goals.length; i++) {
                    _goals[i].search(this);
                }
                for (i = 0; i < _groundEnemies.length; i++) {
                    _groundEnemies[i].setGoal(getNearestGoalFrom(_groundEnemies[i].posX, _groundEnemies[i].posY, false));
                }
            }
            
            _towerLayer.removeChild(tower);
            _towers.splice(_towers.indexOf(tower), 1);
        }
        
        //----------------------------------------------------
        // 弾を出現させる
        public function addBullet(bullet:Bullet):void {
            _bullets.push(bullet);
            _bulletLayer.addChild(bullet);
        }
        
        // 弾を消去する
        public function removeBullet(bullet:Bullet):void {
            _bulletLayer.removeChild(bullet);
            _bullets.splice(_bullets.indexOf(bullet), 1);
        }
        
        //----------------------------------------------------
        // 敵を出現させる
        public function addEnemy(enemy:Enemy):void {
            enemy.setGoal(getNearestGoalFrom(enemy.posX, enemy.posY, enemy.type.flying));
            
            if (enemy.type.flying) {
                _flyingEnemies.push(enemy);
            }else {
                _groundEnemies.push(enemy);
                _nodes[enemy.tileY][enemy.tileX].numEnemy++;
            }
            _enemyLayer.addChild(enemy);
        }
        
        // 敵を消去する
        public function removeEnemy(enemy:Enemy):void {
            _enemyLayer.removeChild(enemy);
            if (enemy.type.flying) {
                _flyingEnemies.splice(_flyingEnemies.indexOf(enemy), 1);
            }else {
                _nodes[enemy.tileY][enemy.tileX].numEnemy--;
                _groundEnemies.splice(_groundEnemies.indexOf(enemy), 1);
            }
        }
        
        // エフェクトを発生させる
        public function addEffect(effect:Sprite):void {
            _effectLayer.addChild(effect);
        }
        // 範囲攻撃
        public function damageSurroundingEnemies(bullet:Bullet):void {
            var i:int, enemy:Enemy;
            if (bullet.ground) {
                for (i = _groundEnemies.length - 1; i >= 0; i--) {
                    enemy = _groundEnemies[i];
                    if (bullet.isHitTarget(enemy, bullet.splashRadius)) { bullet.damageTarget(enemy); }
                }
            }
            if (bullet.air) {
                for (i = _flyingEnemies.length - 1; i >= 0; i--) {
                    enemy = _flyingEnemies[i];
                    if (bullet.isHitTarget(enemy, bullet.splashRadius)) { bullet.damageTarget(enemy); }
                }
            }
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * Node
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    //public 
    class Node {
        private var _center:TileBasedPoint;    // 中心の座標
        private var _passable:Boolean;        // 敵が通れるかどうか
        private var _buildable:Boolean;        // 足場を建てられるかどうか【F】
        private var _placeable:Boolean;        // タワーを建てられるかどうか【F】
        private var _numEnemy:int;            // このノード上にいる敵の数
        
        public function get tileX():int { return _center.tileX; }
        public function get tileY():int { return _center.tileY; }
        public function get centerX():Number { return _center.x; }
        public function get centerY():Number { return _center.y; }
        public function get passable():Boolean { return _passable; }
        public function get buildable():Boolean { return _buildable; }
        public function get placeable():Boolean { return _placeable; }   //追加【F】
        public function get numEnemy():int { return _numEnemy; }
        
        public function set passable(value:Boolean):void { _passable = value; }
        public function set buildable(value:Boolean):void { _buildable = value; }
        public function set placeable(value:Boolean):void { _placeable = value; }  //追加【F】
        public function set numEnemy(value:int):void { _numEnemy = value; }
        
        public function Node(tilex:int, tiley:int, type:int) {
            _center = TileBasedPoint.createFromTilePos(tilex, tiley);
            _center.x += Const.NODE_SIZE / 2;
            _center.y += Const.NODE_SIZE / 2;
            
            switch(type) {    // 追加【F】
                case 0: { _passable = true; _buildable = true; _placeable =false; break; }  // 通路となる土地。土台を置けるが、タワーを置けない【F】
                case 1: { _passable = false; _buildable = false; _placeable =true; break; }  // 土台と同等の土地。通過できないがタワーを置ける【F】
                case 2: { _passable = true; _buildable = false; _placeable = false; break; }  // 敵の出入り口。通過できるが、何も置けない【F】
                case 3: { _passable = false; _buildable = false; _placeable = false; break; }  //  ゲーム中、何も置けない土地【F】
            }
            _numEnemy = 0;
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * Start
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    //public 
    class Start {
        private var _position:TileBasedPoint;
        private var _width:int;
        private var _forFlying:Boolean;
        
        public function get posX():Number { return _position.x; }
        public function get posY():Number { return _position.y; }
        public function get tileX():int { return _position.tileX; }
        public function get tileY():int { return _position.tileY; }
        public function get forFlying():Boolean { return _forFlying; }
        
        public function Start(tilex:int, tiley:int, width:int, forFlying:Boolean) {
            _position = TileBasedPoint.createFromTilePos(tilex, tiley);
            _width = width * Const.NODE_SIZE;
            _forFlying = forFlying;
        }
        
        // ランダムな出現位置を取得する
        public function getRandomSpawningPosition():TileBasedPoint {
            var posx:int = int(_position.x + ((2 * _width * Math.random()) - _width));
            var posy:int = int(_position.y + Const.NODE_SIZE);
            return TileBasedPoint.createFromWorldPos(posx, posy);
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * Goal
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    //public 
    class Goal {
        private static const DX:Array = [0, -1, 1, 0, -1, 1, -1, 1];
        private static const DY:Array = [ -1, 0, 0, 1, -1, -1, 1, 1];
        private static const DCOST:Array = [1, 1, 1, 1, Math.SQRT2, Math.SQRT2, Math.SQRT2, Math.SQRT2];
        
        private var _center:TileBasedPoint;
        private var _node:Node;
        private var _openNodes:Vector.<Node>;            // 保留ノードリスト
        private var _nodeCost:Vector.<Vector.<Number>>;    // 各ノードの移動コスト
        private var _nodeNext:Vector.<Vector.<Node>>;    // 各ノードの次の経路となるノード
        
        private var _previousNodeCost:Vector.<Vector.<Number>>;    // 以前のnodeCost
        private var _previousNodeNext:Vector.<Vector.<Node>>;    // 以前のnodeNext
        
        public function get tileX():int { return _center.tileX; }
        public function get tileY():int { return _center.tileY; }
        
        public function Goal(tilex:int, tiley:int) {
            _center = TileBasedPoint.createFromTilePos(tilex, tiley);
            _center.setWorldPos(_center.x + Const.NODE_SIZE / 2, _center.y + Const.NODE_SIZE / 2);
            _openNodes = new Vector.<Node>();
            _nodeCost = null; _nodeNext = null;
        }
        public function setNode(node:Node):void { _node = node; }
        
        // 引数で指定した位置から、ゴールまでのコストを返す
        public function getCost(posx:Number, posy:Number, flying:Boolean):Number {
            if (flying) {
                var diffx:Number = _center.x - posx;
                var diffy:Number = _center.y - posy;
                return diffx * diffx + diffy * diffy;
            }
            
            var postion:TileBasedPoint = TileBasedPoint.createFromWorldPos(posx, posy);
            return _nodeCost[postion.tileY][postion.tileX];
        }
        
        // 引数で指定した位置から、ゴールへ向かう経路が存在しているかどうか
        public function hasPath(tilex:int, tiley:int):Boolean {
            return _nodeCost[tiley][tilex] != Number.MAX_VALUE;
        }
        
        // 引数で指定した位置から、ゴールへ向かう為の次のノードを返す
        public function getNext(posx:Number, posy:Number, flying:Boolean):Node {
            if (flying) {
                return _node;
            }
            
            var position:TileBasedPoint = TileBasedPoint.createFromWorldPos(posx, posy);
            return _nodeNext[position.tileY][position.tileX];
        }
        
        // Dijkstra法による経路探索
        public function search(world:World):void {
            setup(world);
            
            while (_openNodes.length > 0) {
                var subject:Node = _openNodes.pop() as Node;
                
                // 周囲8方向のノードを訪問する
                for (var i:int = 0; i < 8; i++) {
                    // 画面外の存在しないノードを指すなら次の周囲ノードへ進む
                    if (!isValid(subject.tileX + Goal.DX[i], subject.tileY + Goal.DY[i])) { continue; }
                    // 通れないノード、計算済み(確定)ノード、直進することができないノードなら次の周囲ノードへ進む
                    var test:Node = world.getNode(subject.tileX + Goal.DX[i], subject.tileY + Goal.DY[i]);
                    if (!test.passable || isCalculatedNode(test) || !canGoStraightTo(subject, test, world)) { continue; }
                    
                    // 移動コストを計算する
                    _nodeCost[test.tileY][test.tileX] = _nodeCost[subject.tileY][subject.tileX] + Goal.DCOST[i];
                    // 次の経路ノードをsubjectノードに設定する
                    _nodeNext[test.tileY][test.tileX] = subject;
                    // 保留ノードリストに追加する
                    insertToOpenNodes(test);
                }
            }
        }
        
        // 探索前の準備
        private function setup(world:World):void {
            _previousNodeCost = _nodeCost;
            _previousNodeNext = _nodeNext;
            
            _nodeCost = new Vector.<Vector.<Number>>();
            _nodeNext = new Vector.<Vector.<Node>>();
            for (var row:int = 0; row < Const.NODE_ROWS; row++) {
                _nodeCost[row] = new Vector.<Number>();
                _nodeNext[row] = new Vector.<Node>();
                for (var col:int = 0; col < Const.NODE_COLS; col++) {
                    _nodeCost[row][col] = Number.MAX_VALUE;
                    _nodeNext[row][col] = world.getNode(col, row);
                }
            }
            
            // Goalのノードを経路探索のスタートノードとする
            _nodeCost[_center.tileY][_center.tileX] = 0;
            _openNodes.push(_node);
        }
        
        // indexの値が有効な値かどうか
        private function isValid(col:int, row:int):Boolean {
            return (col >= 0) && (col < Const.NODE_COLS) && (row >= 0) && (row < Const.NODE_ROWS);
        }
        
        // 既にコストを計算済みのノードかどうか
        private function isCalculatedNode(node:Node):Boolean {
            return _nodeCost[node.tileY][node.tileX] != Number.MAX_VALUE;
        }
        
        // subjectノードからtestノードへ直進できるかどうか
        private function canGoStraightTo(subject:Node, test:Node, world:World):Boolean {
            return world.getNode(subject.tileX, test.tileY).passable && world.getNode(test.tileX, subject.tileY).passable;
        }
        
        // nodeを保留ノードリストの適切な場所に挿入する
        private function insertToOpenNodes(node:Node):void {
            var insertIndex:int;
            var nodeCost:Number = _nodeCost[node.tileY][node.tileX];
            
            for (insertIndex = 0; insertIndex < _openNodes.length; insertIndex++) {
                var openNode:Node = _openNodes[insertIndex];
                if (nodeCost > _nodeCost[openNode.tileY][openNode.tileX]) { break; }
            }
            _openNodes.splice(insertIndex, 0, node);
        }
        
        // 最探索更新前の経路情報に戻す
        public function revertToPrevious():void {
            _nodeCost = _previousNodeCost;
            _nodeNext = _previousNodeNext;
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * Tower
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.text.TextField;
    
    //public 
    class Tower extends Sprite {
        private var _center:TileBasedPoint;
        private var _type:TowerType;        // 種類
        private var _level:int;                // 現在のレベル
        private var _world:World;
        private var _target:Enemy;            // 現在のターゲット
        private var _reloadCount:Number;    // 100を超えたら弾発射
        
        private var _body:Sprite;
        private var _levelText:TextField;
        
        public function get tileX():int { return _center.tileX; }
        public function get tileY():int { return _center.tileY; }
        public function get type():TowerType { return _type; }
        public function get level():int { return _level; }
        public function get active():Boolean { return _world != null; }
        
        //----------------------------------------------------
        public function Tower(posx:int, posy:int, type:TowerType, world:World = null) {
            x = posx;
            y = posy;
            
            _center = TileBasedPoint.createFromWorldPos(posx + Const.TOWER_SIZE / 2, posy + Const.TOWER_SIZE / 2);
            _type = type;
            _level = 1;
            _world = world;
            _target = null;
            _reloadCount = 0;
            
            draw();
            
            buttonMode = true;
            mouseChildren = false;
            
           addEventListener(MouseEvent.CLICK, clickTower, false, 0, true);         
        }

        //----------------------------------------------------
        // タワーの画像を描画する
        private function draw():void {
            addChild(new Bitmap(ImageFactory.getImage("Circle")));
            _body = addChild(new Sprite()) as Sprite;
            var bitmap:Bitmap = _body.addChild(new Bitmap(ImageFactory.getImage(_type.name), "auto", true)) as Bitmap;
            bitmap.x = bitmap.y = int( -Const.TOWER_SIZE / 2);
            _body.x = _body.y = int(Const.TOWER_SIZE / 2);
            
            if (active) {
                if ( !_type.towerbase ) { _body.rotation = 360 * Math.random() - 180};
                if ( !_type.towerbase ) { addChild(_levelText = ImageFactory.createBorderedText(Const.TOWER_SIZE - 10, Const.TOWER_SIZE - 10, 10, 10, _level.toString(), 10, 0xffffff, 0x000000))};
               }
        }
           
        // タワーをクリックしたとき
        public function clickTower(e:MouseEvent = null):void {
            GameData.instance.selectedTower = this;            
        }
      
        //----------------------------------------------------
        public function update():void {
            var range:int = _type.getStatus(_level).range;
            // ターゲット無しorターゲットがやられていたorターゲットが消えたなら、新しいターゲットを探す
            if (_target == null || _target.isDead() || (!_target.targetable) ) {
                _target = _world.findTarget(_center.x, _center.y, range, _type.ground, _type.air);
            }
            
            // リロードカウントを進める
            if (_reloadCount < 100) { _reloadCount += _type.getStatus(_level).reloadSpeed; }
            
            if (_target != null) {
                var rangeSq:int = range * range;
                var diffX:Number = _target.posX - _center.x;
                var diffY:Number = _target.posY - _center.y;
                if (diffX * diffX + diffY * diffY < rangeSq) {
                    _body.rotation = _type.adjustBodyRotation(diffX, diffY, _body.rotation);
                    // リロードを終えていて、ターゲットがいるなら弾を発射する
                    if (_reloadCount >= 100 && _target != null) {
                        _reloadCount = 0;
                        _world.addBullet(type.createBullet(_center.x, _center.y, _level, _target, _world));
                    }
                }else {
                    // ターゲットが射程外になっていたらターゲットから外す
                    _target = null;
                }
            }
        }
        
        public function upgrade():void {
            // 既に最高レベルになっていたら終了
            if (!_type.hasStatus(_level + 1)) { return; }
            
            // アップグレードするだけの所持金があれば、アップグレード
            var upgradeCost:int = _type.getStatus(_level + 1).cost - _type.getStatus(_level).cost;
            if (upgradeCost <= GameData.instance.gold) {
                _level++;
                _levelText.text = _level.toString();
                GameData.instance.gold -= upgradeCost;
                GameData.instance.selectedTower = this;
            }
        }
        
        public function sell():void {
            _world.removeTower(this);
            GameData.instance.gold += _type.getStatus(_level).cost * GameData.instance.sellingRatio;
            GameData.instance.selectedTower = null;
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * TowerType
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.BitmapData;
    
    //public 
    class TowerType {
        private var _name:String;                    // 種類名
        private var _towerbase:Boolean;              //足場(タワーベース)型か【F】
        private var _ground:Boolean;                // 対地攻撃可能か
        private var _air:Boolean;                    // 対空攻撃可能か
        private var _slow:int;                    // スロー効果量
        private var _venom:int;                    //毒攻撃力
        private var _splash:int;                // 範囲攻撃サイズ
        private var _status:Vector.<TowerStatus>;    // (レベルごとの)各ステータス
        
        public function get name():String { return _name; }
        public function get ground():Boolean { return _ground; }
        public function get towerbase():Boolean { return _towerbase; }
        public function get air():Boolean { return _air; }
        public function get slow():int { return _slow; }
        public function get venom():int { return _venom; }
        public function get splash():int { return _splash; }
        public function getStatus(level:int):TowerStatus { return _status[level - 1]; }
        
        // ※インスタンスは Config.getTowerType() から生成する
        public function TowerType(name:String, towerbase:Boolean ,ground:Boolean, air:Boolean, slowing:int, splash:int, venom:int) {
            _name = name;
            _towerbase=towerbase;
            _ground = ground;
            _air = air;
            _slow = slowing;
            _splash = splash;
            _venom = venom;
            _status = Config.getTowerStatus(_name);
        }
        
        // 指定したレベルのステータスがあるかどうか
        public function hasStatus(level:int):Boolean {
            return level <= _status.length;
        }
        
        // 種類に応じて、砲頭の角度を調整する
        public function adjustBodyRotation(diffx:Number, diffy:Number, currentRotation:Number):Number {
            switch(_name) {
                case "Voltex": { return currentRotation + 10; }
                default: { return Math.atan2(diffy, diffx) * 180 / Math.PI; }
            }
        }
        
        // 種類に応じた弾を生成する
        public function createBullet(posx:int, posy:int, level:int, target:Enemy, world:World):Bullet {
            var image:BitmapData = ImageFactory.getImage("Bullet_" + _name);
            var pos:TileBasedPoint = TileBasedPoint.createFromWorldPos(posx, posy);
            var status:TowerStatus = getStatus(level);

            switch(_name) {
            // Bullet引数内訳(pos:TileBasedPoint, life:int, power:int, radius:int, speed:int, ground:Boolean, air:Boolean, level:int
            //               slow:int,venom:int, homing:Boolean, pierce:Boolean, target:Enemy, image:BitmapData, world:World)
                //case "Arrow":
                //{ return new Bullet(pos, status.range, status.damage, _splash, 8, _ground, _air, level, _slow, _venom, false, false, target, image, world); }
                case "Gun":
                { return new Bullet(pos, status.range, status.damage, _splash, (12+2*level), _ground, _air, level, _slow, _venom, true, false, target, image, world); }
                case "Gatling":
                { return new Bullet(pos, status.range, status.damage, _splash, 24, _ground, _air, level, _slow, _venom, false, false, target, image, world); }
                case "Cannon":
                { return new Bullet(pos, status.range, status.damage, _splash, 8, _ground, _air, level, _slow, _venom, true, false, target, image, world); }
                case "Venom":
                { return new Bullet(pos, status.range, status.damage, _splash, 10, _ground, _air, level, _slow, _venom, true, false, target, image, world); }
                case "Voltex":
                { return new Bullet(pos, 0, status.damage, status.range, 0, _ground, _air, level, _slow, _venom, false, false, target, image, world); }
                case "AntiFly":
                { return new Bullet(pos, 900, status.damage, (Const.ENEMY_SIZE + Const.BULLET_SIZE) / 2, Const.NODE_SIZE, _ground, _air, level, _slow, _venom, false, true, target, image, world); }
            }
            return null; // never called
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * TowerStatus
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    //public 
    class TowerStatus {
        private var _level:int;            // レベル 
        private var _cost:int;            // コスト
        private var _damage:int;        // ダメージ
        private var _range:int;            // 射程
        private var _firerate:Number;    // 射撃間隔(発/秒)
        private var _reloadSpeed:Number;
        
        public function get level():int { return _level; }
        public function get cost():int { return _cost; }
        public function get damage():int { return _damage; }
        public function get range():int { return _range; }
        public function get firerate():Number { return _firerate; }
        public function get reloadSpeed():Number { return _reloadSpeed; }
        
        // ※インスタンスは Config.getTowerStatus() から生成する
        public function TowerStatus(level:int, cost:int, damage:int, range:int, firerate:Number) {
            _level = level;
            _cost = cost;
            _damage = damage;
            _range = range;
            _firerate = firerate;
            _reloadSpeed = _firerate * 100 / Const.FRAME_RATE;
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * Bullet
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.geom.Point;
    
    //public 
    class Bullet extends Sprite {
        private var _life:int;            // 寿命(最大射程)
        private var _power:int;            // 威力
        private var _splashRadius:int;    // 範囲攻撃の半径(範囲攻撃で無いなら0)
        private var _speed:int;            // 速さ
        private var _ground:Boolean;    // 地上の敵に当たるか
        private var _air:Boolean;        // 空中の敵にあたるか
        private var _level:int;        // 発射弾のレベル
        private var _slow:int;        // スロー効果量
        private var _venom:int;        // 毒効果量
        private var _homing:Boolean;    // 追尾能力
        private var _pierce:Boolean;    // 貫通力
        private var _target:Enemy;        // ターゲット
        private var _world:World;
        
        private var _position:TileBasedPoint;    // 位置
        private var _velocity:Point;            // 速度
        
        public function get splashRadius():int { return _splashRadius; }
        public function get ground():Boolean { return _ground; }
        public function get air():Boolean { return _air; }
        
        public function Bullet(
            pos:TileBasedPoint, 
            life:int, power:int, radius:int, speed:int, 
            ground:Boolean, air:Boolean, level:int, slow:int, venom:int,
            homing:Boolean, pierce:Boolean, 
            target:Enemy, image:BitmapData, world:World)
        {
            _life = life;
            _power = power;
            _splashRadius = radius;
            _speed = speed;
            _ground = ground;
            _air = air;
            _level = level;
            _slow = slow;
            _venom = venom;
            _homing = homing;
            _pierce = pierce;
            _target = target;
            _world = world;
            
            _position = pos;
            x = int(_position.x);
            y = int(_position.y);
            _velocity = new Point();

            changeVelocity();
            draw(image);
        }
        
        private function draw(image:BitmapData):void {
            var bitmap:Bitmap = new Bitmap(image);
            bitmap.x = bitmap.y = -int(Const.BULLET_SIZE / 2);
            addChild(bitmap);
        }
        
        // 速度を変更し、向きを変える
        private function changeVelocity():void {
            var diffX:Number = _target.posX - _position.x;
            var diffY:Number = _target.posY - _position.y;
            var radian:Number = Math.atan2(diffY, diffX);
            _velocity.x = _speed * Math.cos(radian);
            _velocity.y = _speed * Math.sin(radian);
            
            var degree:Number = radian * 180 / Math.PI;
            rotation = degree;
        }

        
        public function update():void {
            // 移動する
            _life -= _speed;
            x = int(_position.x += _velocity.x);
            y = int(_position.y += _velocity.y);
            if (_homing) { changeVelocity(); }
            
            // 画面外に出たら、消滅する
            if (_position.x < 0 || _position.x > 465 || _position.y < 0 || _position.y > 465) {
                _world.removeBullet(this);
                return;
            }
            
            // 射程外に出たら、(範囲攻撃の弾なら周辺の敵にダメージを与え)消滅する
            // 範囲攻撃の弾なら範囲アニメを出すspreadEffects(位置x、位置y、スプレッドサイズ、色、時間)
            if (_life <= 0) {
                if (_splashRadius > 0) { 
                    if(_slow > 0){_world.addEffect(new splashEffect(x, y, _splashRadius,0x000000,3))
                    }else if(_venom > 0){_world.addEffect(new splashEffect(x, y, _splashRadius,0x00aa00,1))
                    }else {_world.addEffect(new splashEffect(x, y, _splashRadius,0xff5500,1))};
                    _world.damageSurroundingEnemies(this); 
                }
                _world.removeBullet(this);
                return;
            }
            
            // 貫通力ありなら、(ターゲットを問わず)周辺の敵にダメージを与える
            // ターゲットが死んでいたら、直線軌道に変更
            // ターゲットに当たっていたら、ダメージを与え消滅する
            if (_pierce) {
                _world.damageSurroundingEnemies(this);
            }else if (_target.isDead()) {
                _homing = false;
            }else if (isHitTarget(_target, (Const.BULLET_SIZE + Const.ENEMY_SIZE) / 2)) {
                if (_splashRadius > 0) {
                    if(_slow > 0){_world.addEffect(new splashEffect(x, y, _splashRadius,0x000000,3))
                    }else if(_venom > 0){_world.addEffect(new splashEffect(x, y, _splashRadius,0x00aa00,1))
                    }else {_world.addEffect(new splashEffect(x, y, _splashRadius,0xff5500,1))};
                    _world.damageSurroundingEnemies(this); 
                }else { damageTarget(_target); }
                _world.removeBullet(this);
                return;
            }
        }

        
        public function isHitTarget(target:Enemy, radius:Number):Boolean {
            var diffX:Number = target.posX - _position.x;
            var diffY:Number = target.posY - _position.y;
            return diffX * diffX + diffY * diffY < radius * radius;
        }
        
        public function damageTarget(target:Enemy):void {
            target.damage(_power, _level, _slow,_venom);
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * Enemy
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.filters.GlowFilter;
    import flash.geom.Point;
    
    //public 
    class Enemy extends Sprite {
        private var _world:World;
        private var _center:TileBasedPoint;    // 中心の座標
        private var _velocity:Point;        // 速度ベクトル
        private var _currentSpeed:Number;    //速度の変更時に参照する基本速度の値
        private var _type:EnemyType;        // 種族
        private var _HP:int;                // 現在のHP
        private var _maxHP:int;                // 最大HP
        private var _point:int;                // 倒した時のポイント
        private var _money:int;                // 倒した時のお金
        private var _targetable:Boolean;    // 索敵可能かどうか
        private var _isBaby:Boolean;    //出産能力で生まれた場合TRUE(ゲートやスキルの効果を子どもにも継続させる場合に参照)
        private var _babyNum:int;    //出産能力がある場合の出産合計数
        
        private var _liveCount:int;            //出現時間カウント(ランダムな位相差あり)
        private var _slowingCount:int;        //スロウ効果の時間カウント
        private var _attackedSlow:int;        //スロウ効果によって減少した速度値(一時変化)
        private var _venomingCount:int;     //毒効果の時間カウント
        private var _venomingLevel:int;     //毒効果の最大レベルを継続する
        private var _regeneAmount:Number;     //小数で累積する回復量のカウント
        private var _fadeAlpha:Number;        //フェイド能力のアルファ値
        private var _BA:BornAbility;        //出産能力
        private var _AA:AccelerateAbility;    //加速能力
        
        private var _image:Sprite;
        private var _HPbar:Sprite;
        
        private var _goal:Goal;
        private var _nextNode:Node;
        
        public function get posX():Number { return _center.x; }
        public function get posY():Number { return _center.y; }
        public function get tileX():int { return _center.tileX; }
        public function get tileY():int { return _center.tileY; }
        public function get type():EnemyType { return _type; }
        public function get targetable():Boolean { return _targetable; }
        public function get BA():BornAbility { return _BA; }
        public function get AA():AccelerateAbility { return _AA; }
        public function isDead():Boolean { return _HP <= 0; }
        public function isBaby():Boolean { return _isBaby; }
        public function babyNum():int { return _babyNum; }
        public function setGoal(value:Goal):void {
            _goal = value;
            _nextNode = _goal.getNext(_center.x, _center.y, _type.flying);
        }
        
        public function Enemy(center:TileBasedPoint, type:EnemyType, HP:int, point:int, money:int, world:World ,isBaby:Boolean) {
            _world = world;
            _isBaby = isBaby;
            _center = center;
            x = int(_center.x);
            y = int(_center.y);
            _type = type;
            _velocity = new Point(0,0); //移動の速度ベクトルは出現時ゼロ
            _currentSpeed = type.speed; //ベクトルの長さとなる移動速度はタイプの値
            _HP = _maxHP = HP;
            _point = point;
            _money = money;

            _liveCount = Math.floor( (Math.random()*Const.FRAME_RATE) ); //ランダムな位相差あり
            _slowingCount = 0;
            _attackedSlow = 100;
            _venomingCount = 0;
            _venomingLevel = 1;
            _regeneAmount = 0 ;
            _BA = BAbility(); //出産能力のデータセット
            _babyNum = 0;
            _AA = AAbility(); //加速能力のデータセット
            _targetable = true ;

            draw();
        }
        
        private function BAbility():BornAbility {
            if ( _type.born ) { return BornAbility.getBornData( _type.name );
            }else { return null };
        }
        private function AAbility():AccelerateAbility {
            if ( _type.accelerate ) { return AccelerateAbility.getAccelerateData( _type.name );
            }else { return null };
        }
        
        private function draw():void {
            _image = addChild(new Sprite()) as Sprite;
            var bitmap:Bitmap = _image.addChild(new Bitmap(ImageFactory.getImage(_type.name), "auto", true)) as Bitmap;
            bitmap.x = bitmap.y = int( -Const.ENEMY_SIZE / 2);
            
            var HPbarBackground:Sprite = addChild(new Sprite()) as Sprite;
            HPbarBackground.x = -Const.ENEMY_SIZE / 2;
            HPbarBackground.y = -(Const.ENEMY_SIZE / 2 + 2);
            HPbarBackground.graphics.beginFill(0xff0000);
            HPbarBackground.graphics.drawRect(0, 0, Const.ENEMY_SIZE, 1);
            HPbarBackground.graphics.endFill();
            
            _HPbar = HPbarBackground.addChild(new Sprite()) as Sprite;
            _HPbar.graphics.beginFill(0xffff00);
            _HPbar.graphics.drawRect(0, 0, Const.ENEMY_SIZE, 1);
            _HPbar.graphics.endFill();
        }
        
        
        public function update(world:World):void {
            
            _liveCount ++;
            if (_BA != null && _babyNum >= _BA.limit) { _BA = null };

            // スロー状態を更新
            if (_slowingCount > 0) { _slowingCount--; } 
            else { 
                _image.filters = CONDITION_GOOD; 
                _attackedSlow = 100 ; 
            }
            //毒状態を更新(_venomingLevelは毒被弾時にタワーレベルを継承)
            if (_venomingCount > 0) { 
                _venomingCount--;
                var venomDamage : Number = _currentSpeed * (0.5 + (_venomingLevel * 0.5) + (Math.floor(_venomingLevel / 5) * 3));
                damage(venomDamage,1,0,0); 
            } else { 
                _HPbar.filters = CONDITION_GOOD; 
            }
            //regeneration > 0 のときHP回復 
            if ( _type.regeneration > 0 ) {
                _regeneAmount += ((_maxHP / 1000) * _type.regeneration);
                    if (_regeneAmount >= 1) {
                        _HP += int(_regeneAmount)
                        _regeneAmount -= int(_regeneAmount)}
                    if (_HP >= _maxHP) { _HP = _maxHP } ;
                _HPbar.scaleX = _HP / _maxHP;
                }
            //fade > 0 のときフェイド (_liveCountをフェイド間隔でわった偶奇でチェンジ)
            if ( _type.fade > 0 ) {
                if (Math.floor((_liveCount / _type.fade) % 2) == 0) { ;
                    if ( ((_liveCount % _type.fade) / _type.fade) < 0.2 ) { _fadeAlpha = 1 ;
                    } else { _fadeAlpha = 1 - ((_liveCount % _type.fade) / _type.fade)} ;
                    this.alpha = _fadeAlpha ;
                    _targetable = true ;
                }
                if (Math.floor((_liveCount / _type.fade) % 2) == 1) { ;
                    _fadeAlpha = 0 ;
                    this.alpha = _fadeAlpha ;
                    _targetable = false ;
                }
            }    
            
            // 移動する(スロー効果は0~99%の間)
            if (_attackedSlow <= 1) { _attackedSlow = 1 };
            if (_attackedSlow >= 100) { _attackedSlow = 100 };
            x = int(_center.x += (_velocity.x * (_attackedSlow/100)));
            y = int(_center.y += (_velocity.y * (_attackedSlow/100)));

            // ゴールに到着していたら、ライフを減らして消滅
            if (_center.tileX == _goal.tileX && _center.tileY == _goal.tileY) {
                GameData.instance.lives--;
                _HP = 0;
                _world.removeEnemy(this);
                return;
            }
            // 次に進むべきノードに到着していたら、その次に進むべきノードに更新
            if (_center.tileX == _nextNode.tileX && _center.tileY == _nextNode.tileY) {
                _nextNode = _goal.getNext(_center.x, _center.y, _type.flying);
            }
            
            // 速度と向きの更新
            var radian:Number = Math.atan2(_nextNode.centerY - _center.y, _nextNode.centerX - _center.x);
            // 【向き変化】加速能力:Angle >0 の場合、向きを変える
            if (_AA != null && _AA.Angle > 0 ) { 
                radian += (_AA.Angle * Math.PI / 180);
            }
            // 【向き変化】加速能力:sineSlip >0 の場合、向きをぐねぐねさせる
            if (_AA != null && _AA.sineSlip > 0 ) { 
                radian += Math.sin(_liveCount/AA.sineSlip)* 12 *(Math.PI*2)/180 ; //角度の幅は12度内に固定。これ以上だと暴走しやすい
            }
            // 【速度変化】加速能力:時間条件が満たされたら加速
            if (_AA != null && _AA.intervalRun > 0 && (_liveCount % _AA.intervalRun == 0 )) {
                    _currentSpeed = _AA.SpeedChange(_currentSpeed);
            }            
            // 【速度変化】全キャラ共通:移動速度をわずかにふらつかせる(+-は周期変化)
            _currentSpeed += Math.sin(_liveCount)*(Math.random()*0.1) ;
            
            //【速度と向きの計算】
            if (_currentSpeed <= _type.MinSpeed) { _currentSpeed = _type.MinSpeed };
            if (_currentSpeed >= _type.MaxSpeed) { _currentSpeed = _type.MaxSpeed };
            _velocity.x = (_velocity.x + _currentSpeed * Math.cos(radian)) * 0.5;
            _velocity.y = (_velocity.y + _currentSpeed * Math.sin(radian)) * 0.5;
            var degree:Number = radian * 180 / Math.PI;
            _image.rotation = degree;
            
            // 【向き変化】Decoyのみ向きは動きと無関係に回転
            if (_type.name == "Decoy-1") { _image.rotation = (_liveCount * 90 / Math.PI) };
            if (_type.name == "Decoy-2") { _image.rotation = (_liveCount * 90 / Math.PI) * ( -1) };
            if ((_type.name == "Decoy-1" || _type.name == "Decoy-2") && _liveCount > (5 * Const.FRAME_RATE)) { _world.removeEnemy(this) };
            // 時限性の出産があれば出産
            if (_BA != null && _BA.intervalBorn > 0 && (_liveCount % _BA.intervalBorn == 0 )) {
                _babyNum = _BA.EnemyBirth(_babyNum,"interval", this, _center, _maxHP, _point, _money, _world);
                if (_BA.selfRemove ) {
                    _HP = 0;
                    _BA = null;
                    _world.removeEnemy(this);}
            }
        }

        private static const CONDITION_GOOD:Array = [];
        private static const CONDITION_SLOWED:Array = [new GlowFilter(0x0088ff, 1, 4, 4)];
        private static const CONDITION_VENOMED:Array = [new GlowFilter(0x00ff00, 1, 2, 2,255,1,true)];

        // ダメージを受ける処理
        public function damage(amount:Number, level:int, slow:int, venom:int ):void {
            _HP -= amount;
             if (_HP <= 0) { DoomAction() } ;
            _HPbar.scaleX = _HP / _maxHP;
            
            //以下、生きている場合のみ適用
            if (_HP > 0){
                // 能力を持っている場合に、HP割合条件による能力の作動
                if (_BA != null  && _BA.HPrateBorn > 0 && _HP <= (_BA.HPrateBorn * _maxHP)) {
                    _babyNum = _BA.EnemyBirth(_babyNum,"damaged",this, _center, _maxHP, _point, _money, _world);
                    if (_BA.selfRemove ) {
                        _HP = 0;
                        _world.removeEnemy(this);}
                }
                if (_AA != null  && _AA.HPrateRun > 0 && _HP <= (_AA.HPrateRun * _maxHP)) {
                    _currentSpeed = _AA.SpeedChange(_currentSpeed);
                }           
                // 攻撃にスロー効果が付いていて、それに免疫が無かったら、スロー状態になる
                if (( slow > 0 ) && !_type.immunity) { 
                    _attackedSlow = (100 - slow - level*5) ;
                    _slowingCount = Const.SLOWING_DURATION;
                    _image.filters = CONDITION_SLOWED;
                }
                // 攻撃に毒効果が付いていたら、毒状態になる(高レベルの毒効果優先、途中で低レベルの毒攻撃を受けると持続時間リセット)
                if (( venom > 0 ) && !_type.immunity) { 
                    if ( _venomingLevel < level){
                        _venomingLevel = level } ;
                    _venomingCount = venom * Const.VENOMING_DURATION;
                    _HPbar.filters = CONDITION_VENOMED;    
                }
                // 加速能力を持っていて、ダメージ量の加速条件があるとき、ダメージが条件値以上なら加速
                if (_AA != null && _AA.damageRun > 0 && amount >= _AA.damageRun) {
                    var changedSpeed : Number = _AA.SpeedChange(_currentSpeed);
                    _currentSpeed = changedSpeed;
                }
            }
        }

        //-------------------------------------------------
        // 死亡時アクション
        private function DoomAction():void {
                GameData.instance.score += _point;
                // 毒状態で死んだときインフェクション発生
                if (_venomingCount > 0 ) {
                    var Infection:BitmapData = ImageFactory.getImage("Infection");
                    _world.addBullet( new Bullet(_center, 0, 1, 12, 2, true, false, 1, 0, 5, false, false, this, Infection, _world) );
                }
                // 死亡出産のチェック
                if( _BA != null && _BA.deadBorn ){
                    _babyNum = _BA.EnemyBirth(_babyNum,"dead",this, _center, _maxHP, _point, _money, _world);
                    if (_BA.descent) { _money = 0 };
                }
                _world.removeEnemy(this);
                GameData.instance.gold += _money;
                if(_money > 0){_world.addEffect(new Coin(_center.x, _center.y))};
                //return;
            }
     
        public function hasPathToGoal():Boolean {
            return _goal.hasPath(_center.tileX, _center.tileY);
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * EnemyType
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.utils.Dictionary;
    
    //public 
    class EnemyType {
        private static var _types:Dictionary;
        public static function initialize():void { _types = Config.getEnemyType(); }
        public static function getType(typeName:String):EnemyType { return _types[typeName]; }
        
        private var _name:String;        // 種族名称
        private var _speed:Number;        // 移動の速さ
        private var _MinSpeed:Number;        // 移動の最小速度(スロー効果含めない)
        private var _MaxSpeed:Number;        // 移動の最大速度        
        private var _flying:Boolean;    // 飛んでいるかどうか
        private var _immunity:Boolean;    // 免疫(状態異常スローに対する)があるかどうか
        private var _regeneration:int;    // HPの回復量(MaxHPの千分率/フレーム)
        private var _fade:int;    // フェイド能力量(時間間隔)
        private var _born:Boolean;    // 出産能力があるかどうか
        private var _accelerate:Boolean;    // 加速能力があるかどうか
        
        public function get name():String { return _name; }
        public function get speed():Number { return _speed; }
        public function get MinSpeed():Number { return _MinSpeed; }
        public function get MaxSpeed():Number { return _MaxSpeed; }
        public function get flying():Boolean { return _flying; }
        public function get immunity():Boolean { return _immunity; }
        public function get regeneration():int { return _regeneration; }
        public function get fade():int { return _fade; }
        public function get born():Boolean { return _born; }
        public function get accelerate():Boolean { return _accelerate; }
        
        // ※インスタンスは Config.getEnemyType() から生成する
        public function EnemyType(name:String, speed:Number, MinSpeed:Number,MaxSpeed:Number,flying:Boolean, immunity:Boolean, 
                                regeneration:int, fade:int, born:Boolean, accelerate:Boolean) {
            _name = name;
            _speed = speed;
            _MinSpeed = MinSpeed;
            _MaxSpeed = MaxSpeed;
            _flying = flying;
            _immunity = immunity;
            _regeneration = regeneration;
            _fade = fade;
            _born = born;
            _accelerate = accelerate;            
        }
    }
//}
/*----------------------------------------------------------------------------------------------------------------------
 * BornAbility 出産能力管理【F】
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.utils.Dictionary;
    
    //public 
    class BornAbility {
        private static var _parent:Dictionary;
        public static function initialize():void { _parent = Config.getBornAbility(); }
        public static function getBornData (parentName:String):BornAbility { return _parent[parentName]; }
        
        private var _name:String;        //親の名前 
        private var _childrenName:String;        //生まれる子の名前
        private var _childrenHP:Number;      //生まれる子のHP (親に対する割合)
        private var _childrenPoint:Number;   //生まれる子のPoint (親に対する割合)
        private var _amount:int;    //1回の出産で生まれる数
        private var _limit:int;    //出産数の限界量
        private var _intervalBorn:int;    //時間制で生まれるとき、その時間間隔 
        private var _HPrateBorn:Number;    //HPの残量で生まれるとき、その残りHP割合
        private var _deadBorn:Boolean;    //ダメージ量で生まれるとき、生まれる最低ダメージ
        private var _descent:Boolean;    //相続の有無。TRUEのとき自分はお金を出さず、子がお金を出す
        private var _selfRemove:Boolean;    //自己消去の有無。TRUEのとき出産と同時におやは消える
        private var _childrenFull:Boolean;    //子どもが満員のお知らせ。値は計算ごとに更新される
        
        public function get name():String { return _name; }
        public function get childrenName():String { return _childrenName; }
        public function get childrenHP():Number { return _childrenHP; }
        public function get childrenPoint():Number { return _childrenPoint; }
        public function get amount():int { return _amount; }
        public function get limit():int { return _limit; }
        public function get intervalBorn():int { return _intervalBorn; }
        public function get HPrateBorn():Number { return _HPrateBorn; }
        public function get deadBorn():Boolean { return _deadBorn; }
        public function get descent():Boolean { return _descent; }
        public function get selfRemove ():Boolean { return _selfRemove; }
        public function get childrenFull ():Boolean { return _childrenFull; }
        
        public function EnemyBirth(babyNum:int, chance:String, parent:Enemy, center:TileBasedPoint, MaxHP:int, point:int, money:int, world:World):int{
            var _money:int = money;
            if ( !_descent ) { _money = 0 } ; //「相続」がfalseの場合、子どもが持つ報酬は0に
            for ( var i:int = 1; i <= _amount ; i++){
                if (babyNum < limit) {
                var enemyChildren:Enemy = new Enemy(TileBasedPoint.createFromWorldPos(center.x, center.y), EnemyType.getType(_childrenName), int(Math.ceil(MaxHP*_childrenHP)), int(Math.ceil(point*_childrenPoint)), _money, world, true); 
                world.addEnemy(enemyChildren);
                babyNum ++;
                _childrenFull = false;
                }else if (babyNum >= limit) { _childrenFull = true };             
            }
            return babyNum;
        }

        
        // ※インスタンスは Config.getBornAbility() から生成する
        public function BornAbility(name:String, childrenName:String, childrenHP:Number, childrenPoint:Number, amount:int, limit:int, 
                                intervalBorn:int, HPrateBorn:Number, deadBorn:Boolean, descent:Boolean, selfRemove:Boolean) {
            _name = name;
            _childrenName = childrenName;
            _childrenHP = childrenHP;
            _childrenPoint = childrenPoint;
            _amount = amount;
            _limit = limit;
            _intervalBorn = intervalBorn;
            _HPrateBorn = HPrateBorn;
            _deadBorn = deadBorn;
            _descent = descent;
            _selfRemove = selfRemove;
            _childrenFull = false;
        }
    }
//}
/*
/*----------------------------------------------------------------------------------------------------------------------
 * AccelerateAbility 加速能力管理【F】
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.utils.Dictionary;    
    //public 
    class AccelerateAbility {
        private static var _runner:Dictionary;
        public static function initialize():void { _runner = Config.getAccelerateAbility(); }
        public static function getAccelerateData (runnerName:String):AccelerateAbility { return _runner[runnerName]; }
        
        private var _name:String;        //能力者のタイプ名 
        private var _AddPoint:Number;        //速度加算量(マイナスあり)
        private var _RatePoint:Number;      //速度割合変化量
        private var _Angle:Number;            //飛行角度(度数値)
        private var _sineSlip:int;    //ふらふら移動するときの周期量
        private var _intervalRun:int;    //時間制で変化するとき、その時間間隔 
        private var _HPrateRun:Number;    //HPの残量で加速するとき、その残りHP割合        
        private var _damageRun:Number;    //ダメージ量で加速するときの最低ダメージ(割合)
        
        public function get name():String { return _name; }
        public function get AddPoint():Number { return _AddPoint; }
        public function get RatePoint():Number { return _RatePoint; }
        public function get Angle():int { return _Angle; }
        public function get sineSlip():int { return _sineSlip; }
        public function get intervalRun():int { return _intervalRun; }
        public function get HPrateRun():Number { return _HPrateRun; }
        public function get damageRun():Number { return _damageRun; }
        
        //---------------------------
        public function SpeedChange(speed:Number):Number{
            speed = (_RatePoint * speed) + _AddPoint;
            return speed ;
        }

        // ※インスタンスは Config.getAccelerateAbility() から生成する
        public function AccelerateAbility(name:String, AddPoint:Number, RatePoint:Number, Angle:Number, sineSlip:int, 
                                intervalRun:int, HPrateRun:Number, damageRun:Number ) {
            _name = name;
            _AddPoint = AddPoint;
            _RatePoint = RatePoint;
            _Angle = Angle;
            _sineSlip = sineSlip;
            _intervalRun = intervalRun;
            _HPrateRun = HPrateRun;
            _damageRun = damageRun;

        }
    }
//}
/*
/* ----------------------------------------------------------------------------------------------------------------------
 * Coin
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import org.libspark.betweenas3.BetweenAS3;
    import org.libspark.betweenas3.easing.Back;
    import org.libspark.betweenas3.easing.Expo;
    
    //public 
    class Coin extends Sprite {
        public function Coin(posx:int, posy:int) {
            x = posx;
            y = posy;
            
            draw();
            
            BetweenAS3.serial (
                BetweenAS3.tween(this, { $y: -16 }, null, 0.4, Back.easeOut),
                BetweenAS3.tween(this, { alpha: 0 }, null, 0.4, Expo.easeIn),
                BetweenAS3.removeFromParent(this)
            ).play();
        }
        
        private function draw():void {
            var bitmap:Bitmap = new Bitmap(ImageFactory.getImage("Coin"));
            bitmap.smoothing = true;
            bitmap.x = bitmap.y = -4;
            addChild(bitmap);
        }
    }
//}
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * SplashEffect 【F】
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import org.libspark.betweenas3.BetweenAS3;
    import org.libspark.betweenas3.easing.Expo;
    
    //public 
    class splashEffect extends Sprite { 
        //爆発エフェクト (位置x、位置y、スプレッドサイズ、色、時間)        
        public function splashEffect(posx:int, posy:int, size:int, color:uint ,appearTime:int) {
            x = posx;
            y = posy;
            
            drawSplash(color);

            //サイズ値の半径まで拡大、scaleの拡大は右下に伸びるので、同時に基点座標(左上)を動かし、見た目の場所を固定する
            BetweenAS3.serial (
                BetweenAS3.tween(this, { $scaleX: size ,$scaleY: size, alpha: 0 ,$x: -size ,$y: -size  }, null, appearTime, Expo.easeOut),
                BetweenAS3.removeFromParent(this)
            ).play();
        }
        
        private function drawSplash(color:uint):void {
            var sprite:Sprite = new Sprite ;
            sprite.graphics.beginFill(color,0.8);
            sprite.graphics.drawCircle(1,1,1);
            sprite.x = sprite.y=0 ;
            addChild(sprite);
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * Cursor  タワー選択などの動作時にカーソルが変化
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.events.Event;
    
    //public 
    class Cursor extends Sprite {
        private var _world:World;
        private var _border:Sprite;        // 枠線
        private var _baseborder:Sprite;        //選択中の四角い枠追加【F】
        private var _towerImage:Sprite;    // タワーの画像
        private var _towerBody:Bitmap;    // タワー本体の画像
        private var _blockingText:TextField; //ブロッキングの文字表示
        private var _blockingAlart:int
        
        public function Cursor(world:World) {
            _world = world;
            _border = createBorder(0xffff00);
            _baseborder = createBorder(0xff0000);  //選択中の四角い枠追加【F】
            _towerImage = new Sprite();
            _towerImage.addChild(_towerBody = new Bitmap());
            _towerImage.alpha = 0.5;

            _blockingText = ImageFactory.createBorderedText(0, 0, 60, 15, "Blocking!", 12, 0xff0000, 0xffffff);
            _blockingAlart = 0;
            
            mouseChildren = mouseEnabled = false;
            
            GameData.instance.addEventListener(Const.EVENT_CHANGE_SELECTEDTOWER, onUpdateSelectedTower);
        }
        
        // マップ上でタワー選択時に表示する囲み線を生成【F】
        private function createBorder(borderColor:uint):Sprite {
            var sprite:Sprite = new Sprite();
            sprite.graphics.lineStyle(2, borderColor);
            sprite.graphics.drawRect(0, 0, Const.TOWER_SIZE, Const.TOWER_SIZE);
            return sprite;
        }
        
        //ブロッキング警告
        public function blockingAlart():void {
            _blockingAlart = 15;
            _blockingText.x = -10 ;
            _blockingText.y = 2 ;
            _blockingText.alpha = 1;
            addChild(_blockingText);
        }

        
        // 
        public function update(posx:int, posy:int):void {
            var selectedTower:Tower = GameData.instance.selectedTower;
            var position:TileBasedPoint;

            // (selectedTowerがnullでない)かつ(selectedTower.activeがtrue)とき
            if (selectedTower != null && selectedTower.active) {
                position = TileBasedPoint.createFromWorldPos(selectedTower.x, selectedTower.y);
            }else {
                position = TileBasedPoint.createFromWorldPos(posx, posy);
                position.setTilePos(position.tileX, position.tileY);
            }
            
            x = position.x;
            y = position.y;
            
            updateRangeCircle(position.tileX, position.tileY);
 
            updateBlockingAlart();
                
            
        }
        
        private function updateBlockingAlart():void {
            if ( _blockingAlart > 0) {
                _blockingAlart-- ;
                _blockingText.alpha -= 0.04;
                if (_blockingAlart == 0) { removeChild(_blockingText) };
            }
        }
        
        
        // 設置可否で変える色の設定
        private static const POSSIBLE:uint = 0xffffff;
        private static const IMPOSSIBLE:uint = 0xff0000;
        
        private function updateRangeCircle(tilex:int, tiley:int):void {
            graphics.clear();
            
            var selectedTower:Tower = GameData.instance.selectedTower;
            if (selectedTower == null) { return; }
            // 配置できる場所かどうかで、レンジサークルの色を変える【F】
            var color:uint = (selectedTower.active || _world.canBuildTower(tilex, tiley)) ? POSSIBLE : IMPOSSIBLE;
            graphics.lineStyle(0, color, 0.6);
            graphics.beginFill(color, 0.2);
            graphics.drawCircle(int(Const.TOWER_SIZE / 2), int(Const.TOWER_SIZE / 2), selectedTower.type.getStatus(selectedTower.level).range);
            graphics.endFill();
            //配置できない場所ではカーソルが赤い四角になる【F】
            if(_world.canBuildTower(tilex, tiley) || selectedTower.active ) {
                 if (contains(_baseborder)) {removeChild(_baseborder)};
            }else{addChild(_baseborder)}

        }
                
        
        private function onUpdateSelectedTower(e:Event):void {
            var selectedTower:Tower = GameData.instance.selectedTower;

            if (contains(_border)) { removeChild(_border); }
            if (contains(_baseborder)) { removeChild(_baseborder); }
            if (contains(_towerImage)) { removeChild(_towerImage); }
            
            if (selectedTower == null) { return; }
            // タワーが選択中なら囲み線表示
            if (selectedTower.active) {
                addChild(_border);
            }else {
                _towerBody.bitmapData = ImageFactory.getImage(selectedTower.type.name);
                _towerBody.smoothing = true;
                addChild(_towerImage);
            }
            
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * Frontend
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.filters.GlowFilter;
    import flash.geom.ColorTransform;
    import flash.text.TextField;
    import flash.ui.Keyboard;
    
    //public 
    class Frontend extends Sprite {
        private var _wave:TextField;
        private var _score:TextField;
        private var _lives:TextField;
        private var _gold:TextField;

        private var _backSprite:Sprite;        //背景的な使用のスプライト        
        private var _buttons:Sprite;                    // ボタンをまとめる表示オブジェクト
        private var _towerStatus:TowerStatusWindow;        // タワーのステータスを表示するウインドウ

        public function Frontend(posx:int, posy:int) {
            x = posx;
            y = posy;
            
            addChild(createTowerSelectionWindow(365, 0));
            addChild(createGameStatusWindow(0, 0));
                        
            GameData.instance.addEventListener(Const.EVENT_CHANGE_SELECTEDTOWER, onUpdateSelectedTower);
            GameData.instance.addEventListener(Const.EVENT_CHANGE_GAMESTATUS, onUpdateGameStatus);
            
        }
                      
        // タワー選択ボタンを配置するウインドウと、タワーのステータスを表示するウインドウを作成する
        private function createTowerSelectionWindow(posx:int, posy:int):Sprite {
            var towerSelection:Sprite = ImageFactory.createWindow(posx, posy, 100, 417);
            towerSelection.addChild(_backSprite = new Sprite());            
            _backSprite.graphics.beginFill(0x505050);_backSprite.graphics.drawRect(5,30,90,110);
            _backSprite.addChild(ImageFactory.createSimpleText(5,-15, 10, 90, "Tower", 10, 0xffffff));
            _backSprite.graphics.beginFill(0x505050);_backSprite.graphics.drawRect(5,150,90,70);
           
            // タワー選択ボタンを7つ作成して配置する
            towerSelection.addChild(_buttons = new Sprite());            

            var towertypes:Vector.<TowerType> = Config.getTowerType();            
            for (var i:int = 0; i < 7; i++) {
                 //var tower:Tower = _buttons.addChild(new Tower(((i < 4) ? 15 : 53), 32 + 38 * (i % 4), towertypes[i])) as Tower;
                var tower:Tower = _buttons.addChild(new Tower(12 + 26 * (i % 3),5 + Math.ceil((i+1)/ 3)*35, towertypes[i])) as Tower;
                //tower.addChild(ImageFactory.createSimpleText(((i < 4) ? -12 : 32), 0, 12, 32, String(i + 1), 10, 0xffffff));
                tower.scaleX = 0.75; tower.scaleY = 0.75;
                
                HotKey.bind(Keyboard.NUMBER_1 + i, tower.clickTower);
                HotKey.bind(Keyboard.NUMPAD_1 + i, tower.clickTower);
            }
            
            // 選択キャンセルボタンを作成して配置する
            var cancelButton:Sprite = towerSelection.addChild(createCancelButton(12 + 27, 5 + 3*35)) as Sprite;
            //cancelButton.addChild(ImageFactory.createSimpleText(32, 0, 12, 32, "0", 10, 0xffffff));
            cancelButton.scaleX=0.75; cancelButton.scaleY=0.75;
            HotKey.bind(Keyboard.NUMBER_0, isSelectedCancelButton);
            HotKey.bind(Keyboard.NUMPAD_0, isSelectedCancelButton);
            HotKey.bind(Keyboard.ESCAPE, isSelectedCancelButton);
            
            // 選択ウィンドウ内にテータスウィンドウを設置し隠しておく【F】
            towerSelection.addChild(_towerStatus = new TowerStatusWindow(5, 225));
            _towerStatus.visible = false;
            return towerSelection;
        }
         
        // ゲームのステータスを表示するウインドウを作成する
        private function createGameStatusWindow(posx:int, posy:int):Sprite {
            var gameStatus:Sprite = ImageFactory.createWindow(posx, posy, 463, 25);
            gameStatus.addChild(ImageFactory.createBorderedText(14, 0, 40, 25, "Wave :", 12, 0xffffff, 0x808080));
            gameStatus.addChild(_wave = ImageFactory.createScoreText(54, 0, 25, 25, "0", 14, 0xffffff));
            gameStatus.addChild(ImageFactory.createBorderedText(93, 0, 40, 25, "Score :", 12, 0xffffff, 0x808080));
            gameStatus.addChild(_score = ImageFactory.createScoreText(133, 0, 50, 25, "0", 14, 0xffffff));
            gameStatus.addChild(ImageFactory.createBorderedText(197, 0, 40, 25, "Lives :", 12, 0xffffff, 0xf00000));
            gameStatus.addChild(_lives = ImageFactory.createScoreText(237, 0, 20, 25, "0", 14, 0xff0000));
            gameStatus.addChild(ImageFactory.createBorderedText(370, 0, 35, 25, "$ :", 12, 0xffffff, 0xb0b000));
            gameStatus.addChild(_gold = ImageFactory.createScoreText(406, 0, 45, 25, "0", 14, 0xffff00));
            return gameStatus;
        }
        
        // 選択キャンセルボタンを作成する
        private function createCancelButton(posx:int, posy:int):Sprite {
            var cancel:Sprite = new Sprite();
            cancel.x = posx;
            cancel.y = posy;
            cancel.addChild(new Bitmap(ImageFactory.getImage("Cancel")));
            cancel.buttonMode = true;
            cancel.addEventListener(MouseEvent.CLICK, isSelectedCancelButton);
            return cancel;
        }
        private function isSelectedCancelButton(e:MouseEvent = null):void { GameData.instance.selectedTower = null; }
        //カラートランスフォームで「明るい(値のまま)」と「暗くする(値半減)」を定義【F】
        private static const LIGHTEN:ColorTransform = new ColorTransform();
        private static const DARKEN:ColorTransform = new ColorTransform(0.5, 0.5, 0.5);
        
        public function onUpdateGameStatus(e:Event):void {
            var data:GameData = GameData.instance;            
            _wave.text = data.wave.toString();
            _score.text = data.score.toString();
            _lives.text = data.lives.toString();
            _gold.text = data.gold.toString();
            
            // タワーが購入できるかどうかで、タワー選択ボタンに明暗をつける
            for (var i:int = 0; i < _buttons.numChildren; i++) {
                var button:Tower = _buttons.getChildAt(i) as Tower;
                button.transform.colorTransform = ((button.type.getStatus(button.level).cost <= data.gold) ? LIGHTEN: DARKEN);
            }
            
            // アップグレードボタンの有効/無効を反映させる
            if (_towerStatus.visible) { _towerStatus.updateUpgradeButton(); }
        }
        
        private static const NON_GLOW:Array = [];
        private static const GLOW:Array = [new GlowFilter(0xffff00, 1, 8, 8)];
        
        public function onUpdateSelectedTower(e:Event):void {
            var selectedTower:Tower = GameData.instance.selectedTower;
            
            // タワー選択ボタンのハイライトを解除する
            for (var i:int = 0; i < _buttons.numChildren; i++) {
                _buttons.getChildAt(i).filters = NON_GLOW;
            }
            
            if (selectedTower != null) {
                _buttons.removeEventListener(MouseEvent.MOUSE_OVER, onMouseOverButton);
                _buttons.removeEventListener(MouseEvent.MOUSE_OUT, onMouseOutButton);
                
                _towerStatus.update(selectedTower);
                _towerStatus.visible = true;
                // 選択されたボタンにハイライトをつける
                if (!selectedTower.active) { selectedTower.filters = GLOW; }
            }else {
                _buttons.addEventListener(MouseEvent.MOUSE_OVER, onMouseOverButton);
                _buttons.addEventListener(MouseEvent.MOUSE_OUT, onMouseOutButton);
                _towerStatus.visible = false;
            }
        }
        
        // タワー非選択時、選択ボタンにマウスオーバーでステータスを表示するようにする
        private function onMouseOverButton(e:MouseEvent):void {
            _towerStatus.update(Tower(e.target));
            _towerStatus.visible = true;
        }
        private function onMouseOutButton(e:MouseEvent):void {
            _towerStatus.visible = false;
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * TowerStatusWindow タワーステータスウィンドウ
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import com.bit101.components.PushButton;
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import flash.text.TextField;
    import flash.ui.Keyboard;
    
    //public 
    class TowerStatusWindow extends Sprite {
        private var _towerName:TextField;
        //シンボルスプライトを追加【F】
        private var _synbolKinds:Array = ["groundSynbol","airSynbol","slowSynbol","venomSynbol"];
        private var _synbolWalking:Sprite;
        private var _synbolFlying:Sprite;
        private var _synbolSlow:Sprite;
        private var _synbolVenom:Sprite;

        private var _synbolMarks:Array = ["gradeSynbol","damageSynbol","rangeSynbol","reloadSynbol"];
        private var _level:TextField;  private var _levelAdd:TextField;
        private var _cost:TextField;  private var _costAdd:int;
        private var _sell:TextField;
        private var _damage:TextField;  private var _damageAdd:TextField;
        private var _range:TextField;  private var _rangeAdd:TextField;
        private var _firerate:TextField;  private var _firerateAdd:TextField;
                
        private var _upgradeButton:PushButton;
        private var _sellButton:PushButton;
        
        
        private static const LIGHTEN:uint = 0xffffff;
        private static const DARKEN:uint = 0x606060;

        
        public function TowerStatusWindow(posx:int, posy:int):void {
            x = posx;
            y = posy;
            addChild(ImageFactory.createWindow(0, 0, 90, 190));
            addChild(ImageFactory.createWindow(0, 0, 90, 20));
            //ImageFactoryで定義したSimpleテキストで文字を作成【F】
            addChild(_towerName = ImageFactory.createSimpleText(0, 0, 90, 20, "Tower", 12, 0xffffff));
            
            
            //タワー属性のシンボルを配置【F】
            //シンボルつくって設置。表示更新時にタワーの引数にあわせて見えるor見えない【F】
            _synbolWalking = addChild(createSynbol(5,25,0)) as Sprite;
            _synbolFlying = addChild(createSynbol(25,25,1)) as Sprite;
            _synbolSlow = addChild(createSynbol(45,25,2)) as Sprite;
            _synbolVenom = addChild(createSynbol(65,25,3)) as Sprite;

            //ステータスのシンボルとステータス文字を配置【F】            
            //左にシンボル、右に数字を配置。Upgrade情報は別のフィールドで色を変えて配置。【F】
            addChild(createStatusSynbol(5,45,0));  //レベル 
            addChild(_level = ImageFactory.createStatusText(3, 45, 60, 15, "E", 12, 0xffffff));
            addChild(_levelAdd = ImageFactory.createStatusText(32, 40, 60, 15, "", 10, 0x22aa22));            
            addChild(createStatusSynbol(5,70,1));  //攻撃力 (上のアイコンとの高さの差25)
            addChild(_damage = ImageFactory.createStatusText(3, 70, 60, 15, "0", 12, 0xffffff));
            addChild(_damageAdd = ImageFactory.createStatusText(32, 65, 60, 15, "", 10, 0x22aa22));
            addChild(createStatusSynbol(5,95,2));  //範囲
            addChild(_range = ImageFactory.createStatusText(3, 95, 60, 15, "0", 12, 0xffffff));
            addChild(_rangeAdd = ImageFactory.createStatusText(32, 90, 60, 15, "", 10, 0x22aa22));
            addChild(createStatusSynbol(5,120,3));  //装填速度 
            addChild(_firerate = ImageFactory.createStatusText(3, 120, 60, 15, "0", 12, 0xffffff));
            addChild(_firerateAdd = ImageFactory.createStatusText(32, 115, 60, 15, "", 10, 0x22aa22));
            //コスト
            _upgradeButton = new PushButton(this, 5, 145, " ", upgradeSelectedTower);
            addChild(_cost = ImageFactory.createStatusText(5, 146, 80, 15, " ", 10, 0x505050));
            _sellButton = new PushButton(this, 5, 166, "", sellSelectedTower);
            addChild(_sell = ImageFactory.createStatusText(5, 167, 80, 15, " ", 10, 0x505050));
            _upgradeButton.width = _sellButton.width = 80;
            
            // 各ボタンに対応するホットキーを設定する
            HotKey.bind(Keyboard.U, upgradeSelectedTower);
            HotKey.bind(Keyboard.S, sellSelectedTower);
        }
        
        //タワー属性のシンボルマークを設置するファンクション【F】       
        private function createSynbol(posx:int,posy:int,arrayNum:int):Sprite{
            var Synbol:Sprite = new Sprite();
            Synbol.x = posx ; Synbol.y = posy ; 
            Synbol.addChild(new Bitmap(ImageFactory.getImage(_synbolKinds[arrayNum])));
            Synbol.visible = true;
            return Synbol;
        }        
        //ステータスのシンボルマークを設置するファンクション【F】
        private function createStatusSynbol(posx:int,posy:int,arrayNum:int):Sprite{
            var Synbol:Sprite = new Sprite();
            Synbol.x = posx ; Synbol.y = posy ; 
            Synbol.addChild(new Bitmap(ImageFactory.getImage(_synbolMarks[arrayNum])));
            return Synbol;
        }

        private function upgradeSelectedTower(e:MouseEvent = null):void {
            var selectedTower:Tower = GameData.instance.selectedTower;
            if (selectedTower != null && selectedTower.active) {
                selectedTower.upgrade();
            }
        }
        
        private function sellSelectedTower(e:MouseEvent = null):void {
            var selectedTower:Tower = GameData.instance.selectedTower;
            if (selectedTower != null && selectedTower.active) {
                selectedTower.sell();
            }
        }
        
       
        // 引数で与えたタワーのステータス表示に更新する
        public function update(tower:Tower):void {
            var type:TowerType = tower.type;
            
            var status:TowerStatus = type.getStatus(tower.level);
            _level.text = tower.level.toString();
            _cost.text = status.cost.toString();
            _damage.text = status.damage.toString();
            _range.text = status.range.toString();
            _firerate.text = status.firerate.toFixed(1);
            _levelAdd.text = _damageAdd.text = _rangeAdd.text = _firerateAdd.text = _cost.text = _sell.text = "" ;            

            //_towerName.text = type.name + " Tower";
            _towerName.text = type.name + "  ($"+ status.cost.toString()+ ")" ;

            //シンボルの表示visible = タイプ関数の真偽【F】
            _synbolWalking.visible = type.ground;
            _synbolFlying.visible = type.air;
            _synbolSlow.visible = (type.slow > 0);
            _synbolVenom.visible = (type.venom > 0);

            // タワーが選択ボタンのものならボタンを隠して、処理を終える
            if (!tower.active) {
                _upgradeButton.visible = _sellButton.visible = false;
                return;
            }            
            // アップグレード可能か、アップグレード時の上昇値はいくつかを表示に反映させる
            _upgradeButton.visible = _sellButton.visible = true;           
            updateUpgradeButton();
            if (type.hasStatus(tower.level + 1)) {
                var nextStatus:TowerStatus = type.getStatus(tower.level + 1);
                _levelAdd.text = (" → " + nextStatus.level.toString());
                _costAdd = nextStatus.cost - status.cost;
            
                //レベルとコスト表示【F】
                _cost.text = ( "Lv" + nextStatus.level.toString() + " [" + _costAdd.toString() + "]"); 
                if (nextStatus.damage - status.damage > 0) { 
                _damageAdd.text = (" → " + nextStatus.damage.toString()); }
                if (nextStatus.range - status.range > 0) { _rangeAdd.text = (" → " + nextStatus.range.toString()); }
                if (nextStatus.firerate - status.firerate > 0) { _firerateAdd.text = (" → " + nextStatus.firerate.toFixed(1)); }
                else if (nextStatus.firerate - status.firerate < 0) { _firerateAdd.text = (" → " + nextStatus.firerate.toFixed(1)); }
            }
            var _sellValue:int = status.cost * GameData.instance.sellingRatio;
            _sell.text = ( "Sell [" + _sellValue.toString() + "]" );
        }
        
        public function updateUpgradeButton():void {
            var selectedTower:Tower = GameData.instance.selectedTower;
            if (selectedTower == null || !selectedTower.active || !selectedTower.type.hasStatus(selectedTower.level + 1)) {
                _upgradeButton.enabled = false;
                return;
            }
            var upgradeCost:int = selectedTower.type.getStatus(selectedTower.level + 1).cost - selectedTower.type.getStatus(selectedTower.level).cost;
            _upgradeButton.enabled = (GameData.instance.gold >= upgradeCost) ? true : false;
            
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * WaveManager
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.geom.Rectangle;
    
    //public 
    class WaveManager extends Sprite {
        private var _currentWave:int;
        private var _waves:Vector.<Wave>;
        private var _onScreen:BitmapData;
        private var _offScreen:Sprite;
        private var _offScreenPosX:int;
        private var _nextWaveCount:int;
        private var _countDownText:TextField;
        private var _countDown:int;
        
        public function finished():Boolean { return _currentWave == _waves.length; }
        
        public function WaveManager(posx:int, posy:int, world:World) {
            x = posx;
            y = posy;
            
            _waves = Config.getWaves();
            _offScreen = new Sprite();
            for (var i:int = 0; i < _waves.length; i++) {
                var wave:Wave = _waves[i];
                wave.x = i * Const.WAVE_WIDTH;
                wave.setWorld(world);
                _offScreen.addChild(wave);
            }
            createWaveManagementWindow();
            initialize();
        }
        
        public function initialize():void {
            _currentWave = 0;
            _offScreenPosX = 301;
            _offScreen.x = _offScreenPosX / 10;
            updateOnScreen();
            _nextWaveCount = 1;
            
            for (var i:int = 0; i < _waves.length; i++) {
                _waves[i].initialize();
            }
        }
        
        private function updateOnScreen():void {
            _onScreen.fillRect(ONSCREEN_RECT, 0x000000);
            _onScreen.draw(_offScreen, _offScreen.transform.matrix);
        }
        
        private function createWaveManagementWindow():void {
            var window:Sprite = addChild(ImageFactory.createWindow(-10, 0, 475, 50)) as Sprite;
            _onScreen = new BitmapData(365, 30, false, 0x000000);
            var bitmap:Bitmap = window.addChild(new Bitmap(_onScreen)) as Bitmap;
            bitmap.x = bitmap.y = 10;
            
            var line:Sprite = window.addChild(new Sprite()) as Sprite;
            line.graphics.lineStyle(1, 0xffff00);
            line.graphics.moveTo(40, 2);
            line.graphics.lineTo(40, 48);

            _countDown = 0 ;
            addChild(ImageFactory.createSimpleText(19,30, 100, 15, "Send Bonus", 10, 0xffffff));
            addChild(_countDownText = ImageFactory.createStatusTextRight(75, 30, 80, 15, _countDown.toString(), 10, 0xffffff));
        }
        
        private static const ONSCREEN_RECT:Rectangle = new Rectangle(0, 0, 365, 30);
        
        public function update():void {
            _offScreenPosX--;
            if (_offScreenPosX % 10 == 0) { _offScreen.x = _offScreenPosX / 10; }
            updateOnScreen();
            
            _nextWaveCount--;
            _countDown = int(_nextWaveCount / Const.WAVE_INTERVAL * 10) ;
            
            if (_currentWave == _waves.length) { 
                _countDownText.text = "0" ;
            } else { _countDownText.text = "$ "  + _countDown.toString() + " × "  + (int(_currentWave / 5) +1) ; }
            if (_nextWaveCount == 0) {
                sendNextWave();
            }

            
            for (var i:int = 0; i < _waves.length; i++) {
                _waves[i].update();
            }
        }
        
        public function sendNextWave():void {
            // 全てのWaveが送出されていたら何もせずに終了する
            if (_currentWave == _waves.length) { return; }
            
            _currentWave++;
            GameData.instance.wave = _currentWave;
            _waves[_currentWave - 1].send();
            
            // 先送りしていたら、その分をスコアに加算する
            GameData.instance.score += int(_nextWaveCount / 10);
            // 先送りしていたら、センドボーナスのお金を追加する
            _countDown = int(_nextWaveCount / Const.WAVE_INTERVAL * 10) ;
            GameData.instance.gold += _countDown * (int((_currentWave - 1)/5) +1);
            if((_countDown * (int((_currentWave - 1)/5) +1)) > 0 ) {addChild(new Coin(36,40))};
            
            _offScreenPosX -= _nextWaveCount;
            _offScreen.x = _offScreenPosX / 10;
            updateOnScreen();
            _nextWaveCount = Const.WAVE_INTERVAL;
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * Wave ウェイブの処理とバーグラフィックなど
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.Sprite;
    import flash.utils.Dictionary;
    import flash.display.GradientType;
    
    //public 
    class Wave extends Sprite {
        private var _world:World;
        private var _number:int;            // Wave数
        
        private var _enemyType:EnemyType;    // 敵のタイプ
        private var _enemyHP:int;            // 敵のHP
        private var _enemyPoint:int;        // 敵を倒した時のポイント
        private var _enemyMoney:int;        // 敵を倒した時の入手金
        private var _enemyNum:Vector.<int>;    // 出現する敵の数
        
        private var _isActivated:Boolean;        // 送出中かどうか
        private var _allEnemiesSent:Boolean;     // 全ての敵が送出されたかどうか
        private var _spawnInterval:int;            // 敵の出現間隔
        private var _spawnCount:int;            // 出現カウント
        private var _waitingNum:Vector.<int>;    // 待機中の敵の数
        
        
        public function setWorld(value:World):void { _world = value; }
        
        public function Wave(number:int, type:EnemyType, HP:int, point:int, money:int, numSpawning:Vector.<int>) {
            _number = number
            _enemyType = type;
            _enemyHP = HP;
            _enemyPoint = point;
            _enemyMoney = money;
            _enemyNum = numSpawning;
            
            initialize();
            var max:int = 0;
            for (var i:int = 0; i < _enemyNum.length; i++) {
                if (_enemyNum[i] > max) { max = _enemyNum[i]; }
            }
            _spawnInterval = int((Const.WAVE_INTERVAL / 4) / max);
            _spawnCount = 0;
            _waitingNum = new Vector.<int>(_enemyNum.length);
            
            draw();
        }
        
        public function initialize():void {
            _isActivated = false;
            _allEnemiesSent = false;
        }
        // ウェイブバーを描く (出現する敵の種類によって色を設定)
        private function draw():void {
            var bodyColor:uint, borderColor:uint;
            switch(_enemyType.name) { //bodyColor 数字以外の部分 borderColorは数字などの部分
                case "Immune": { bodyColor = 0xccaaee; borderColor = 0x664488; break; }
                case "Fast":   { bodyColor = 0x99aaff; borderColor = 0x6688dd; break; }
                case "Flying": { bodyColor = 0xffdd00; borderColor = 0xddaa00; break; }
                case "Swarm": { bodyColor = 0xaaaa88; borderColor = 0x888866; break; }
                case "Zombie": { bodyColor = 0x55ddff; borderColor = 0x00aacc; break; }
                case "Fade": { bodyColor = 0xcccccc; borderColor = 0x999999; break; }
                case "Split": { bodyColor = 0x55cc88; borderColor = 0x053305; break; }
                case "Fury": { bodyColor = 0xff3333; borderColor = 0xdd0000; break; }
                case "Shell": { bodyColor = 0xaaaa44; borderColor = 0x444422; break; }
                case "Fupa": { bodyColor = 0xffccaa; borderColor = 0xccaa77; break; }
                case "Ghost": { bodyColor = 0xffeeaa; borderColor = 0xbbbbbb; break; }
                case "Detour": { bodyColor = 0xffee22; borderColor = 0xccaa00; break; }
                case "Decoyer": { bodyColor = 0xff99bb; borderColor = 0x773399; break; }
                case "Wall": { bodyColor = 0xccbbcc; borderColor = 0x443344; break; }
                default:       { bodyColor = 0x88aa88; borderColor = 0x669966; break; }
            }


            graphics.lineStyle(1, borderColor);
            graphics.beginGradientFill(GradientType.LINEAR, [0x050505 , bodyColor ] , [100, 35] , [20 ,255]);
            graphics.drawRect(0.5, 0, Const.WAVE_WIDTH - 1, 20);
            graphics.endFill();
            
            addChild(ImageFactory.createStatusText(0, 0, Const.WAVE_WIDTH, 20, _number.toString(), 30, borderColor));
            addChild(ImageFactory.createBorderedText(0, 0, Const.WAVE_WIDTH, 20, _enemyType.name, 10, 0xffffff, borderColor));
            cacheAsBitmap = true;
        }
        
        // 敵の送出を開始する
        public function send():void {
            _isActivated = true;
            _spawnCount = 0;
            for (var i:int = 0; i < _enemyNum.length; i++) {
                _waitingNum[i] = _enemyNum[i];
            }
        }
        
        public function update():void {
            if (!_isActivated || _allEnemiesSent) { return; }
            
            // カウントを進める
            _spawnCount--;
            if (_spawnCount > 0) { return; }
            _spawnCount = _spawnInterval;
            
            // カウントが0になったら、敵を出現させる
            _allEnemiesSent = true;
            for (var i:int = 0; i < _waitingNum.length; i++) {
                if (_waitingNum[i] > 0) {
                    _waitingNum[i]--;
                    _allEnemiesSent = false;
                    
                    var enemy:Enemy = new Enemy(_world.getStartingPos(i), _enemyType, _enemyHP, _enemyPoint, _enemyMoney, _world , false);                    
                    _world.addEnemy(enemy);
                }
            }
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * GameData
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.events.Event;
    import flash.events.EventDispatcher;
    
    //public 
    class GameData extends EventDispatcher {
        private var _wave:int;
        private var _score:int;
        private var _lives:int;
        private var _gold:int;
        private var _selectedTower:Tower;
        private var _sellingRatio:Number;
        
        public function get wave():int { return _wave; }
        public function get score():int { return _score; }
        public function get lives():int { return _lives; }
        public function get gold():int { return _gold; }
        public function get selectedTower():Tower { return _selectedTower; }
        public function get sellingRatio():Number { return _sellingRatio; }
        
        public function set wave(value:int):void { _wave = value; dispatchEvent(new Event(Const.EVENT_CHANGE_GAMESTATUS)); }
        public function set score(value:int):void { _score = value; dispatchEvent(new Event(Const.EVENT_CHANGE_GAMESTATUS)); }
        public function set lives(value:int):void { _lives = Math.max(0, value); dispatchEvent(new Event(Const.EVENT_CHANGE_GAMESTATUS)); }
        public function set gold(value:int):void { _gold = value; dispatchEvent(new Event(Const.EVENT_CHANGE_GAMESTATUS)); }
        public function set selectedTower(value:Tower):void { _selectedTower = value; dispatchEvent(new Event(Const.EVENT_CHANGE_SELECTEDTOWER)); }
        public function set sellingRatio(value:Number):void { _sellingRatio = value; }
        
        //----------------------------------------

        private static var _instance:GameData = null;
        public static function get instance():GameData {
            if (GameData._instance == null) { _instance = new GameData(new SingletonEnforcer()); }
            return _instance;
        }
        public function GameData(enforcer:SingletonEnforcer) { initialize(); }
        
        public function initialize():void {
            _wave = 0;
            _score = 0;
            _lives = Config.INITIAL_LIVES;
            _gold = Config.INITIAL_GOLD;
            _selectedTower = null;
            _sellingRatio = 1;
            
            dispatchEvent(new Event(Const.EVENT_CHANGE_GAMESTATUS));
            dispatchEvent(new Event(Const.EVENT_CHANGE_SELECTEDTOWER));
        }
    }
//}
internal class SingletonEnforcer { }
/* ----------------------------------------------------------------------------------------------------------------------
 * Const
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    //public 
    class Const {
        public static const FRAME_RATE:int = 30;    // フレームレート
        public static const NODE_SIZE:int = 16;        // ノードの大きさ
        public static const NODE_COLS:int = 24;        // ノードの列数
        public static const NODE_ROWS:int = 26;        // ノードの行数
        public static const TOWER_SIZE:int = 32;    // タワーの大きさ
        public static const BULLET_SIZE:int = 8;    // 弾の大きさ
        public static const ENEMY_SIZE:int = 16;    // 敵の大きさ
        
        public static const SLOWING_DURATION:int = 5 * Const.FRAME_RATE;
        public static const VENOMING_DURATION:int = 1 * Const.FRAME_RATE;

        public static const WAVE_INTERVAL:int = 20 * Const.FRAME_RATE;
        public static const WAVE_WIDTH:int = int(WAVE_INTERVAL / 10);
        public static const CURSOR_OFFSET:int = Const.NODE_SIZE / 2;
        
        public static const EVENT_CHANGE_GAMESTATUS:String = "change_gamestatus";
        public static const EVENT_CHANGE_SELECTEDTOWER:String = "change_selectedtower";
        
        //availableFonts["Aqua","Azuki","Cinecaption","Mona","Sazanami","YSHandy","VLGothic","IPAGP","IPAM","UmeUgo","UmePms","Bebas"]
        public static const EMBED_FONT:String = "IPAGP";
        public static const USE_FONTLOADER:Boolean = true;
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * HotKey
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.Stage;
    import flash.events.KeyboardEvent;
    
    //public 
    class HotKey {
        private static var _keymap:Vector.<Function> = new Vector.<Function>(256, true);
        private static var _stage:Stage;
        
        public static function setStage(value:Stage):void { HotKey._stage = value; }
        public static function enable():void { HotKey._stage.addEventListener(KeyboardEvent.KEY_DOWN, HotKey.onKeyDown); _stage.focus = null; }
        public static function disable():void { HotKey._stage.removeEventListener(KeyboardEvent.KEY_DOWN, HotKey.onKeyDown); }
        
        // 押したキーに処理が割り当てられていたら、それを実行する
        private static function onKeyDown(e:KeyboardEvent):void {
            var command:Function = HotKey._keymap[e.keyCode];
            if (command != null) { command(); }    // command.execute
            _stage.focus = null;
        }
        
        // keyCodeに対応するキーに、commandで指定した処理を割り当てる
        public static function bind(keyCode:uint, command:Function):void {
            HotKey._keymap[keyCode] = command;
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * Preloader
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import com.bit101.components.ProgressBar;
    import flash.display.DisplayObjectContainer;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.utils.Dictionary;
    import net.wonderfl.utils.FontLoader;
    
    //public 
    class Preloader extends EventDispatcher {
        private var _assetsNum:int;                // 読み込むアセットの数
        private var _loadedNum:int;                // 読み込み完了したアセットの数
        private var _progressBar:ProgressBar;    // プログレスバー
        
        private var _imageLoaders:Dictionary;    // 画像のローダを保持する連想配列
        private var refImageHolder:Dictionary;    // 画像を保持する連想配列の参照
        
        public function Preloader(parentOfProgressBar:DisplayObjectContainer, imagePaths:Dictionary, imageHolder:Dictionary) {
            _assetsNum = _loadedNum = 0;
            _progressBar = new ProgressBar(parentOfProgressBar, 182, 227);
            
            startLoadingImages(imagePaths, imageHolder);
            if (Const.USE_FONTLOADER) { startLoadingFont(); }
            
            _progressBar.maximum = _assetsNum;
        }
        
        // 外部画像の読み込みを開始する
        private function startLoadingImages(imagePaths:Dictionary, imageHolder:Dictionary):void {
            _imageLoaders = new Dictionary();
            refImageHolder = imageHolder;
            
            for (var imageName:String in imagePaths) {
                _assetsNum++;
                var imageLoader:ExternalImageLoader = new ExternalImageLoader();
                _imageLoaders[imageName] = imageLoader;
                imageLoader.addEventListener(Event.COMPLETE, assetLoaded);
                imageLoader.load(imagePaths[imageName]);
            }
        }
        
        // フォントの読み込みを開始する
        private function startLoadingFont():void {
            _assetsNum++;
            
            var fontLoader:FontLoader = new FontLoader();
            fontLoader.addEventListener(Event.COMPLETE, assetLoaded);
            fontLoader.load(Const.EMBED_FONT);
        }
        
        // 一つのアセットの読み込みが完了した際に呼ばれるメソッド
        private function assetLoaded(e:Event):void {
            e.target.removeEventListener(Event.COMPLETE, assetLoaded);
            
            _loadedNum++;
            _progressBar.value = _loadedNum;
            checkLoadComplete();
        }
        
        // 読み込んだアセット数を調べ、全て読み込んでいたら完了イベントを通知する
        private function checkLoadComplete():void {
            if (_loadedNum == _assetsNum) {
                for (var imageName:String in _imageLoaders) {
                    refImageHolder[imageName] = _imageLoaders[imageName].content;
                }
                
                _progressBar.parent.removeChild(_progressBar);
                dispatchEvent(new Event(Event.COMPLETE));
            }
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * ExternalImageLoader
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.BitmapData;
    import flash.display.Loader;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    
    //public 
    class ExternalImageLoader extends EventDispatcher {
        private var _content:BitmapData;
        private var _tempA:Loader;
        private var _tempB:Loader;
        
        public function get content():BitmapData { return _content; }
        
        public function ExternalImageLoader() {
            _content = null; _tempA = new Loader(); _tempB = new Loader();
        }
        
        public function load(url:String):void {
            _tempA.contentLoaderInfo.addEventListener(Event.INIT, tempALoaded);
            _tempA.load(new URLRequest(url), new LoaderContext(true));
        }
        
        private function tempALoaded(e:Event):void {
            _tempA.contentLoaderInfo.removeEventListener(Event.INIT, tempALoaded);
            _content = new BitmapData(int(_tempA.width), int(_tempA.height), true, 0x00ffffff);
            _tempB.contentLoaderInfo.addEventListener(Event.INIT, tempBLoaded);
            _tempB.loadBytes(_tempA.contentLoaderInfo.bytes);
        }
        
        private function tempBLoaded(e:Event):void {
            _tempB.contentLoaderInfo.removeEventListener(Event.INIT, tempBLoaded);
            _content.draw(_tempB); _tempA.unload(); _tempB.unload();
            dispatchEvent(new Event(Event.COMPLETE));
        }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * TileBasedPoint
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    //public 
    class TileBasedPoint {
        private static const TILE_SIZE:int = Const.NODE_SIZE;
        private static const TILE_COLS:int = Const.NODE_COLS;
        private static const TILE_ROWS:int = Const.NODE_ROWS;
        
        // ワールド座標
        private var _worldX:Number;
        private var _worldY:Number;
        // タイル座標
        private var _tileX:int;
        private var _tileY:int;
        
        private var _isInvalidWorldPos:Boolean;    // ワールド座標値を更新する必要があるかどうか
        private var _isInvalidTilePos:Boolean;    // タイル座標値を更新する必要があるかどうか
        
        // Creation Method でインスタンスを生成する
        public static function createFromWorldPos(x:Number, y:Number):TileBasedPoint { return new TileBasedPoint(true, x, y, 0, 0); }
        public static function createFromTilePos(x:int, y:int):TileBasedPoint { return new TileBasedPoint(false, 0, 0, x, y); }
        public function TileBasedPoint(isWorldPos:Boolean, worldx:Number, worldy:Number, tilex:int, tiley:int) {
            _worldX = worldx;
            _worldY = worldy;
            _tileX = tilex;
            _tileY = tiley;
            _isInvalidWorldPos = !isWorldPos;
            _isInvalidTilePos = isWorldPos;
        }
        
        private function updateWorldPos():void {
            _worldX = Math.max(0, Math.min(_tileX * TILE_SIZE, (TILE_COLS - 1) * TILE_SIZE));
            _worldY = Math.max(0, Math.min(_tileY * TILE_SIZE, (TILE_ROWS - 1) * TILE_SIZE));
        }
        
        private function updateTilePos():void {
            _tileX = Math.max(0, Math.min(int(_worldX / TILE_SIZE), TILE_COLS - 1));
            _tileY = Math.max(0, Math.min(int(_worldY / TILE_SIZE), TILE_ROWS - 1));
        }
        
        // ワールド座標を有効にする
        private function validateWorldPos():void {
            if (_isInvalidWorldPos) {
                updateWorldPos();
                _isInvalidWorldPos = false;
            }
        }
        
        // タイル座標を有効にする
        private function validateTilePos():void {
            if (_isInvalidTilePos) {
                updateTilePos();
                _isInvalidTilePos = false;
            }
        }
        
        public function get x():Number { validateWorldPos(); return _worldX; }
        public function get y():Number { validateWorldPos(); return _worldY; }
        public function get tileX():int { validateTilePos(); return _tileX; }
        public function get tileY():int { validateTilePos(); return _tileY; }
        
        public function set x(value:Number):void { validateWorldPos(); _worldX = value; _isInvalidTilePos = true; }
        public function set y(value:Number):void { validateWorldPos(); _worldY = value; _isInvalidTilePos = true; }
        public function setWorldPos(x:Number, y:Number):void { validateWorldPos(); _worldX = x; _worldY = y; _isInvalidTilePos = true; }
        public function set tileX(value:int):void { validateTilePos(); _tileX = value; _isInvalidWorldPos = true; }
        public function set tileY(value:int):void { validateTilePos(); _tileX = value; _isInvalidWorldPos = true; }
        public function setTilePos(x:int, y:int):void { validateTilePos(); _tileX = x; _tileY = y; _isInvalidWorldPos = true; }
    }
//}
/* ----------------------------------------------------------------------------------------------------------------------
 * ImageFactory
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.display.BitmapData;
    import flash.display.GradientType;
    import flash.display.Sprite;
    import flash.filters.BevelFilter;
    import flash.filters.GlowFilter;
    import flash.geom.Matrix;
    import flash.text.AntiAliasType;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.utils.Dictionary;
    
    import flash.display.Bitmap;
    import flash.filters.ColorMatrixFilter;
    
    //public 
    class ImageFactory {
        private static var _images:Dictionary;    // 画像を保持する連想配列
        
        public static function getImage(imageName:String):BitmapData {
            return ImageFactory._images[imageName];
        }
        
        // 外部画像のパスをまとめた配列を取得する
        public static function getExternalImagePaths():Dictionary {
            var imagePaths:Dictionary = new Dictionary();
            imagePaths["World"] = "http://assets.wonderfl.net/images/related_images/2/2c/2c9f/2c9f8923cc3e44db37520f0cbdcda0965a2e3682";
            //imagePaths["World"] = "http://assets.wonderfl.net/images/related_images/f/f9/f957/f957053513e0cf8aeb4991f6d7c5ca4f708d2230";            
        return imagePaths;
        }


        // (内部で作成できる)画像の読み込みを行う
        public static function load():Dictionary {
            ImageFactory._images = new Dictionary();
            
            //タワーのグラフィック読み込みを追加【F】
            ImageFactory._images["Gun"] = ImageFactory.createGunTower();
            ImageFactory._images["Gatling"] = ImageFactory.createGatlingTower();
            ImageFactory._images["Venom"] = ImageFactory.createVenomTower();
            ImageFactory._images["Cannon"] = ImageFactory.createCannonTower();
            ImageFactory._images["Voltex"] = ImageFactory.createVoltexTower();
            ImageFactory._images["AntiFly"] = ImageFactory.createAntiFlyTower();
            ImageFactory._images["Base"] = ImageFactory.createTowerBase();
            ImageFactory._images["Circle"] = ImageFactory.createBase();
            ImageFactory._images["Cancel"] = ImageFactory.createCancelMark();

            //タワー属性のシンボルイメージ読み込みを追加【F】
            ImageFactory._images["groundSynbol"] = ImageFactory.createWalkingSynbol();
            ImageFactory._images["airSynbol"] = ImageFactory.createFlyingSynbol();
            ImageFactory._images["slowSynbol"] = ImageFactory.createSlowSynbol();
            ImageFactory._images["venomSynbol"] = ImageFactory.createVenomSynbol();
            ImageFactory._images["stealSynbol"] = ImageFactory.createStealSynbol();
            
            //ステータスのシンボルイメージの読み込みを追加【F】
            ImageFactory._images["gradeSynbol"] = ImageFactory.createLevelSynbol();
            ImageFactory._images["damageSynbol"] = ImageFactory.createDamageSynbol();
            ImageFactory._images["rangeSynbol"] = ImageFactory.createRangeSynbol();
            ImageFactory._images["reloadSynbol"] = ImageFactory.createReloadSynbol();


            //敵のイメージの読み込み【F】
            ImageFactory._images["Normal"] = ImageFactory.createNormalEnemy(0x669966, 0x99cc99);
            ImageFactory._images["Fast"] = ImageFactory.createFastEnemy(0x6688dd, 0x99aaff);
            ImageFactory._images["Immune"] = ImageFactory.createImmuneEnemy(0x664488, 0xaa88bb);
            ImageFactory._images["Flying"] = ImageFactory.createFlyingEnemy(0xddaa00, 0xffdd00);
            ImageFactory._images["Swarm"] = ImageFactory.createSwarmEnemy(0x888822, 0xcccc44);
            ImageFactory._images["Zombie"] = ImageFactory.createZombieEnemy(0x00aacc, 0x55ddff);
            ImageFactory._images["Fade"] = ImageFactory.createFadeEnemy(0x999999, 0xeeeeee);
            ImageFactory._images["Split"] = ImageFactory.createSplitEnemy(0x116611, 0x55cc88);
            ImageFactory._images["SplitChild"] = ImageFactory.createSplitChildEnemy(0x116611, 0x55cc88);
            ImageFactory._images["Fury"] = ImageFactory.createFuryEnemy(0xdd0000, 0xff3333);
            ImageFactory._images["Shell"] = ImageFactory.createShellOneEnemy(0x666622, 0x999944);
            ImageFactory._images["Shell-2"] = ImageFactory.createShellTwoEnemy(0x666622, 0x999944);
            ImageFactory._images["Shell-3"] = ImageFactory.createShellThreeEnemy(0x666622, 0x999944);
            ImageFactory._images["Fupa"] = ImageFactory.createFupaEnemy(0xaa9955, 0xffccaa);
            ImageFactory._images["FupaChild"] = ImageFactory.createFlyingEnemy(0xddaa22, 0xffdd22);
            ImageFactory._images["Ghost"] = ImageFactory.createGhostEnemy(0xbbbbbb, 0xffeeaa);
            ImageFactory._images["Detour"] = ImageFactory.createDetourRightEnemy(0xcc8800, 0x444444);
            ImageFactory._images["Detour-L"] = ImageFactory.createDetourLeftEnemy(0xcc8800, 0xffffff);             
            ImageFactory._images["Decoyer"] = ImageFactory.createDecoyerEnemy(0x773399, 0xff99bb);
            ImageFactory._images["Decoy-1"] = ImageFactory.createDecoyEnemy(0x773399, 0xff99bb);
            ImageFactory._images["Decoy-2"] = ImageFactory.createDecoyEnemy(0x773399, 0xff99bb);
            ImageFactory._images["Wall"] = ImageFactory.createWallEnemy(0x443344, 0xccbbcc);
            
            //ImageFactory._images["Bullet_Arrow"] = ImageFactory.createArrowBullet();
            ImageFactory._images["Bullet_Gatling"] = ImageFactory.createNormalBullet(2);
            ImageFactory._images["Bullet_Cannon"] = ImageFactory.createNormalBullet(3);
            //ImageFactory._images["Bullet_Missile"] = ImageFactory.createMissileBullet();
            ImageFactory._images["Bullet_Gun"] = ImageFactory.createNormalBullet(2);
            ImageFactory._images["Bullet_Voltex"] = ImageFactory.createNormalBullet(1);
            ImageFactory._images["Bullet_AntiFly"] = ImageFactory.createArrowBullet();            
            ImageFactory._images["Coin"] = ImageFactory.createCoin();
            
            return ImageFactory._images;
        }
        
        
        
        // タワーを設置する土台の画像を作成する
        private static function createTowerBase():BitmapData {            
            var bitmapData:BitmapData = new BitmapData(32, 32,true,0x00ffffff);
            var _base:Sprite = new Sprite;
            _base.graphics.moveTo(2,1);           
            _base = ImageFactory.drawingArray(_base,0x888888,0,0x888888,[0,0,2,30,32,32,30,2],[3,27,29,29,27,3,1,1]);
            _base.graphics.moveTo(0,27);          
            _base = ImageFactory.drawingArray(_base,0x888888,0,0x101010,[0,2,30,32,32,30,2,0],[29,32,32,29,27,29,29,27]);
            _base.graphics.endFill();
            _base.graphics.lineStyle(1,0xd0d0d0,1);
            bitmapData.draw(_base);
            return bitmapData;
        }
        // タワー描画時の土台
        private static function createBase():BitmapData {            
            var bitmapData:BitmapData = new BitmapData(32, 32,true,0x00ffffff);
            var _base:Sprite = new Sprite;
            _base.graphics.beginFill(0xcccccc);
            _base.graphics.drawCircle(16, 16, 10);
            _base.graphics.endFill();
            bitmapData.draw(_base);
            return bitmapData;
        }

        // 各種タワー描画-------------------------------------------------
        // ベーシックガン Gun
        private static function createGunTower():BitmapData{
            var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            var _towerColor:uint = 0x000000;           
            sprite = towerCircle(_towerColor); 
            sprite.graphics.moveTo(16,14)
            sprite = ImageFactory.drawingArray(sprite,_towerColor,0,_towerColor, [18,18,19,19,22,22,20,10,10,20,22,22,16,16], [14,18,18,14,14,12,10,10,22,22,20,18,18,14]);
            sprite.graphics.beginFill(_towerColor);
            sprite.graphics.drawRect(20,15,10,2);
            bitmapData.draw(sprite);
            return bitmapData;
        }


        // ガトリング Gatling
        private static function createGatlingTower():BitmapData{
            var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            var _towerColor:uint = 0x000000;           
            sprite = towerCircle(_towerColor); 
            sprite.graphics.moveTo(6, 6);
            sprite = ImageFactory.drawingArray (sprite, _towerColor, 0, _towerColor, 
                        [4, 4, 6, 6, 4, 4, 6, 6, 4, 4, 6,14,16,29,29,15,15,17,19,19,17,15,15,29,29,16,14, 6], 
                        [8,11,11,12,14,18,20,21,21,24,26,26,24,24,22,22,21,21,20,12,11,11,10,10, 8, 8, 6, 6]);
            sprite.graphics.beginFill(_towerColor);
            sprite.graphics.drawEllipse(5,8,10,16);
            bitmapData.draw(sprite);
            return bitmapData;
        }

        // ポイズン Venom
        private static function createVenomTower():BitmapData{
            var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            var _towerColor:uint = 0x000000;           
            sprite = towerCircle(_towerColor);
            sprite.graphics.moveTo(15,10)           
            sprite = ImageFactory.drawingArray (sprite,_towerColor,0,_towerColor, [11,13,13,11,15,19,30,30,19,15], [14,14,18,18,22,17,17,15,15,10]);
            sprite.graphics.beginFill(_towerColor);
            sprite.graphics.drawCircle(16,9,4);
            sprite.graphics.drawCircle(16,23,4);
            sprite.graphics.drawCircle(10,13,2);
            sprite.graphics.drawCircle(10,19,2);
            sprite.graphics.drawCircle(21,16,3);
            bitmapData.draw(sprite);
            return bitmapData;
        }

        // キャノン Cannon
        private static function createCannonTower():BitmapData{
            var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            var _towerColor:uint = 0x000000;           
            sprite = towerCircle(_towerColor); 
            sprite.graphics.moveTo(7,6);
            sprite = ImageFactory.drawingArray (sprite, _towerColor, 0, _towerColor, 
                            [6, 6, 8, 6, 6, 8, 6, 6, 7,17,19,19,16,12,30,30,12,12,19,19,17, 7], 
                            [8,10,10,12,20,22,22,24,26,26,24,22,22,20,20,12,12,10,10, 8, 6, 6]);            sprite.graphics.beginFill(_towerColor);
            sprite.graphics.drawCircle(14,16,7);
            bitmapData.draw(sprite);
            return bitmapData;
        }

        // アンチフライ AntiFly
        private static function createAntiFlyTower():BitmapData{
            var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            var _towerColor:uint = 0x000000;           
            sprite = towerCircle(_towerColor); 
            sprite.graphics.moveTo(14,8);           
            sprite = ImageFactory.drawingArray (sprite,_towerColor,0,_towerColor, [10,12,10,14,24,14], [14,16,18,24,16,8]);
            sprite.graphics.lineStyle(1.5,0x000000,1);
            sprite.graphics.endFill();
            sprite.graphics.moveTo(12,8); sprite.graphics.lineTo(9,13);
            sprite.graphics.moveTo(12,24); sprite.graphics.lineTo(9,19);           
            sprite.graphics.moveTo(28,8); 
            sprite.graphics.lineTo(22,2);sprite.graphics.lineTo(14,16);
            sprite.graphics.lineTo(22,30);sprite.graphics.lineTo(28,24);
            bitmapData.draw(sprite);
            return bitmapData;
        }

        // ボルテクス Votex
        private static function createVoltexTower():BitmapData{
            var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x00ffffff);
            var sprite:Sprite = new Sprite(); 
            var _towerColor:uint = 0x000000;           
            sprite = towerCircle(_towerColor);          
            sprite.graphics.lineStyle(1,0x000000, 1, true);
            sprite.graphics.moveTo(12,7); sprite.graphics.lineTo(6,16); sprite.graphics.lineTo(12,25);
            sprite.graphics.lineTo(20,25); sprite.graphics.lineTo(26,16); sprite.graphics.lineTo(20,7);
            sprite.graphics.lineTo(12,7);
            sprite.graphics.lineStyle(0,0x000000, 0, true);
            sprite.graphics.beginFill(0x000000);
            sprite.graphics.drawCircle(16,16,4);
            sprite.graphics.endFill();
            sprite.graphics.beginFill(0x000000);
            sprite.graphics.moveTo(8,8);
            sprite.graphics.lineTo(12,12);sprite.graphics.lineTo(14,10);sprite.graphics.lineTo(11,4);sprite.graphics.lineTo(8,8);                      
            sprite.graphics.moveTo(4,13);
            sprite.graphics.lineTo(4,19);sprite.graphics.lineTo(10,18);sprite.graphics.lineTo(10,14);sprite.graphics.lineTo(4,13);
            sprite.graphics.moveTo(8,24);
            sprite.graphics.lineTo(11,28);sprite.graphics.lineTo(14,22);sprite.graphics.lineTo(12,20);sprite.graphics.lineTo(8,24);
            sprite.graphics.moveTo(21,28);
            sprite.graphics.lineTo(24,24);sprite.graphics.lineTo(20,20);sprite.graphics.lineTo(18,22);sprite.graphics.lineTo(21,28);
            sprite.graphics.moveTo(28,19);
            sprite.graphics.lineTo(28,13);sprite.graphics.lineTo(22,14);sprite.graphics.lineTo(22,18);sprite.graphics.lineTo(28,19);
            sprite.graphics.moveTo(24,8);
            sprite.graphics.lineTo(21,4);sprite.graphics.lineTo(18,10);sprite.graphics.lineTo(20,12);sprite.graphics.lineTo(24,8);
            sprite.graphics.endFill();
            bitmapData.draw(sprite);
            return bitmapData;
        }
        //-----------------------------------------------------
        //-----------------------------------------------------
        
                
        // キャンセルマークの画像を作成する
        private static function createCancelMark():BitmapData {
            var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.lineStyle(4, 0xff0000);
            sprite.graphics.drawCircle(16, 16, 12);
            sprite.graphics.moveTo(16 + (12 * Math.cos(9 * Math.PI / 8)), 16 + (12 * Math.sin(9 * Math.PI / 8)));
            sprite.graphics.lineTo(16 + (12 * Math.cos(Math.PI / 8)), 16 + (12 * Math.sin(Math.PI / 8)));
            bitmapData.draw(sprite);
            return bitmapData;
        }

        // ステータスウィンドウ用の画像を作成する【F】
        // 靴アイコン:地上の敵を攻撃【F】
        private static function createWalkingSynbol():BitmapData{
            var bitmapData:BitmapData = new BitmapData(12, 12, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.lineStyle(0, 0x000000, 0, true);
            sprite.graphics.beginFill(0xb0b0b0)
            sprite.graphics.moveTo(6,2);
            sprite.graphics.lineTo(12,2);
            sprite.graphics.lineTo(12,11);
            sprite.graphics.lineTo(3,11);
            sprite.graphics.curveTo(0,7,6,6);
            sprite.graphics.lineTo(6,2);
            bitmapData.draw(sprite);
            return bitmapData;
        }
       // 羽アイコン:空中の敵を攻撃【F】
        private static function createFlyingSynbol():BitmapData{
            var bitmapData:BitmapData = new BitmapData(12, 12, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.lineStyle(0, 0x000000, 0, true);
            sprite.graphics.beginFill(0xb0b0b0)
            sprite.graphics.moveTo(8,2);
            sprite.graphics.lineTo(11,2);
            sprite.graphics.curveTo(15,2.5,8,5);
            sprite.graphics.curveTo(12,5.5,6,7);
            sprite.graphics.curveTo(10,8,4,9);
            sprite.graphics.curveTo(3,9.8,3,12);
            sprite.graphics.lineTo(2,11);
            sprite.graphics.curveTo(2,2.5,8,2);
            bitmapData.draw(sprite);
            return bitmapData;
        }        
       // スロウアイコン:減速効果【F】
        private static function createSlowSynbol():BitmapData{
            var bitmapData:BitmapData = new BitmapData(12, 12, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.lineStyle(1.4, 0xffffff, 1, true);
            sprite.graphics.endFill();
            sprite.graphics.moveTo(4,1) ; 
            sprite.graphics.lineTo(2,3) ; sprite.graphics.lineTo(4,5) ; sprite.graphics.lineTo(2,7) ; sprite.graphics.lineTo(4,9) ; sprite.graphics.lineTo(2,11) ;
            sprite.graphics.moveTo(7,1) ; 
            sprite.graphics.lineTo(5,3) ; sprite.graphics.lineTo(7,5) ; sprite.graphics.lineTo(5,7) ; sprite.graphics.lineTo(7,9) ; sprite.graphics.lineTo(5,11) ;
            sprite.graphics.moveTo(10,1) ; 
            sprite.graphics.lineTo(8,3) ; sprite.graphics.lineTo(10,5) ; sprite.graphics.lineTo(8,7) ; sprite.graphics.lineTo(10,9) ; sprite.graphics.lineTo(8,11) ;
            bitmapData.draw(sprite);
            return bitmapData;
        }
       // ベノムアイコン:毒液効果【F】
        private static function createVenomSynbol():BitmapData{
            var bitmapData:BitmapData = new BitmapData(12,12, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.lineStyle(0, 0x000000, 0, true);
            sprite.graphics.beginFill(0xb0b0b0);
            sprite.graphics.moveTo(9,9);           
            sprite = drawingArray( sprite, 0xb0b0b0, 0, 0xb0b0b0, [7,7,5,5,3], [6,0,0,6,9]);
            sprite.graphics.curveTo(0,12,5,12); sprite.graphics.lineTo(7,12); sprite.graphics.curveTo(12,12,9,9);
            bitmapData.draw(sprite);
            return bitmapData;
        }
       // スティールアイコン:窃盗効果【F】
        private static function createStealSynbol():BitmapData{
            var bitmapData:BitmapData = new BitmapData(12, 12, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.lineStyle(0, 0x000000, 0, true);
            sprite.graphics.beginFill(0xb0b0b0);
            sprite.graphics.drawEllipse( 3, 1, 6, 10);
            sprite.graphics.endFill();
            sprite.graphics.lineStyle(1, 0x000000, 1, true);
            sprite.graphics.drawEllipse(4.5, 3, 3, 6);
            bitmapData.draw(sprite);
            return bitmapData;
        }


       //レベルアイコン:タワーレベル【F】
        private static function createLevelSynbol():BitmapData{
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.lineStyle(0, 0x000000, 0, true);
            sprite.graphics.beginFill(0xffffff);
            sprite.graphics.moveTo(4, 4); sprite.graphics.lineTo(6, 4); sprite.graphics.lineTo(6, 10); sprite.graphics.lineTo(8, 10);
            sprite.graphics.lineTo(8, 12); sprite.graphics.lineTo(4, 12); sprite.graphics.lineTo(4, 4);
            sprite.graphics.moveTo(8, 6); sprite.graphics.lineTo(9, 6); sprite.graphics.lineTo(10, 10); sprite.graphics.lineTo(11, 6);
            sprite.graphics.lineTo(12, 6); sprite.graphics.lineTo(11, 12); sprite.graphics.lineTo(9, 12); sprite.graphics.lineTo(8, 6);
            bitmapData.draw(sprite);
            return bitmapData;
        }

       //剣アイコン:攻撃力【F】
        private static function createDamageSynbol():BitmapData{
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.lineStyle(0, 0x000000, 0, true);
            sprite.graphics.beginFill(0xffffff);
            sprite.graphics.moveTo(4, 11); sprite.graphics.lineTo(10, 4); sprite.graphics.lineTo(12, 4); sprite.graphics.lineTo(12, 6); sprite.graphics.lineTo(5, 12); 
            sprite.graphics.endFill();sprite.graphics.beginFill(0xffffff);
            sprite.graphics.moveTo(4, 7); sprite.graphics.lineTo(5, 6); sprite.graphics.lineTo(10, 11); sprite.graphics.lineTo(9, 12); sprite.graphics.lineTo(4, 7);
            bitmapData.draw(sprite);
            return bitmapData;
        }
       //波紋アイコン:攻撃範囲【F】
        private static function createRangeSynbol():BitmapData{
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.lineStyle(2,0xffffff);
            sprite.graphics.drawCircle(8,8,4.6);sprite.graphics.drawCircle(8,8,1.8);
            bitmapData.draw(sprite);
            return bitmapData;
        }
       //連射アイコン:装填速度【F】
        private static function createReloadSynbol():BitmapData{
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.lineStyle(2,0xffffff);
            sprite.graphics.moveTo(4,6); sprite.graphics.lineTo(6,8);sprite.graphics.lineTo(4,10);
            sprite.graphics.moveTo(7,5); sprite.graphics.lineTo(9,8); sprite.graphics.lineTo(7,11);
            sprite.graphics.moveTo(10,4); sprite.graphics.lineTo(12,8); sprite.graphics.lineTo(10,12);
            bitmapData.draw(sprite);
            return bitmapData;
        }

       
        //-----------------------------------------------------       
        // 敵の画像作成【F】
        //-----------------------------------------------------
        //Nomal タイプ
        private static function createNormalEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite; 
            sprite.graphics.moveTo(0,8);
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_inColor ,1 ,
                            [3.5,7,14] , [8,4,4] , [5.5,9.5,14] , [6,4,8] );
            sprite.graphics.moveTo(0,8); 
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_inColor ,1 ,
                            [3.5,7,14] , [8,4,4] , [5.5,9.5,14] , [6,4,8] );
            sprite.graphics.moveTo(15.5,8);
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [15.5,7,3 ,3.5 ,7,14] , [2.5,2.5,8,8,4 ,4 ] , [9.5,5,0 ,5.5,9.5,14] , [2.5 ,5,8,6,4 ,8]);
            sprite.graphics.moveTo(15.5,8);
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [15.5,7,3 ,3.5 ,7,14] , [2.5,2.5,8,8,4 ,4 ] , [9.5,5,0 ,5.5,9.5,14] , [2.5 ,5,8,6,4 ,8]);
            sprite.graphics.drawCircle(10,8,3); 
            bitmapData.draw(sprite);
            return bitmapData;
        }
        // Fastタイプ
        private static function createFastEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.moveTo(5,8);
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_inColor ,1 ,
                            [8.5,11] , [6,6] , [9.5,11] , [6,8]);
            sprite.graphics.moveTo(5,8);
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_inColor ,1 ,
                            [8.5,11] , [6,6] , [9.5,11] , [6,8]);
            sprite.graphics.moveTo(12,8);
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [12,5.5,  ,8.5,11] , [4.5 ,4.5 ,  ,6 ,6 ] , [8.5 ,0 ,5 ,9.5,11] , [4.5 ,8 ,8 ,6 ,8 ]);
            sprite.graphics.moveTo(12,8);
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [12,5.5,  ,8.5,11] , [4.5 ,4.5 ,  ,6 ,6 ] , [8.5 ,0 ,5 ,9.5,11] , [4.5 ,8 ,8 ,6 ,8 ]);
            sprite.graphics.moveTo(15 ,8 );
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [15,9,13] , [3.5 ,3 ,3.5 ] , [10 ,8 ,13.5 ] , [3 ,3.5 ,8]);
            sprite.graphics.moveTo(15 ,8 );
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [15,9,13] , [3.5 ,3 ,3.5 ] , [10 ,8 ,13.5 ] , [3 ,3.5 ,8]);
            bitmapData.draw(sprite);
            return bitmapData;
        }
        // Immuneタイプの敵の画像を作成する【F】
        private static function createImmuneEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.moveTo(4, 8);
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_inColor ,1 ,
                            [4 ,10.5] , [5.5, 4 ] , [5, 12] , [4 ,8 ]);
            sprite.graphics.moveTo(4, 8);
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_inColor ,1 ,
                            [4 ,10.5] , [5.5, 4 ] , [5, 12] , [4 ,8 ]);
            sprite.graphics.moveTo(15,8);
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [12 ,1.5 ,  ,4 ,10.5] , [0 ,2 ,  ,5.5 ,4 ] , [4 ,1 ,4 ,5 ,12 ] , [1.5 ,8 ,8 ,4 ,8 ]);
            sprite.graphics.moveTo(15,8);
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [12 ,1.5 ,  ,4 ,10.5] , [0 ,2 ,  ,5.5 ,4 ] , [4 ,1 ,4 ,5 ,12 ] , [1.5 ,8 ,8 ,4 ,8 ]);
            sprite.graphics.moveTo(11,8);
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [10 ,5.5 ] , [6 ,7 ] , [6 ,5.5] , [5 ,8 ]);
            sprite.graphics.moveTo(11,8);
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [10 ,5.5 ] , [6 ,7 ] , [6 ,5.5] , [5 ,8 ]);
            bitmapData.draw(sprite);
            return bitmapData;
        }
        // Flying タイプの敵の画像を作成する
        private static function createFlyingEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.moveTo(12 ,6 );
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [11 ,  ,10 ] , [2 ,  ,3 ] , [6 ,6.5 ,12 ] , [0.5 ,4.5 ,6 ]);
            sprite.graphics.moveTo(12,10);
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [11 ,  ,10 ] , [2 ,  ,3 ] , [6 ,6.5 ,12 ] , [0.5 ,11.5,6]);
            sprite.graphics.drawCircle(8.5 ,8 ,3.5)
            sprite.graphics.beginFill(_inColor); sprite.graphics.drawCircle(9 ,8 ,3)
            sprite.graphics.beginFill(_outColor); sprite.graphics.drawCircle(9.5 ,8 ,2)
            bitmapData.draw(sprite);
            return bitmapData;
        }
        // Swarm タイプの敵の画像を作成する
        private static function createSwarmEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.moveTo(0,8);           
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [4 ,7 ,12 ] , [8 ,5 ,5 ] , [6 ,9.5 ,14 ] , [7 ,5 ,8 ]);
            sprite.graphics.moveTo(0,8);
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [4 ,7 ,12 ] , [8 ,5 ,5 ] , [6 ,9.5 ,14 ] , [7 ,5 ,8 ]);                       
            sprite.graphics.beginFill(_inColor); sprite.graphics.drawCircle(11 ,8 ,2 ); sprite.graphics.drawCircle(8 ,8 ,1 );
            bitmapData.draw(sprite);
            return bitmapData;
        }

        // Zombieタイプの敵の画像を作成する            
        private static function createZombieEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.moveTo(5,2);           
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [5,  ,8] , [5,  ,5] , [5,15,2] , [8,8 ,5]); 
            sprite.graphics.moveTo(5,14);
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [5,  ,8] ,[5,  ,5] , [5,15,2] ,[8,8 ,5]); 
            sprite.graphics.moveTo(2,2);           
            sprite = drawingArray(sprite ,0x000000 ,0 ,_outColor ,
                            [8,14,10,14,8 ,2 ,6] , [6,2 , 8,14,10,14,8] );
            sprite.graphics.endFill() ;
            sprite.graphics.beginFill(_outColor);
            sprite.graphics.drawCircle(8,8,3.5);
            sprite.graphics.endFill();
            sprite.graphics.beginFill(_inColor);
            sprite.graphics.drawCircle(8,8,2);
            sprite.graphics.drawCircle(2,2,2);
            sprite.graphics.drawCircle(2,14,2);
            bitmapData.draw(sprite);
            return bitmapData;
        }

        // Fadeタイプの敵の画像を作成する            
        private static function createFadeEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
                        sprite.graphics.beginFill(_inColor);
            sprite.graphics.drawCircle(4,8,2.5);                                      
            sprite.graphics.drawCircle(12,4,2.5);
            sprite.graphics.drawCircle(12,12,2.5);
            sprite.graphics.moveTo(2,8);
            sprite = drawingCurveArray(sprite ,_outColor ,1 ,_outColor ,0 ,
                            [2,7,10 ,15,13] , [5,5,1 ,4 ,7 ] , 
                            [5,9,13,14,13] , [5,3,2 ,6 ,8 ]); 
            sprite.graphics.moveTo(2,8);
            sprite = drawingCurveArrayMILLOR(sprite ,_outColor ,1 ,_outColor ,0 ,
                            [2,7,10,15,13] , [5,5,1 ,4 ,7 ] , 
                            [5,9,13,14,13] , [5,3,2 ,6 ,8 ]); 
            sprite.graphics.endFill();
            sprite.graphics.moveTo(7,5); sprite.graphics.lineTo(13,14);
            sprite.graphics.moveTo(7,11); sprite.graphics.lineTo(13,2);
            bitmapData.draw(sprite);
            return bitmapData;
        }

        // Splitタイプの敵の画像を作成する            
        private static function createSplitEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.beginFill(_outColor);
            sprite.graphics.drawCircle(9,8,6);sprite.graphics.endFill();
            sprite.graphics.beginFill(_outColor);            
            sprite.graphics.drawCircle(5,4,3.5); sprite.graphics.drawCircle(11,5,3);
            sprite.graphics.drawCircle(5,12,3.5); sprite.graphics.drawCircle(11,11,3);
            sprite.graphics.endFill();
            sprite.graphics.moveTo(6,4);
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [4,4] , [7,9] , [0,6] , [8,12] ); 
            sprite.graphics.beginFill(_inColor);
            sprite.graphics.drawCircle(8,8,2);
            sprite.graphics.drawCircle(5,4,2.5); sprite.graphics.drawCircle(11,5,2);
            sprite.graphics.drawCircle(5,12,2.5); sprite.graphics.drawCircle(11,11,2);
            bitmapData.draw(sprite);
            return bitmapData;
        }
        // SplitChildタイプの敵の画像を作成する
        private static function createSplitChildEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.beginFill(_outColor);
            sprite.graphics.drawCircle(9,8,3.5);sprite.graphics.endFill();
            sprite.graphics.moveTo(8,6);
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 , [4,4] , [7,9] , [0,8] , [8,10] ); 
            sprite.graphics.beginFill(_inColor);
            sprite.graphics.drawCircle(9,8,2);
            bitmapData.draw(sprite);
            return bitmapData;
        }
        // Furyタイプの敵の画像を作成する
        private static function createFuryEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.moveTo(14,8);
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 , [13,5 ] , [6 ,6 ] , [9 ,0 ] ,  [6 ,8 ] ); 
            sprite.graphics.endFill();            
            sprite.graphics.moveTo(15,7);            
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 , [15,11 ,10 ,14] , [3 ,0.5,2.5,5 ] ,  [13,4  ,12 ,15] , [2 ,2  ,4  ,7 ] ); 
            sprite.graphics.endFill();
            sprite.graphics.moveTo(12,5.5);
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 , [10 ,5.5,8  ] ,  [3.5,3  ,4] ,  [8  ,2  ,12 ] ,  [3.5,6  ,5.5 ] ); 
            sprite.graphics.endFill();            
            sprite.graphics.moveTo(14,8);
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 , [13,5 ] , [6 ,6 ] , [9 ,0 ] ,  [6 ,8 ] ); 
            sprite.graphics.endFill();            
            sprite.graphics.moveTo(15,9);            
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 , [15,11 ,10 ,14] , [3 ,0.5,2.5,5 ] ,  [13,4  ,12 ,15] , [2 ,2  ,4  ,7 ] ); 
            sprite.graphics.endFill();
            sprite.graphics.moveTo(12,10.5);
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 , [10 ,5.5,8  ] ,  [3.5,3  ,4] ,  [8  ,2  ,12 ] ,  [3.5,6  ,5.5 ] ); 
            sprite.graphics.endFill();
            sprite.graphics.beginFill(_inColor);
            sprite.graphics.drawEllipse(7,7,5,2);
            bitmapData.draw(sprite);
            return bitmapData;
        }
        
        // Shellタイプの敵01-03の画像を作成する
        private static function createShellOneEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.beginFill(_inColor);
            sprite.graphics.drawCircle(8,8,4);
            sprite.graphics.endFill();
            sprite.graphics.moveTo(15,8);
            sprite = drawingArray(sprite ,0x000000 ,0 ,_outColor ,
                            [13,11,10,12,10,11,13,15] , 
                            [4 ,2 ,2 ,8 ,14,14,12,8 ] ); 
            sprite.graphics.moveTo(11,8);
            sprite = drawingArray(sprite ,0x000000 ,0 ,_outColor ,
                            [9 ,7 ,6 ,8 ,6 ,7 ,9 ,11] , 
                            [5 ,3 ,3 ,8 ,13,13,11,8 ] ); 
            sprite.graphics.moveTo(7,8);
            sprite = drawingArray(sprite ,0x000000 ,0 ,_outColor ,
                            [5 ,3 ,2 ,4 ,2 ,3 ,5 ,7 ] , 
                            [6 ,4 ,4 ,8 ,12,12,10,8 ] ); 
            sprite.graphics.endFill();
            bitmapData.draw(sprite);
            return bitmapData;
        }            
        private static function createShellTwoEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.beginFill(_inColor);
            sprite.graphics.drawCircle(7,8,3.5);
            sprite.graphics.endFill();
            sprite.graphics.moveTo(11,8);
            sprite = drawingArray(sprite ,0x000000 ,0 ,_outColor ,
                            [9 ,7 ,6 ,8 ,6 ,7 ,9 ,11] , 
                            [5 ,3 ,3 ,8 ,13,13,11,8 ] ); 
            sprite.graphics.moveTo(7,8);
            sprite = drawingArray(sprite ,0x000000 ,0 ,_outColor ,
                            [5 ,3 ,2 ,4 ,2 ,3 ,5 ,7 ] , 
                            [6 ,4 ,4 ,8 ,12,12,10,8 ] ); 
            sprite.graphics.endFill();
            bitmapData.draw(sprite);
            return bitmapData;
        }            
        private static function createShellThreeEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.beginFill(_inColor);
            sprite.graphics.drawCircle(5,8,3);
            sprite.graphics.endFill();
            sprite.graphics.moveTo(7,8);
            sprite = drawingArray(sprite ,0x000000 ,0 ,_outColor ,
                            [5 ,3 ,2 ,4 ,2 ,3 ,5 ,7 ] , 
                            [6 ,4 ,4 ,8 ,12,12,10,8 ] ); 
            sprite.graphics.endFill();
            bitmapData.draw(sprite);
            return bitmapData;
        }                
        
        // Fupaタイプの敵の画像を作成する
        private static function createFupaEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.moveTo(6,4);
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
                            [1,1 ,8 ,15,15,8] , [4,12,12,12,4 ,4] , [1,6 ,10,15,10,6] , [8,12,12,8 ,4 ,4] ); 
            sprite.graphics.endFill();
            sprite.graphics.beginFill(_inColor);
            sprite.graphics.drawCircle(11,8,2);
            sprite.graphics.moveTo(11,5);
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_inColor ,1 ,
                            [10,6  ,6  ,8 ] , [5 ,5.5,7.5,6 ] , [8 ,5  ,8  ,11] , [5 ,7.5,7.5,5 ] ); 
            sprite.graphics.moveTo(11,11);
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_inColor ,1 ,
                            [10,6  ,6  ,8 ] , [5 ,5.5,7.5,6 ] ,  [8 ,5  ,8  ,11] , [5 ,7.5,7.5,5 ] ); 
            sprite.graphics.endFill();
            bitmapData.draw(sprite);
            return bitmapData;
        }                
        
        // Ghostタイプの敵の画像を作成する
        private static function createGhostEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.beginFill(_inColor);
            sprite.graphics.drawCircle(11,8,4);
            sprite.graphics.endFill();
            sprite.graphics.lineStyle(1,_outColor,1);
            sprite.graphics.drawCircle(10,8,5);
            sprite.graphics.moveTo(13,8);
            sprite = drawingCurveArray(sprite ,_outColor ,1 ,_outColor ,0 ,
                            [13,8,3,3] , 
                            [6 ,3,4,7] ,  
                            [11,1,4,1] , 
                            [5 ,2,6,8] ); 
            sprite.graphics.moveTo(13,8);
            sprite = drawingCurveArrayMILLOR(sprite ,_outColor ,1 ,_outColor ,0 ,
                            [13,8,3,3] , 
                            [6 ,3,4,7] ,  
                            [11,1,4,1] , 
                            [5 ,2,6,8] ); 
            sprite.graphics.endFill();
            bitmapData.draw(sprite);
            return bitmapData;
        }                
        
        // Left-Rightタイプの敵の画像を作成する
        private static function createDetourRightEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.moveTo(15,10);
            sprite = drawingCurveArray(sprite ,_outColor ,0 ,_outColor ,1 ,
                            [15,11,8,4 ,5 ,10,15] , 
                            [7 ,3 ,4,7 ,10,14,12] ,  
                            [13,6 ,9,0 ,7 ,13,15] , 
                            [5 ,2 ,6,11,12,13,10] ); 
            sprite.graphics.moveTo(14,13);
            sprite = drawingCurveArray(sprite ,_outColor ,0 ,_outColor ,1 ,
                            [13,12,13] , 
                            [16,15,14] ,  
                            [10,11,14] , 
                            [16,14,13] ); 
            sprite.graphics.endFill();
            sprite.graphics.beginFill(_inColor);
            sprite.graphics.drawCircle(11.5, 10, 2.5);
            bitmapData.draw(sprite);
            return bitmapData;
        }
        private static function createDetourLeftEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.moveTo(15,6);
            sprite = drawingCurveArray(sprite ,_outColor ,0 ,_outColor ,1 ,
                            [15,11,8 ,4 ,5 ,10,15] , 
                            [9 ,13,12,9 ,6 ,2 ,4 ] ,  
                            [13,6 ,9 ,0 ,7 ,13,15] , 
                            [11,14,10,5 ,4 ,3 ,6 ] ); 
            sprite.graphics.moveTo(14,3);
            sprite = drawingCurveArray(sprite ,_outColor ,0 ,_outColor ,1 ,
                            [13,12,13] , 
                            [0 ,1 ,2 ] ,  
                            [10,11,14] , 
                            [0 ,2 ,3 ] ); 
            sprite.graphics.endFill();
            sprite.graphics.beginFill(_inColor);
            sprite.graphics.drawCircle(11.5,6,2.5);
            bitmapData.draw(sprite);
            return bitmapData;
        }
        // Decoyerタイプの敵の画像を作成する
        private static function createDecoyerEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.moveTo(15,8);
            sprite = drawingCurveArray(sprite ,_outColor ,0 ,_outColor ,1 ,
                            [15,11,11] ,[6 ,4 ,6 ] ,[8 ,5 ,11] ,[1 ,5 ,8 ] ); 
            sprite.graphics.moveTo(10,8);
            sprite = drawingCurveArray(sprite ,_outColor ,0 ,_outColor ,1 ,
                            [10,5] ,[7 ,8] ,[8 ,0] ,[6 ,8] );
            sprite.graphics.moveTo(15,8);
            sprite = drawingCurveArrayMILLOR(sprite ,_outColor ,0 ,_outColor ,1 ,
                            [15,11,11] ,[6 ,4 ,6 ] ,[8 ,5 ,11] ,[1 ,5 ,8 ] ); 
            sprite.graphics.moveTo(10,8);
            sprite = drawingCurveArrayMILLOR(sprite ,_outColor ,0 ,_outColor ,1 ,
                            [10,5] ,[7 ,8] ,[8 ,0] ,[6 ,8] ); 
            sprite.graphics.endFill();
            sprite.graphics.beginFill(_inColor);
            sprite.graphics.drawCircle(12,8,2);
            bitmapData.draw(sprite);
            return bitmapData;
        }// デコイ画像
        private static function createDecoyEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.beginFill(_outColor);
            sprite.graphics.drawRect(5,7,6,2);
            sprite.graphics.drawCircle(3.5,8,2);
            sprite.graphics.drawCircle(12.5,8,2);
            bitmapData.draw(sprite);
            return bitmapData;
        }
        // Wallタイプの敵の画像を作成する
        private static function createWallEnemy(_outColor:uint, _inColor:uint):BitmapData {
            var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.moveTo(2, 8);
            sprite = drawingArray(sprite ,_outColor ,0,_outColor ,
                            [8, 2,2,8,14,14,8 ],[0 ,2,14,16,14,2,0]);
            sprite.graphics.endFill();
            sprite.graphics.moveTo(3, 8);
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_inColor ,1 ,
                            [4 ,10.5] , [5.5, 4 ] , [5, 12] , [4 ,8 ]);
            sprite.graphics.moveTo(13, 8);            
            sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_inColor ,1 ,
                            [12 ,5.5] , [5.5, 4 ] , [11, 4 ] , [4 ,8 ]);
            sprite.graphics.moveTo(3, 8);                            
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_inColor ,1 ,
                            [4 ,10.5] , [5.5, 4 ] , [5, 12] , [4 ,8 ]);
            sprite.graphics.moveTo(13, 8);            
            sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_inColor ,1 ,
                            [12 ,5.5] , [5.5, 4 ] , [11, 4 ] , [4 ,8 ]);            
            sprite.graphics.beginFill(_outColor);
            sprite.graphics.drawCircle(8,8,2);
            bitmapData.draw(sprite);
            return bitmapData;
        }        
        
        //-----------------------------------------------------       
        // 弾の画像作成【F】
        //----------------------------------------------------- 
        private static function createArrowBullet():BitmapData {
            var bitmapData:BitmapData = new BitmapData(8, 8, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.lineStyle(2);
            sprite.graphics.moveTo(1, 4);
            sprite.graphics.lineTo(7, 4);
            bitmapData.draw(sprite);
            return bitmapData;
        }
        // 普通の弾の画像を作成する (引数に弾の半径)
        private static function createNormalBullet(radius:int):BitmapData {
            var bitmapData:BitmapData = new BitmapData(8, 8, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.beginFill(0x000000);
            sprite.graphics.drawCircle(4, 4, radius);
            bitmapData.draw(sprite);
            return bitmapData;
        }        
        private static function createMissileBullet():BitmapData {
            var bitmapData:BitmapData = new BitmapData(8, 8, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.beginFill(0x000000);
            sprite.graphics.drawCircle(3, 2, 2);
            sprite.graphics.drawCircle(3, 6, 2);
            sprite.graphics.drawCircle(5, 4, 2);
            bitmapData.draw(sprite);
            return bitmapData;
        }
        // エフェクトのコインの画像を作成する
        private static function createCoin():BitmapData {
            var bitmapData:BitmapData = new BitmapData(8, 8, true, 0x00ffffff);
            var sprite:Sprite = new Sprite();
            sprite.graphics.beginFill(0xcccc00);
            sprite.graphics.drawEllipse(2, 1, 4, 6);
            sprite.graphics.endFill();
            sprite.filters = [new BevelFilter(1, 45, 0xffffff, 1, 0x000000, 1, 0, 0)];
            bitmapData.draw(sprite);
            return bitmapData;
        }

        //-----------------------------------------------------       
        // テキストの作成【F】
        //-----------------------------------------------------

        // 普通のテキストを作成する
        public static function createSimpleText(posx:int, posy:int, width:int, height:int, text:String, fontSize:int, textColor:uint):TextField {
            return ImageFactory.createText(posx, posy, width, height, text, fontSize, textColor, TextFieldAutoSize.CENTER);
        }
        
        // 縁取り付きのテキストを作成する
        public static function createBorderedText(posx:int, posy:int, width:int, height:int, text:String, fontSize:int, textColor:uint, borderColor:uint):TextField {
            return ImageFactory.createText(posx, posy, width, height, text, fontSize, textColor, TextFieldAutoSize.CENTER, false, true, borderColor);
        }
        // 縁取り付き左揃えのテキストを作成する【F】
        public static function createBorderedTextLEFT(posx:int, posy:int, width:int, height:int, text:String, fontSize:int, textColor:uint, borderColor:uint):TextField {
            return ImageFactory.createText(posx, posy, width, height, text, fontSize, textColor, TextFieldAutoSize.LEFT, false, true, borderColor);
        }

        // スコア表示用のテキストを作成する
        public static function createScoreText(posx:int, posy:int, width:int, height:int, text:String, fontSize:int, textColor:uint):TextField {
            return ImageFactory.createText(posx, posy, width, height, text, fontSize, textColor, TextFieldAutoSize.RIGHT, true);
        }
        // タワーのステータス表示用テキストを作成する
        public static function createStatusText(posx:int, posy:int, width:int, height:int, text:String, fontSize:int, textColor:uint):TextField {
            return ImageFactory.createText(posx, posy, width, height, text, fontSize, textColor, TextFieldAutoSize.CENTER, true);
        }
        // タワーのステータス表示用テキスト右揃えを作成する
        public static function createStatusTextRight(posx:int, posy:int, width:int, height:int, text:String, fontSize:int, textColor:uint):TextField {
            return ImageFactory.createText(posx, posy, width, height, text, fontSize, textColor, TextFieldAutoSize.RIGHT, true);
        }
        
        private static function createText(posx:int, posy:int, width:int, height:int, text:String, fontSize:int, textColor:uint, autoSize:String, bold:Boolean = false, border:Boolean = false, borderColor:uint = 0x000000, embed:Boolean = false):TextField { 
            var textField:TextField = new TextField();
            if (embed) {
                textField.embedFonts = true;
                textField.antiAliasType = AntiAliasType.ADVANCED;
            }
            var font:String = embed ? Const.EMBED_FONT : "Arial";
            textField.defaultTextFormat = new TextFormat(font, fontSize, null, bold);
            textField.text = text;
            textField.x = posx;
            textField.y = posy + Math.ceil((height - (textField.textHeight + 4)) / 2);
            textField.width = Math.max(width, textField.textWidth + 4);
            textField.height = textField.textHeight + 4;
            textField.textColor = textColor;
            if (border) { textField.filters = [new GlowFilter(borderColor, 1, 4, 4)]; }
            textField.autoSize = autoSize;
            textField.mouseEnabled = textField.selectable = false;
            return textField;
        }
        
        // 説明用のテキストを作成する
        public static function createInstructionText(posx:int, posy:int, width:int, height:int, text:String, fontSize:int):TextField {
            return ImageFactory.createText(posx, posy, width, height, text, fontSize, 0xffffff, TextFieldAutoSize.LEFT, false, false, 0x000000, Const.USE_FONTLOADER);
        }
        
        // ウインドウを作成する
        public static function createWindow(posx:int, posy:int, width:int, height:int):Sprite {
            var sprite:Sprite = new Sprite();
            sprite.x = posx;
            sprite.y = posy;
            sprite.mouseEnabled = false;
            var matrix:Matrix = new Matrix();
            matrix.createGradientBox(width, height, Math.PI / 2);
            sprite.graphics.lineStyle(1);
            sprite.graphics.lineGradientStyle(GradientType.LINEAR, [0xf0f0f0, 0x808080], [1, 1], [0, 255], matrix);
            sprite.graphics.beginGradientFill(GradientType.LINEAR, [0x303030, 0x000000], [1, 1], [0, 255], matrix);
            sprite.graphics.drawRect(1, 1, width - 2, height - 2);
            sprite.graphics.endFill();
            return sprite;
        }
        
        
        //描画サポートファンクション【F】-----------------------------------        
        //線を描画用のファンクション引数は(スプライト、線色、線のアルファ、塗り色、x座標アレイ、y座標アレイ) 
        private  static function drawingArray(drawn:Sprite,lineColor:uint,alpha:int,bodyColor:uint,xArray:Array,yArray:Array):Sprite {
            drawn.graphics.lineStyle(1,lineColor,alpha,true);
            drawn.graphics.beginFill(bodyColor);
            if(xArray.length == yArray.length){                 
                 var len:int = xArray.length;
                 for ( var i:int=0; i<len; i++ ){drawn.graphics.lineTo(xArray[i],yArray[i])} ;
            }
            return drawn;    
        }
        
        //タワー画像の下に敷く円 引数は(線の色)
        private  static function towerCircle(lineColor:uint):Sprite{
            var _cy:Sprite = new Sprite;
            _cy.graphics.lineStyle(1,lineColor,1,true);
            _cy.graphics.drawCircle(16,16,10);
            return _cy;
        }
        //カーブ用の描画サポート、アーカーポイントの座標がnullのときはlineToする
        //引数は(スプライト、線色、線のアルファ、塗り色、塗りのアルファ、アーカーx座標アレイ、アーカーy座標アレイ、 描画x座標アレイ、 描画y座標アレイ)
        private static function drawingCurveArray(drawn:Sprite, lineColor:uint, lineAlpha:Number, bodyColor:uint, bodyAlpha:Number , AxArray:Array, AyArray:Array ,PxArray:Array, PyArray:Array):Sprite{
            drawn.graphics.lineStyle(1 ,lineColor, lineAlpha, true);
            drawn.graphics.beginFill(bodyColor ,bodyAlpha );
            if(AxArray.length == AyArray.length && PxArray.length == PyArray.length && AxArray.length == PxArray.length){                 
                 var len:int = AxArray.length;
                     for ( var i:int=0; i<len; i++ ){
                         if ( AxArray[i] == null  &&  AyArray[i] == null) {drawn.graphics.lineTo(PxArray[i], PyArray[i]); continue 
                         } else { drawn.graphics.curveTo(AxArray[i], AyArray[i] , PxArray[i], PyArray[i] ); continue ;}
                     } 
            }
            return drawn;    
        } 
        // 敵を作成する専用描画ファンクション
        // カーブを上下に反射して描画(縦16ピクセル用)
        private static function drawingCurveArrayMILLOR(drawn:Sprite, lineColor:uint, lineAlpha:Number, bodyColor:uint, bodyAlpha:Number , AxArray:Array, AyArray:Array ,PxArray:Array, PyArray:Array):Sprite{
            drawn.graphics.lineStyle(1 ,lineColor, lineAlpha, true);
            drawn.graphics.beginFill(bodyColor ,bodyAlpha );
            if(AxArray.length == AyArray.length && PxArray.length == PyArray.length && AxArray.length == PxArray.length){                 
                 var len:int = AxArray.length;
                     for ( var i:int=0; i<len; i++ ){
                         if ( AxArray[i] == null  &&  AyArray[i] == null) {drawn.graphics.lineTo(PxArray[i], PyArray[i]); continue 
                         } else { drawn.graphics.curveTo(AxArray[i], 16 - AyArray[i] , PxArray[i], 16 - PyArray[i] ); continue ;}
                     } 
            }
            return drawn;    
        }        
        
        //-----------------------------------        

    }
//}

/* ----------------------------------------------------------------------------------------------------------------------
 * Config
 * -----------------------------------------------------------------------------------------------------------------------
 */
//package {
    import flash.utils.Dictionary;
    
    //public 
    class Config {
        public static const INITIAL_LIVES:int = 10;
        public static const INITIAL_GOLD:int = 200; 
        
        //横Node0-23 縦Node0-25
        public static const NODE_TYPE:Array = [
            [1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,2,2],
            [1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,2,2],
            [1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
            [1,1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1,1],
            [1,1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1,1],
            [1,1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1,1],
            [1,1,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,1,1],
            [1,1,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,1,1],
            [1,1,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,1,1],
            [1,1,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,1,1],
            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
            [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
            [1,1,1,1,1,1,1,1,0,0,2,2,0,0,0,0,0,0,0,0,1,1,1,1],
            [1,1,1,1,1,1,1,1,0,0,2,2,0,0,0,0,0,0,0,0,1,1,1,1],
            [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
            [1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
        ];

        private static const XML_DATA:XML =
        <root>
            <starts>
                <start x="8"  y="0" width="4" flying="0" />
                <start x="21"  y="0" width="2" flying="0" />
                <start x="2" y="0" width="1" flying="1" />
            </starts>
            <goals>
                <goal x="10" y="20" /><goal x="11" y="20" />
                <goal x="10" y="21" /><goal x="11" y="21" />
            </goals>
           
            <tower>
                <type name="Gun" towerbase="0" ground="1" air="1" slow="0" splash="0" venom="0">
                    <status level="1" cost="8"    damage="10"   range="60"  firerate="1.6" />
                    <status level="2" cost="16"   damage="20"   range="65"  firerate="1.8" />
                    <status level="3" cost="32"   damage="40"   range="70"  firerate="2.0" />
                    <status level="4" cost="64"   damage="80"   range="80"  firerate="2.2" />
                    <status level="5" cost="192"  damage="300"  range="180" firerate="1.0" />
                </type>
                <type name="Gatling" towerbase="0" ground="1" air="1" slow="0" splash="0" venom="0">
                    <status level="1" cost="20"   damage="5"    range="55"  firerate="4.0" />
                    <status level="2" cost="35"   damage="9"    range="60"  firerate="4.5" />
                    <status level="3" cost="95"   damage="22"   range="65"  firerate="5.0" />
                    <status level="4" cost="210"  damage="50"   range="70"  firerate="5.5" />
                    <status level="5" cost="800"  damage="166"   range="80"  firerate="9.9" />
                </type>
                <type name="Cannon" towerbase="0" ground="1" air="0" slow="0" splash="24" venom="0">
                    <status level="1" cost="25"   damage="15"   range="80"  firerate="0.9" />
                    <status level="2" cost="50"   damage="40"   range="88"  firerate="1.0" />
                    <status level="3" cost="120"   damage="120"   range="96"  firerate="1.1" />
                    <status level="4" cost="280"  damage="350"  range="104" firerate="1.2" />
                    <status level="5" cost="940"  damage="980"  range="126" firerate="1.6" />
                </type>        
                <type name="Venom" towerbase="0" ground="1" air="0" slow="0" splash="0" venom="3">
                    <status level="1" cost="30"   damage="5"   range="32"  firerate="0.5" />
                    <status level="2" cost="70"   damage="35"   range="34"  firerate="0.6" />
                    <status level="3" cost="150"   damage="80"   range="36"  firerate="0.8" />
                    <status level="4" cost="320"  damage="200"   range="38"  firerate="1.2" />
                    <status level="5" cost="1050"  damage="750"   range="45"  firerate="1.6" />
                </type>        
                <type name="Voltex" towerbase="0" ground="1" air="1" slow="25" splash="42" venom="0">
                    <status level="1" cost="70"   damage="20"   range="42"  firerate="0.6" />
                    <status level="2" cost="130"  damage="50"  range="42"  firerate="0.6" />
                    <status level="3" cost="250"  damage="120"  range="54"  firerate="0.8" />
                    <status level="4" cost="490"  damage="300"  range="54"  firerate="0.8" />
                    <status level="5" cost="990"  damage="690"  range="66"  firerate="1.0" />
                </type>        
                <type name="AntiFly" towerbase="0" ground="0" air="1" slow="0" splash="1" venom="0">
                    <status level="1" cost="100"  damage="135"  range="100"  firerate="1.1" />
                    <status level="2" cost="250"  damage="255"  range="104"  firerate="1.3" />
                    <status level="3" cost="510"  damage="510"  range="108"  firerate="1.5" />
                    <status level="4" cost="990"  damage="990"  range="112"  firerate="1.7" />
                    <status level="5" cost="2000" damage="2500" range="120"  firerate="2.0" />
                </type> 
                <type name="Base" towerbase="1" ground="0" air="0" slow="0" splash="0" venom="0">
                    <status level="1" cost="5"   damage="0"   range="0"  firerate="0" />
                </type>        
            </tower>
            
           <enemy>
                // flying[0/1] immunity[0/1] regeneration[回復量(MaxHPの千分率/フレーム)] fade[時間量] born[0/1] accelerate[0/1]
                <type name="Normal" speed="1.4" MinSpeed="1.3" MaxSpeed="1.5" flying="0" immunity="0" regeneration="0" fade="0" born="0" accelerate="0"/>
                <type name="Immune" speed="0.8" MinSpeed="0.7" MaxSpeed="0.9" flying="0" immunity="1" regeneration="0" fade="0" born="0" accelerate="0"/>
                <type name="Fast"   speed="2.8" MinSpeed="2.6" MaxSpeed="3.0" flying="0" immunity="0" regeneration="0" fade="0" born="0" accelerate="0"/>
                <type name="Flying" speed="1.4" MinSpeed="1.3" MaxSpeed="1.5" flying="1" immunity="0" regeneration="0" fade="0" born="0" accelerate="0" />
                <type name="Swarm" speed="1.8" MinSpeed="1.5" MaxSpeed="2.1" flying="0" immunity="0" regeneration="0" fade="0" born="0" accelerate="1" />
                <type name="Zombie" speed="1.1" MinSpeed="1.0" MaxSpeed="1.2" flying="0" immunity="0" regeneration="10" fade="0" born="0" accelerate="0" />
                <type name="Fade" speed="1.6" MinSpeed="1.5" MaxSpeed="1.7" flying="0" immunity="0" regeneration="0" fade="80" born="0" accelerate="0" />
                <type name="Split" speed="1.1" MinSpeed="1.0" MaxSpeed="1.2" flying="0" immunity="0" regeneration="0" fade="0" born="1" accelerate="0" />
                <type name="SplitChild" speed="1.8" MinSpeed="1.6" MaxSpeed="2.0" flying="0" immunity="0" regeneration="0" fade="0" born="0" accelerate="1" />
                <type name="Fury" speed="1.6" MinSpeed="1.3" MaxSpeed="8.0" flying="0" immunity="0" regeneration="0" fade="0" born="0" accelerate="1" />
                <type name="Fupa" speed="1.5" MinSpeed="1.3" MaxSpeed="1.7" flying="0" immunity="0" regeneration="0" fade="0" born="1" accelerate="0" />
                <type name="FupaChild" speed="0.8" MinSpeed="0.7" MaxSpeed="0.9" flying="1" immunity="0" regeneration="0" fade="0" born="0" accelerate="0" />
                <type name="Ghost" speed="1.3" MinSpeed="1.2" MaxSpeed="1.4" flying="1" immunity="0" regeneration="0" fade="40" born="0" accelerate="0" />
                <type name="Shell" speed="3.8" MinSpeed="1.3" MaxSpeed="4.2" flying="0" immunity="0" regeneration="0" fade="0" born="1" accelerate="1" />
                <type name="Shell-2" speed="4.4" MinSpeed="1.4" MaxSpeed="4.6" flying="0" immunity="0" regeneration="0" fade="0" born="1" accelerate="1" />
                <type name="Shell-3" speed="5.4" MinSpeed="1.6" MaxSpeed="5.4" flying="0" immunity="0" regeneration="0" fade="0" born="0" accelerate="1" />
                <type name="Detour" speed="2.0" MinSpeed="0.7" MaxSpeed="2.3" flying="1" immunity="0" regeneration="0" fade="0" born="1" accelerate="1" />
                <type name="Detour-L" speed="2.0" MinSpeed="0.7" MaxSpeed="2.3" flying="1" immunity="0" regeneration="0" fade="0" born="0" accelerate="1" />
                <type name="Decoyer" speed="1.6" MinSpeed="1.3" MaxSpeed="1.6" flying="1" immunity="0" regeneration="0" fade="0" born="1" accelerate="0" />
                <type name="Decoy-1" speed="6.2" MinSpeed="0" MaxSpeed="6.2" flying="1" immunity="0" regeneration="0" fade="0" born="1" accelerate="1" />
                <type name="Decoy-2" speed="6.2" MinSpeed="0" MaxSpeed="6.2" flying="1" immunity="0" regeneration="0" fade="0" born="0" accelerate="1" />
                <type name="Wall" speed="0.8" MinSpeed="0.6" MaxSpeed="1.0" flying="0" immunity="1" regeneration="2" fade="0" born="0" accelerate="0" />
            </enemy>
            
            <bornAbility>
                //親名[string]、子名[string]、子HP割合[Number]、子得点割合[Number]、1回産数[int]、限度産量[int]、インターバル[int]、出産被ダメ%[0~1]、死亡出産[0/1]、お金相続[0/1]、出産後の自分除去[0/1]
                <parent name="Split" childrenName="SplitChild" childrenHP="0.2" childrenPoint="0.2" amount="4" limit="4" intervalBorn="0" HPrateBorn="0" deadBorn="1" descent="1" selfRemove="1"/>
                <parent name="Fupa" childrenName="FupaChild" childrenHP="0.5" childrenPoint="0.5" amount="1" limit="1" intervalBorn="0" HPrateBorn="0" deadBorn="1" descent="1" selfRemove="1"/>
                <parent name="Shell" childrenName="Shell-2" childrenHP="0.6" childrenPoint="1" amount="1" limit="1" intervalBorn="0" HPrateBorn="0.6" deadBorn="0" descent="1" selfRemove="1"/>
                <parent name="Shell-2" childrenName="Shell-3" childrenHP="0.5" childrenPoint="1" amount="1" limit="1" intervalBorn="0" HPrateBorn="0.5" deadBorn="0" descent="1" selfRemove="1"/>
                <parent name="Detour" childrenName="Detour-L" childrenHP="1" childrenPoint="1" amount="1" limit="1" intervalBorn="1" HPrateBorn="0" deadBorn="0" descent="1" selfRemove="0"/>
                <parent name="Decoyer" childrenName="Decoy-1" childrenHP="0.01" childrenPoint="0.01" amount="1" limit="40" intervalBorn="45" HPrateBorn="0" deadBorn="0" descent="0" selfRemove="0"/>
                <parent name="Decoy-1" childrenName="Decoy-2" childrenHP="1" childrenPoint="1" amount="1" limit="1" intervalBorn="1" HPrateBorn="0" deadBorn="0" descent="0" selfRemove="0"/>
            </bornAbility>
            
            <accelerateAbility>
                //能力者名[string]、加算変化[Number]、積変化[Number]、飛行角度[int(degree)],サイン周期変化[Number]、インターバル[int]、加速ダメ%[0~1]、加速被ダメ割合[Number]
                 <runner name="Swarm" AddPoint="0" RatePoint="1" Angle="0" sineSlip="60" intervalRun="0" HPrateRun="0" damageRun="0"/>
                 <runner name="SplitChild" AddPoint="0" RatePoint="1" Angle="0" sineSlip="90" intervalRun="0" HPrateRun="0" damageRun="0"/>
                 <runner name="Fury" AddPoint="0.15" RatePoint="1" Angle="0" sineSlip="0" intervalRun="0" HPrateRun="0" damageRun="1"/>
                 <runner name="Shell" AddPoint="-0.2" RatePoint="1" Angle="0" sineSlip="0" intervalRun="2" HPrateRun="0" damageRun="0"/>
                 <runner name="Shell-2" AddPoint="-0.2" RatePoint="1" Angle="0" sineSlip="0" intervalRun="2" HPrateRun="0" damageRun="0"/>
                 <runner name="Shell-3" AddPoint="-0.2" RatePoint="1"  Angle="0" sineSlip="0" intervalRun="2" HPrateRun="0" damageRun="0"/>
                 <runner name="Detour" AddPoint="0" RatePoint="0.99"  Angle="305" sineSlip="0" intervalRun="3" HPrateRun="0" damageRun="0"/>
                 <runner name="Detour-L" AddPoint="0" RatePoint="0.99"  Angle="55" sineSlip="0" intervalRun="3" HPrateRun="0" damageRun="0"/>
                 <runner name="Decoyer" AddPoint="0" RatePoint="1"  Angle="0" sineSlip="60" intervalRun="2" HPrateRun="0" damageRun="0"/>
                 <runner name="Decoy-1" AddPoint="0" RatePoint="0.9"  Angle="90" sineSlip="0" intervalRun="1" HPrateRun="0" damageRun="0"/>
                 <runner name="Decoy-2" AddPoint="0" RatePoint="0.9"  Angle="270" sineSlip="0" intervalRun="1" HPrateRun="0" damageRun="0"/>
            </accelerateAbility>

            <waves>
                <wave type="Normal" HP="20"   point="8"   money="1"  ><spawn num="10" /><spawn num="0" /><spawn num="0"  /></wave>
                <wave type="Normal" HP="25"   point="8"   money="1"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Normal" HP="30"   point="8"   money="1"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Swarm"  HP="8"   point="1"   money="1"  ><spawn num="20" /><spawn num="20" /><spawn num="0"  /></wave>
                <wave type="Shell" HP="90"   point="8"   money="2"  ><spawn num="5" /><spawn num="5" /><spawn num="0"  /></wave>
                <wave type="Normal" HP="50"   point="8"   money="1"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Fade" HP="70"   point="8"   money="1"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Fast"   HP="80"   point="8"   money="1"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Flying" HP="70"   point="10"  money="2"  ><spawn num="0"  /><spawn num="0"  /><spawn num="15" /></wave>
                <wave type="Zombie" HP="300"  point="50"  money="20" ><spawn num="2"  /><spawn num="2"  /><spawn num="0"  /></wave>
                
                <wave type="Split" HP="70"  point="5"  money="1"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Normal" HP="110"  point="10"  money="2"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Immune" HP="160"  point="10"  money="2"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Shell"   HP="140"  point="10"  money="2"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Flying" HP="120"  point="12"  money="2"  ><spawn num="0"  /><spawn num="0"  /><spawn num="15" /></wave>
                <wave type="Zombie" HP="180"  point="14"  money="3"  ><spawn num="6" /><spawn num="6" /><spawn num="0"  /></wave>
                <wave type="Normal" HP="170"  point="12"  money="2"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Fury" HP="1000" point="60"  money="25" ><spawn num="2"  /><spawn num="2"  /><spawn num="0"  /></wave>
                <wave type="Flying" HP="150"  point="15"  money="4"  ><spawn num="4"  /><spawn num="4"  /><spawn num="4"  /></wave>
                <wave type="Immune" HP="1600"  point="62"  money="30"  ><spawn num="3" /><spawn num="3" /><spawn num="0"  /></wave>
                
                <wave type="Normal" HP="240"  point="12"  money="3"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Fast"   HP="260"  point="12"  money="3"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Fade"   HP="400"  point="12"  money="3"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Fupa" HP="800" point="30" money="18"><spawn num="4"  /><spawn num="4"  /><spawn num="0"  /></wave>
                <wave type="Normal" HP="350"  point="14"  money="4"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Immune" HP="400"  point="14"  money="4"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Swarm"  HP="100"  point="4"  money="1"  ><spawn num="35" /><spawn num="35" /><spawn num="0"  /></wave>
                <wave type="Normal" HP="500"  point="14"  money="4"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Ghost" HP="600"  point="18"  money="8"  ><spawn num="0" /><spawn num="5" /><spawn num="5"  /></wave>
                <wave type="Split" HP="610"  point="8"  money="2"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                
                <wave type="Flying" HP="480"  point="14"  money="4"  ><spawn num="0"  /><spawn num="0"  /><spawn num="20" /></wave>
                <wave type="Fast"   HP="4000" point="150" money="80" ><spawn num="1"  /><spawn num="1"  /><spawn num="0"  /></wave>
                <wave type="Normal" HP="650"  point="15"  money="5"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Fupa" HP="750"  point="15"  money="5"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Immune" HP="900"  point="15"  money="5"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Flying" HP="800"  point="15"  money="5"  ><spawn num="6"  /><spawn num="6"  /><spawn num="6"  /></wave>
                <wave type="Normal" HP="1000" point="15"  money="5"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Immune" HP="1800" point="30"  money="10" ><spawn num="5"  /><spawn num="5"  /><spawn num="0"  /></wave>
                <wave type="Fast"   HP="1200" point="15"  money="6"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Fade" HP="2000" point="20"  money="8"  ><spawn num="20" /><spawn num="20" /><spawn num="0"  /></wave>
                
                <wave type="Swarm"   HP="550" point="5"  money="2"  ><spawn num="45" /><spawn num="45"  /><spawn num="0"  /></wave>
                <wave type="Fast"   HP="1500" point="15"  money="10"  ><spawn num="0"  /><spawn num="20" /><spawn num="0"  /></wave>
                <wave type="Shell" HP="3800" point="15"  money="12"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Immune" HP="7000" point="15"  money="16"  ><spawn num="10" /><spawn num="10" /><spawn num="0"  /></wave>
                <wave type="Detour" HP="1500" point="15"  money="20"  ><spawn num="10"  /><spawn num="0"  /><spawn num="0" /></wave>
                <wave type="Wall" HP="9500" point="15"  money="48"  ><spawn num="4" /><spawn num="4" /><spawn num="0"  /></wave>
                <wave type="Fury"   HP="5300" point="50"  money="52"  ><spawn num="5" /><spawn num="5" /><spawn num="0"  /></wave>
                <wave type="Fupa" HP="4800" point="20" money="35"><spawn num="10"  /><spawn num="10"  /><spawn num="0"  /></wave>
                <wave type="Split" HP="20000"point="200" money="40"><spawn num="3"  /><spawn num="3"  /><spawn num="0"  /></wave>
                <wave type="Decoyer" HP="12000"point="250" money="100"><spawn num="2"  /><spawn num="2"  /><spawn num="2"  /></wave>
            </waves>
        </root>;
        
        // スタート地点の配列を返す
        public static function getStarts():Vector.<Start> {
            var value:Vector.<Start> = new Vector.<Start>();
            for each(var s:XML in Config.XML_DATA.starts.*) {
                value.push(new Start(int(s.@x), int(s.@y), int(s.@width), Boolean(int(s.@flying))));
            }
            return value;
        }
        
        // ゴールの配列を返す
        public static function getGoals():Vector.<Goal> {
            var value:Vector.<Goal> = new Vector.<Goal>();
            for each(var g:XML in Config.XML_DATA.goals.*) {
                value.push(new Goal(int(g.@x), int(g.@y)));
            }
            return value;
        }
        
        //-------------        
        // タワーの種類の配列を返す
        public static function getTowerType():Vector.<TowerType> {
            var value:Vector.<TowerType> = new Vector.<TowerType>();
            for each(var t:XML in Config.XML_DATA.tower.*) {
                value.push(new TowerType(t.@name, Boolean(int(t.@towerbase)),Boolean(int(t.@ground)), Boolean(int(t.@air)), int(t.@slow), int(t.@splash) , int(t.@venom)));
            }
            return value;
        }
        
        // 引数で指定した種類の、ステータスの配列を返す
        public static function getTowerStatus(towerTypeName:String):Vector.<TowerStatus> {
            var value:Vector.<TowerStatus> = new Vector.<TowerStatus>();
            for each(var s:XML in Config.XML_DATA.tower.*.(@name == towerTypeName).*) {
                value.push(new TowerStatus(int(s.@level), int(s.@cost), int(s.@damage), int(s.@range), Number(s.@firerate)));
            }
            //value.sortOn("level", Array.NUMERIC);
            return value;
        }

        //-------------        
        // 敵の種類の連想配列を返す
        public static function getEnemyType():Dictionary {
            var value:Dictionary = new Dictionary();
            for each(var e:XML in Config.XML_DATA.enemy.*) {
                var typeName:String = e.@name;
                value[typeName] = new EnemyType(typeName, Number(e.@speed),  Number(e.@MinSpeed), Number(e.@MaxSpeed),Boolean(int(e.@flying)), Boolean(int(e.@immunity)),int(e.@regeneration),int(e.@fade),Boolean(int(e.@born)),Boolean(int(e.@accelerate)) ) ;
            }
            return value;
        }        
        // 出産能力の連想配列を返す
        public static function getBornAbility():Dictionary {
            var value:Dictionary = new Dictionary();
            for each(var b:XML in Config.XML_DATA.bornAbility.*) {
                var parentName:String = b.@name;
                value[parentName] = new BornAbility( parentName, String(b.@childrenName), Number(b.@childrenHP), Number(b.@childrenPoint), int(b.@amount),  int(b.@limit),  int(b.@intervalBorn), Number(b.@HPrateBorn), Boolean(int(b.@deadBorn)), Boolean(int(b.@descent)), Boolean(int(b.@selfRemove)) );
            }
            return value;
        }
        // 加速能力の連想配列を返す
        public static function getAccelerateAbility():Dictionary {
            var value:Dictionary = new Dictionary();
            for each(var a:XML in Config.XML_DATA.accelerateAbility.*) {
                var runnerName:String = a.@name ;
                value[runnerName] = new AccelerateAbility( runnerName, Number(a.@AddPoint), Number(a.@RatePoint), Number(a.@Angle), int(a.@sineSlip), int(a.@intervalRun), Number(a.@HPrateRun), Number(a.@damageRun));
            }
            return value;
        }               
        //-------------                
        // ウェーブの配列を返す
        public static function getWaves():Vector.<Wave> {
            var waveNumber:int = 1;
            var value:Vector.<Wave> = new Vector.<Wave>();
            for each(var w:XML in Config.XML_DATA.waves.*) {
                var spawn:Vector.<int> = new Vector.<int>();
                for each(var s:XML in w.*) { spawn.push(int(s.@num)); }
                value.push(new Wave(waveNumber, EnemyType.getType(String(w.@type)), int(w.@HP), int(w.@point), int(w.@money), spawn));
                waveNumber++;
            }
            return value;
        }
    }
//}