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

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

節分Wars

<節分Wars>

 クリックで鬼は外!
 豆を投げて頑張ってください。
 
 ソースがひどい...;;

 アップデート 2011/2/4 0:44
  豆の飛距離を修正

 アップデート 2011/2/4 20:25
  敵のポップアップ率を調整
  スコアを調整
  緑鬼のサイズを調整
  ラスト鬼を追加
  豆キャノンを追加


<Setsubun Wars>
 Setsubun : Japanese Traditional Event to throw beans.

 click to throw beans.
 thats all.

 updated 2011/2/4 0:44
  fixed beans throw distance

 updated 2011/2/4 20:25
  adjusted popup rate
  adjusted score
  adjusted green-oni size
  add last oni
  add mame cannon
/**
 * Copyright nikukyu ( http://wonderfl.net/user/nikukyu )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/d0TV
 */

/**
<節分Wars>

 クリックで鬼は外!
 豆を投げて頑張ってください。
 
 ソースがひどい...;;

<Setsubun Wars>
 Setsubun : Japanese Traditional Event to throw beans.

 click to throw beans.
 thats all.

*/
package
{
    import flash.display.DisplayObject;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    
    [SWF(backgroundColor='#888888', frameRate='30', width='465', height='465')]     
    
    public class Main extends Sprite 
    {
        private var _bg_container:BackGround;
        private var _shadow_container:Sprite;
        private var _mob_container:Sprite;
        private var _effect_container:EffectField;
        private var _ui_container:Sprite;
        
        private var _player:Player;
        private var _menu:Menu;
        private var _mobs:Vector.<MobObject>;
        
        private var _count:int;
        
        public function Main()
        {
            _bg_container                    = new BackGround();
            addChild( _bg_container );

            _shadow_container                = new Sprite();
            addChild( _shadow_container );
            
            _mob_container                    = new Sprite();
            addChild( _mob_container );
            
            _effect_container                = new EffectField();
            addChild( _effect_container );
            
            _ui_container                    = new Sprite();
            addChild( _ui_container );
            
            _bg_container.z                    = G.STAGE_FOCAL;
            _shadow_container.z                = G.STAGE_FOCAL;
            _mob_container.z                = G.STAGE_FOCAL;
            
            _player                            = new Player();
            _menu                            = new Menu( _player.score, _player.life, _player.weapon, _player.combo );
            _mobs                            = new Vector.<MobObject>();
            
            _count                            = 0;
            
            _ui_container.addChild( _menu );
            
            stage.addEventListener( MouseEvent.MOUSE_DOWN, onMouseDownStage );
            stage.addEventListener( MouseEvent.MOUSE_UP, onMouseUpStage );
            stage.addEventListener( Event.ENTER_FRAME, update );
        }
        
        private function update( e:Event ):void 
        {
            if ( _player.life <= 0 )
            {
                _effect_container.setBlack();
                _menu.gameOver();
                return;
            }
            
            if ( _player.clear )
            {
                _menu.gameClear();
                return;
            }
            
            // gatling
            if ( _player.shot && _player.weapon == 2 )
            {
                shot( mouseX, mouseY );
            }
            
            popCheck();
            
            lvUpCheck();
            spawnCheck();
            hitCheck();
            comboCheck();
            removeMobCheck();
            damageCheck();
            sortCheck();
            
            // player
            _player.comboUpdate();
            
            // update menu
            _menu.setScore( _player.score );
            _menu.setLife( _player.life );
            _menu.setWeapon( _player.weapon );
            _menu.setCombo( _player.combo );
            
            // update bg
            _bg_container.setTargetPosition( mouseX );
            
            // count up
            _count++;
        }
        
        // game core
        private function popCheck():void
        {
            // preparation
            if ( _count < 100 )
            {
                
            }
            
            // lv1 intro = tutorial pop
            else if ( _count == 100 )
            {
                popROni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            else if ( _count == 500 )
            {
                popROni( G.STAGE_WIDTH * 3 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            else if ( _count == 550 )
            {
                popROni( G.STAGE_WIDTH * 5 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            else if ( _count == 1000 )
            {
                popROni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            else if ( _count == 1030 )
            {
                popROni( G.STAGE_WIDTH * 6 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            else if ( _count == 1060 )
            {
                popROni( G.STAGE_WIDTH * 2 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            
            // lv1
            else if ( 1500 < _count && _count < 3000 )
            {
                if ( Math.random() < 0.002 ) popROni( Math.random() * G.STAGE_WIDTH, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
                if ( !( _count % 100 ) ) popROni( Math.random() * G.STAGE_WIDTH, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            
            // lv1 final
            else if ( _count == 3500 )
            {
                popROni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 2 );
            }
            else if ( _count == 3530 )
            {
                popROni( G.STAGE_WIDTH * 3 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
                popROni( G.STAGE_WIDTH * 5 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            else if ( _count == 3560 )
            {
                popROni( G.STAGE_WIDTH * 2 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
                popROni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
                popROni( G.STAGE_WIDTH * 6 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            else if ( _count == 3590 )
            {
                popROni( G.STAGE_WIDTH * 1 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
                popROni( G.STAGE_WIDTH * 3 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
                popROni( G.STAGE_WIDTH * 5 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
                popROni( G.STAGE_WIDTH * 7 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            
            // lv2 intro
            else if ( _count == 3900 )
            {
                popBOni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            else if ( _count == 4200 )
            {
                popBOni( G.STAGE_WIDTH * 2 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            else if ( _count == 4250 )
            {
                popBOni( G.STAGE_WIDTH * 6 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            
            // lv2
            else if ( 4400 < _count && _count < 6250 )
            {
                if ( Math.random() < 0.003 ) popROni( Math.random() * G.STAGE_WIDTH, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 2 );
                if ( Math.random() < 0.002 ) popBOni( Math.random() * G.STAGE_WIDTH, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
                if ( !( _count % 100 ) ) popBOni( Math.random() * G.STAGE_WIDTH, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            
            // lv2 final
            else if ( _count == 6500 )
            {
                popBOni( G.STAGE_WIDTH * 2 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
                popBOni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 2 );
                popBOni( G.STAGE_WIDTH * 6 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            else if ( _count == 6600 )
            {
                popBOni( G.STAGE_WIDTH * 2 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 2 );
                popBOni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
                popBOni( G.STAGE_WIDTH * 6 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            else if ( _count == 6700 )
            {
                popBOni( G.STAGE_WIDTH * 2 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
                popBOni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
                popBOni( G.STAGE_WIDTH * 6 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 2 );
            }
            
            // lv3 intro
            else if ( _count == 7200 )
            {
                popGOni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            else if ( _count == 7450 )
            {
                popGOni( G.STAGE_WIDTH * 2 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            else if ( _count == 7500 )
            {
                popGOni( G.STAGE_WIDTH * 6 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            
            // lv3
            else if ( 7750 < _count && _count < 10250 )
            {
                if ( Math.random() < 0.003 ) popROni( Math.random() * G.STAGE_WIDTH, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 3 );
                if ( Math.random() < 0.003 ) popBOni( Math.random() * G.STAGE_WIDTH, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 2 );
                if ( Math.random() < 0.002 ) popGOni( Math.random() * G.STAGE_WIDTH, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
                if ( !( _count % 100 ) ) popGOni( Math.random() * G.STAGE_WIDTH, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 1 );
            }
            
            // lv3 final
            else if ( _count == 10500 )
            {
                popGOni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 2 );
            }
            else if ( _count == 10550 )
            {
                popGOni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 2 );
            }
            else if ( _count == 10600 )
            {
                popGOni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 2 );
            }
            else if ( _count == 10650 )
            {
                popGOni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 2 );
            }
            else if ( _count == 10700 )
            {
                popGOni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 3 );
            }
            else if ( _count == 11000 )
            {
                popGOni( G.STAGE_WIDTH * 4 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 2 );
                popGOni( G.STAGE_WIDTH * 2 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 3 );
                popGOni( G.STAGE_WIDTH * 6 / 8, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, 2 );
            }
            
            // final
            else if ( _count == 11250 )
            {
                popOniTank( G.POP_TANK_X, G.POP_TANK_Y, G.POP_Z_DEFAULT, 1 );
            }
            
            // clear check
            else if ( _count == 11252 )
            {
                if ( _mobs.length <= 0 )
                {
                    popLOni( G.POP_L_X, G.POP_L_Y, G.POP_Z_DEFAULT, 1 );
                }
                else
                {
                    _count--;
                }
            }
            
            // clear check
            else if ( 11260 < _count )
            {
                if ( _mobs.length <= 0 )
                {
                    _player.clear            = true;
                }
                else if ( _count == 11700 )
                {
                    _player.score            += 10000;
                    _menu.setBonus();
                }
                else if ( _count == 11800 )
                {
                    _player.clear            = true;
                }
            }
        }
        
        private function lvUpCheck():void
        {
            if ( _player.weapon == 0 )
            {
                if ( G.LVUP_SCORE_1 < _player.score )
                {
                    _player.weapon            = 1;
                    _player.life            = 3;
                    _menu.setLvup();
                }
            }
            else if ( _player.weapon == 1 )
            {
                if ( G.LVUP_SCORE_2 < _player.score )
                {
                    _player.weapon            = 2;
                    _player.life            = 3;
                    _menu.setLvup();
                }
            }
            else if ( _player.weapon == 2 )
            {
                if ( G.LVUP_SCORE_3 < _player.score )
                {
                    _player.weapon            = 3;
                    _player.life            = 3;
                    _menu.setLvup();
                }
            }
        }
        
        private function spawnCheck():void
        {
            var num:int                        = _mobs.length;
            
            for ( var i:int = 0; i < num ; ++i )
            {
                if ( _mobs[i] is OniTank )
                {
                    if ( _mobs[i].isSpawnTama() )
                    {
                        popTOni( G.POP_T_X, G.POP_T_Y, _mobs[i].z, 1 );
                    }
                    if ( _mobs[i].isSpawnMissile() )
                    {
                        popMOni( G.POP_M_X, G.POP_M_Y, _mobs[i].z, 1 );
                    }
                }
            }
        }
        
        private function hitCheck():void
        {
            var num:int                        = _mobs.length;
            
            for ( var i:int = 0; i < num ; ++i )
            {
                if ( _mobs[i] is Mame && _mobs[i].isHittable() )
                {
                    for ( var j:int = 0; j < num; ++j )
                    {
                        if ( _mobs[j] is Oni && _mobs[j].isHittable() )
                        {
                            if ( _mobs[i].getRect( stage ).intersects( _mobs[j].getRect( stage ) ) && Math.abs( _mobs[i].z - _mobs[j].z ) < G.MAME_HIT_RANGE / 2 )
                            {
                                var damage:int                = _mobs[i].hit();
                                _player.score                += _mobs[j].hit( damage, _mobs[j].x - _mobs[i].x );
                            }
                        }
                    }
                }
            }
        }
        
        private function comboCheck():void
        {
            var num:int                        = _mobs.length;
            
            for ( var i:int = 0; i < num ; ++i )
            {
                if ( _mobs[i] is Oni )
                {
                    var combo_range:Number                    = _mobs[i].getCombo();
                    
                    if ( 0 < combo_range )
                    {
                        for ( var j:int = 0; j < num; ++j )
                        {
                            if ( _mobs[j] is Oni && _mobs[j].isComboEnable() )
                            {
                                if ( _mobs[i].getRect( stage ).intersects( _mobs[j].getRect( stage ) ) && _mobs[i].z < _mobs[j].z && ( _mobs[j].z - _mobs[i].z ) < combo_range )
                                {
                                    _player.score                += _mobs[j].combo();
                                    _player.combo++;
                                    _player.score                += _player.combo * G.SCORE_COMBO_RATE;
                                }
                            }
                        }
                    }
                }
            }
        }
        
        private function removeMobCheck():void
        {
            var num:int                        = _mobs.length;
            
            for ( var i:int = num - 1; 0 <= i; --i )
            {
                _mobs[i].update();
                
                if ( _mobs[i].isRemovable() )
                {
                    _mob_container.removeChild( _mobs[i] );
                    _shadow_container.removeChild( _mobs[i].shadow );
                    _mobs.splice( i, 1 );
                }
            }
        }
        
        private function damageCheck():void
        {
            var num:int                        = _mobs.length;
            
            for ( var i:int = 0; i < num; ++i )
            {
                if ( _mobs[i] is Oni )
                {
                    var damage:int                = _mobs[i].getDamage();
                    
                    if ( 0 < damage )
                    {
                        _player.life            -= damage;
                        _effect_container.setRed();
                    }
                }
            }
        }
        
        private function sortCheck():void
        {
            var num:int                        = _mobs.length;
            
            _mobs.sort( sortByZ );
            
            for ( var i:int = 0; i < num; ++i )
            {
                _mob_container.setChildIndex( _mobs[i], i );
            }
        }
        
        private function sortByZ( o1:DisplayObject, o2:DisplayObject ):int
        {
            return ( o1.z < o2.z ) ? 1 : -1;
        }
        
        private function shot( x:Number, y:Number ):void
        {
            if ( _player.life <= 0 || _player.clear )
            {
                return;
            }
            
            var mame_num:int                = 0;
            var shot_num:int                = 1;
            
            for each( var mob:MobObject in _mobs )
            {
                if ( mob is Mame ) mame_num++;
            }
            
            switch( _player.weapon )
            {
            case 0:
                if ( G.MAME_GUN_MAX < mame_num ) return;
                break;
                
            case 1:
                if ( G.MAME_SHOT_MAX < mame_num ) return;
                shot_num                    = 3;
                break;
                
            case 2:
                if ( G.MAME_GATLING_MAX < mame_num ) return;
                _player.shot                = true;
                break;
                
            case 3:
                if ( G.MAME_CANNON_MAX < mame_num ) return;
                break;
            }
            
            for ( var i:int = 0; i < shot_num; ++i )
            {
                var lv:int                    = _player.weapon;
                
                var shadow:Shadow            = new Shadow();
                _shadow_container.addChild( shadow );
                var mame:Mame                = new Mame( shadow, x, y, lv );
                _mobs.push( mame );
                _mob_container.addChild( mame );
            }
        }
        
        private function testPop( e:KeyboardEvent ):void 
        {
            var lv:int = 1;
            
            if ( e.shiftKey ) lv = 2;
            if ( e.ctrlKey ) lv = 3;
            
            if ( e.keyCode == 49 )
            {
                popROni( stage.mouseX, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, lv );
            }
            if ( e.keyCode == 50 )
            {
                popBOni( stage.mouseX, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, lv );
            }
            if ( e.keyCode == 51 )
            {
                popGOni( stage.mouseX, G.POP_Y_DEFAULT, G.POP_Z_DEFAULT, lv );
            }
            if ( e.keyCode == 52 )
            {
                popOniTank( G.POP_TANK_X, G.POP_TANK_Y, G.POP_Z_DEFAULT, 1 );
            }
            if ( e.keyCode == 53 )
            {
                popTOni( G.POP_T_X, G.POP_T_Y, G.POP_Z_DEFAULT, 1 );
            }
            if ( e.keyCode == 54 )
            {
                popMOni( G.POP_M_X, G.POP_M_Y, G.POP_Z_DEFAULT, 1 );
            }
        }
        
        private function popROni( x:Number, y:Number, z:Number, lv:int ):void
        {
            if ( lv < G.POP_LV_MIN )        lv    = G.POP_LV_MIN;
            else if ( G.POP_LV_MAX < lv )    lv    = G.POP_LV_MAX;
            
            var shadow:Shadow            = new Shadow();
            _shadow_container.addChild( shadow );
            var oni:Oni                    = new RedOni( lv, shadow );
            _mobs.push( oni );
            _mob_container.addChild( oni );
            oni.x                        = x;
            oni.y                        = y;
            oni.z                        = z;
    
            if ( oni.x < G.POP_X_MIN ) oni.x            = G.POP_X_MIN;
            else if ( G.POP_X_MAX < oni.x ) oni.x        = G.POP_X_MAX;
        }
        
        private function popBOni( x:Number, y:Number, z:Number, lv:int ):void
        {
            if ( lv < G.POP_LV_MIN )        lv    = G.POP_LV_MIN;
            else if ( G.POP_LV_MAX < lv )    lv    = G.POP_LV_MAX;
            
            var shadow:Shadow            = new Shadow();
            _shadow_container.addChild( shadow );
            var oni:Oni                    = new BlueOni( lv, shadow );
            _mobs.push( oni );
            _mob_container.addChild( oni );
            oni.x                        = x;
            oni.y                        = y;
            oni.z                        = z;
            
            if ( oni.x < G.POP_X_MIN ) oni.x            = G.POP_X_MIN;
            else if ( G.POP_X_MAX < oni.x ) oni.x        = G.POP_X_MAX;
        }
        
        private function popGOni( x:Number, y:Number, z:Number, lv:int ):void
        {
            if ( lv < G.POP_LV_MIN )        lv    = G.POP_LV_MIN;
            else if ( G.POP_LV_MAX < lv )    lv    = G.POP_LV_MAX;
            
            var shadow:Shadow            = new Shadow();
            _shadow_container.addChild( shadow );
            var oni:Oni                    = new GreenOni( lv, shadow );
            _mobs.push( oni );
            _mob_container.addChild( oni );
            oni.x                        = x;
            oni.y                        = y;
            oni.z                        = z;
    
            if ( oni.x < G.POP_X_MIN ) oni.x            = G.POP_X_MIN;
            else if ( G.POP_X_MAX < oni.x ) oni.x        = G.POP_X_MAX;
        }
        
        private function popTOni( x:Number, y:Number, z:Number, lv:int ):void
        {
            if ( lv < G.POP_LV_MIN )        lv    = G.POP_LV_MIN;
            else if ( G.POP_LV_MAX < lv )    lv    = G.POP_LV_MAX;
            
            var shadow:Shadow            = new Shadow();
            _shadow_container.addChild( shadow );
            var oni:Oni                    = new TamaOni( lv, shadow );
            _mobs.push( oni );
            _mob_container.addChild( oni );
            oni.x                        = x;
            oni.y                        = y;
            oni.z                        = z;
    
            if ( oni.x < G.POP_X_MIN ) oni.x            = G.POP_X_MIN;
            else if ( G.POP_X_MAX < oni.x ) oni.x        = G.POP_X_MAX;
        }
        
        private function popMOni( x:Number, y:Number, z:Number, lv:int ):void
        {
            if ( lv < G.POP_LV_MIN )        lv    = G.POP_LV_MIN;
            else if ( G.POP_LV_MAX < lv )    lv    = G.POP_LV_MAX;
            
            var shadow:Shadow            = new Shadow();
            _shadow_container.addChild( shadow );
            var oni:Oni                    = new MissileOni( lv, shadow );
            _mobs.push( oni );
            _mob_container.addChild( oni );
            oni.x                        = x;
            oni.y                        = y;
            oni.z                        = z;
    
            if ( oni.x < G.POP_X_MIN ) oni.x            = G.POP_X_MIN;
            else if ( G.POP_X_MAX < oni.x ) oni.x        = G.POP_X_MAX;
        }
        
        private function popOniTank( x:Number, y:Number, z:Number, lv:int ):void
        {
            if ( lv < G.POP_LV_MIN )        lv    = G.POP_LV_MIN;
            else if ( G.POP_LV_MAX < lv )    lv    = G.POP_LV_MAX;
            
            var shadow:Shadow            = new Shadow();
            _shadow_container.addChild( shadow );
            var oni:Oni                    = new OniTank( lv, shadow );
            _mobs.push( oni );
            _mob_container.addChild( oni );
            oni.x                        = x;
            oni.y                        = y;
            oni.z                        = z;
        }
        
        private function popLOni( x:Number, y:Number, z:Number, lv:int ):void
        {
            if ( lv < G.POP_LV_MIN )        lv    = G.POP_LV_MIN;
            else if ( G.POP_LV_MAX < lv )    lv    = G.POP_LV_MAX;
            
            var shadow:Shadow            = new Shadow();
            _shadow_container.addChild( shadow );
            var oni:Oni                    = new LastOni( lv, shadow );
            _mobs.push( oni );
            _mob_container.addChild( oni );
            oni.x                        = x;
            oni.y                        = y;
            oni.z                        = z;
        }
        
        private function onMouseDownStage( e:MouseEvent ):void 
        {
            shot( e.stageX, e.stageY );
        }
        
        private function onMouseUpStage( e:MouseEvent ):void 
        {
            _player.shot                    = false;
        }
    }
}


import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.GradientType;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.GlowFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Vector3D;
import flash.text.TextField;

/**********************************************
 * Configure
**********************************************/
class G
{
    public static const STAGE_WIDTH:Number            = 465;
    public static const STAGE_HEIGHT:Number            = 465;
    public static const STAGE_FOCAL:Number            = -100;
    
    public static const SCORE_COMBO_RATE:int        = 1;
    public static const COMBO_KEEP_TIME:int            = 60;
    
    public static const POP_X_MIN:Number            = 75;
    public static const POP_X_MAX:Number            = STAGE_WIDTH - 75;
    public static const POP_Y_DEFAULT:Number        = 0;
    public static const POP_Z_DEFAULT:Number        = 500;
    public static const POP_LV_MIN:int                = 1;
    public static const POP_LV_MAX:int                = 3;
    public static const POP_TANK_X:Number            = STAGE_WIDTH * 2;
    public static const POP_TANK_Y:Number            = STAGE_HEIGHT;
    public static const POP_T_X:Number                = STAGE_WIDTH / 2 - 25;
    public static const POP_T_Y:Number                = STAGE_HEIGHT - 147;
    public static const POP_M_X:Number                = STAGE_WIDTH / 2 + 57;
    public static const POP_M_Y:Number                = STAGE_HEIGHT - 147;
    public static const POP_L_X:Number                = STAGE_WIDTH / 2;
    public static const POP_L_Y:Number                = STAGE_HEIGHT;
    
    public static const MAME_HIT_RANGE:Number        = 40;
    public static const MAME_GUN_MAX:int            = 12;
    public static const MAME_SHOT_MAX:int            = 24;
    public static const MAME_GATLING_MAX:int        = 48;
    public static const MAME_CANNON_MAX:int            = 60;
    
    public static const LVUP_SCORE_1:int            = 800;
    public static const LVUP_SCORE_2:int            = 2500;
    public static const LVUP_SCORE_3:int            = 7500;
}

/**********************************************
 * HeartMark
**********************************************/
class Heart extends Sprite
{
    private const SIZE:Number        = 16;
    
    public function Heart()
    {
        fill();
    }
    
    public function fill():void
    {
        var m:Matrix                = new Matrix();
        m.createGradientBox( SIZE, SIZE, 0, -4, -14 );
        
        graphics.clear();
        graphics.lineStyle( 2 );
        graphics.beginGradientFill( GradientType.RADIAL, [ 0xffcccc, 0xff0000 ], [ 1, 1 ], [ 0, 255 ], m );
        
        graphics.moveTo( 0, -SIZE * 7 / 20 );
        graphics.curveTo( -SIZE * 11 / 20, -SIZE * 15 / 20, -SIZE * 15 / 20, -SIZE * 6 / 20 );
        graphics.curveTo( -SIZE, SIZE * 6 / 20, 0, SIZE * 15 / 20 );
        graphics.curveTo( SIZE, SIZE * 6 / 20, SIZE * 15 / 20, -SIZE * 6 / 20 );
        graphics.curveTo( SIZE * 11 / 20, -SIZE * 15 / 20, 0, -SIZE * 7 / 20 );
        
        graphics.endFill();
    }
    
    public function blank():void
    {
        graphics.clear();
        graphics.lineStyle( 2 );
        
        graphics.moveTo( 0, -SIZE * 7 / 20 );
        graphics.curveTo( -SIZE * 11 / 20, -SIZE * 15 / 20, -SIZE * 15 / 20, -SIZE * 6 / 20 );
        graphics.curveTo( -SIZE, SIZE * 6 / 20, 0, SIZE * 15 / 20 );
        graphics.curveTo( SIZE, SIZE * 6 / 20, SIZE * 15 / 20, -SIZE * 6 / 20 );
        graphics.curveTo( SIZE * 11 / 20, -SIZE * 15 / 20, 0, -SIZE * 7 / 20 );
    }
}

/**********************************************
 * Shadow
**********************************************/
class Shadow extends Sprite
{
    public function Shadow()
    {
        rotationX                            = -90;
    }
    
    public function create( size:Number ):void
    {
        graphics.beginFill( 0x0, 0.5 );
        graphics.drawCircle( 0, -size, size );
        graphics.endFill();
    }
}

/**********************************************
 * Player Information
**********************************************/
class Player
{
    private var _score:int;
    private var _life:int;
    private var _weapon:int;
    
    private var _shot:Boolean;
    
    private var _combo:int;
    private var _combo_keep_time:int;
    
    private var _clear:Boolean;
    
    public function get score():int { return _score; }
    public function set score(value:int):void { _score = value; }
    public function get life():int { return _life; }
    public function set life(value:int):void { _life = value; }
    public function get weapon():int { return _weapon; }
    public function set weapon(value:int):void { _weapon = value; }
    
    public function get shot():Boolean { return _shot; }
    public function set shot(value:Boolean):void { _shot = value; }
    
    public function get combo():int { return _combo; }
    public function set combo(value:int):void { if ( _combo < value ) _combo_keep_time = G.COMBO_KEEP_TIME; _combo = value; }
    public function comboUpdate():void { _combo_keep_time--; if ( _combo_keep_time < 0 ) { _combo_keep_time = 0; _combo = 0; } }
    
    public function get clear():Boolean { return _clear; }    
    public function set clear(value:Boolean):void { _clear = value; }
        
    public function Player()
    {
        _score                                = 0;
        _life                                = 3;
        _weapon                                = 0;
        _shot                                = false;
        _combo                                = 0;
        _clear                                = false;
    }
}

/**********************************************
 * Menu
**********************************************/
class Menu extends Sprite
{
    private var _weapon:TextField;
    private var _score:TextField;
    private var _lvup:TextField;
    private var _bonus:TextField;
    private var _combo:TextField;
    private var _life:Vector.<Heart>;
    private var _gameover:TextField;
    private var _gameclear:TextField;
    
    private var _weapon_name:Array            = [ "Mame", "Shot-Mame", "Gatling-Mame", "Mame-Cannon" ];
    
    public function Menu( score:int, life:int, weapon:int, combo:int )
    {
        _weapon                                = new TextField();
        _weapon.textColor                    = 0xffffff;
        _weapon.selectable                    = false;
        _weapon.scaleX = _weapon.scaleY        = 2;
        _weapon.width                        = 210;
        _weapon.x                            = G.STAGE_WIDTH - 210;
        _weapon.y                            = G.STAGE_HEIGHT - 32;
        _weapon.text                        = "Arm: " + _weapon_name[weapon];
        addChild( _weapon );

        _score                                = new TextField();
        _score.textColor                    = 0xffffff;
        _score.selectable                    = false;
        _score.scaleX = _score.scaleY        = 2;
        _score.x                            = 0;
        _score.y                            = 0;
        _score.text                            = "Score: " + score;
        addChild( _score );

        _lvup                                = new TextField();
        _lvup.textColor                        = 0xffff00;
        _lvup.selectable                    = false;
        _lvup.scaleX = _lvup.scaleY            = 2;
        _lvup.x                                = G.STAGE_WIDTH - 200;
        _lvup.y                                = G.STAGE_HEIGHT - 100;
        _lvup.text                            = "Level UP!";
        _lvup.visible                        = false;
        _lvup.filters                        = [ new GlowFilter( 0xffffff ) ];
        addChild( _lvup );

        _bonus                                = new TextField();
        _bonus.textColor                    = 0xffff00;
        _bonus.selectable                    = false;
        _bonus.scaleX = _bonus.scaleY        = 2;
        _bonus.x                            = G.STAGE_WIDTH - 200;
        _bonus.y                            = G.STAGE_HEIGHT - 200;
        _bonus.text                            = "BONUS !!";
        _bonus.visible                        = false;
        _bonus.filters                        = [ new GlowFilter( 0xffffff ) ];
        addChild( _bonus );

        _combo                                = new TextField();
        _combo.textColor                    = 0xffff00;
        _combo.selectable                    = false;
        _combo.scaleX = _combo.scaleY        = 2;
        _combo.x                            = G.STAGE_WIDTH - 100;
        _combo.y                            = 100;
        _combo.text                            = "";
        _combo.visible                        = false;
        _combo.filters                        = [ new GlowFilter( 0xffffff ) ];
        addChild( _combo );

        _life                                = new Vector.<Heart>();
        for ( var i:int = 0; i < life; ++i )
        {
            var heart:Heart                    = new Heart();
            heart.x                            = 20 + i * 31;
            heart.y                            = G.STAGE_HEIGHT - 17;
            addChild( heart );
            _life.push( heart );
        }

        _gameover                            = new TextField();
        _gameover.textColor                    = 0xffffff;
        _gameover.selectable                = false;
        _gameover.scaleX = _gameover.scaleY    = 5;
        _gameover.x                            = G.STAGE_WIDTH / 2 - 188;
        _gameover.y                            = G.STAGE_HEIGHT / 2 - 82;
        _gameover.text                        = "GAME OVER";
        _gameover.visible                    = false;
        _gameover.filters                    = [ new GlowFilter( 0x000000 ) ];
        addChild( _gameover );

        _gameclear                            = new TextField();
        _gameclear.textColor                = 0xffff00;
        _gameclear.selectable                = false;
        _gameclear.scaleX = _gameclear.scaleY    = 5;
        _gameclear.x                        = G.STAGE_WIDTH / 2 - 144;
        _gameclear.y                        = G.STAGE_HEIGHT / 2 - 82;
        _gameclear.text                        = "You Win!!";
        _gameclear.visible                    = false;
        _gameclear.filters                    = [ new GlowFilter( 0xffffff ) ];
        addChild( _gameclear );
    }
    
    public function setWeapon( value:int ):void
    {
        _weapon.text                        = "Arm: " + _weapon_name[value];
    }
    
    public function setScore( value:int ):void
    {
        _score.text                            = "Score: " + value;
    }
    
    public function setCombo( value:int ):void
    {
        if ( 0 < value )
        {
            _combo.text                            = value + "Combo";
            _combo.visible                        = true;
        }
        else
        {
            _combo.text                            = "";
            _combo.visible                        = false;                
        }
    }
    
    public function setLife( value:int ):void
    {
        for ( var i:int = 0; i < _life.length; ++i )
        {
            if ( i < value )
            {
                _life[i].fill();
            }
            else
            {
                _life[i].blank();
            }
        }
    }
    
    public function setLvup():void
    {
        _lvup.visible                        = true;
        _lvup.x                                = G.STAGE_WIDTH;
        
        _lvup.addEventListener( Event.ENTER_FRAME, updateLvup );
    }
    
    public function setBonus():void
    {
        _bonus.visible                        = true;
        _bonus.x                            = G.STAGE_WIDTH;
        
        _bonus.addEventListener( Event.ENTER_FRAME, updateBonus );
    }
    
    public function gameOver():void
    {
        _gameover.visible                    = true;
    }
    
    public function gameClear():void
    {
        _gameclear.visible                    = true;
    }
    
    private function updateLvup( e:Event ):void 
    {
        if ( Math.abs ( _lvup.x - G.STAGE_WIDTH / 2 + 100 ) < 50 )
        {
            _lvup.x                            -= 2;
        }
        else
        {
            _lvup.x                            -= 20;
        }
        
        if ( _lvup.x < -100 )
        {
            _lvup.visible                    = false;
            _lvup.removeEventListener( Event.ENTER_FRAME, updateLvup );
        }
    }
    
    private function updateBonus( e:Event ):void 
    {
        if ( Math.abs ( _bonus.x - G.STAGE_WIDTH / 2 + 100 ) < 50 )
        {
            _bonus.x                            -= 2;
        }
        else
        {
            _bonus.x                            -= 20;
        }
        
        if ( _bonus.x < -100 )
        {
            _bonus.visible                    = false;
            _bonus.removeEventListener( Event.ENTER_FRAME, updateBonus );
        }
    }
}

/**********************************************
 * Effect Field
**********************************************/
class EffectField extends Sprite
{
    private var _bitmap:Bitmap;
    private var _noise:BitmapData;
    
    public function EffectField()
    {
        _noise                        = new BitmapData( 465, 465, true, 0x0 );
        _noise.perlinNoise( _noise.rect.width, _noise.rect.height, 10, Math.floor( Math.random() * 10000 ), true, true, BitmapDataChannel.RED | BitmapDataChannel.GREEN | BitmapDataChannel.BLUE | BitmapDataChannel.ALPHA );
        
        _bitmap                        = new Bitmap();
        addChild( _bitmap );

        addEventListener( Event.ENTER_FRAME, update );
    }
    
    public function setRed():void
    {
        _bitmap.bitmapData = _noise.clone();
        _bitmap.bitmapData.colorTransform( _bitmap.bitmapData.rect, new ColorTransform( 1, 0, 0, 1 ) );
    }
    
    public function setBlack():void
    {
        _bitmap.bitmapData = _noise.clone();
        _bitmap.bitmapData.colorTransform( _bitmap.bitmapData.rect, new ColorTransform( 0, 0, 0, 1 ) );
    }
    
    private function update( e:Event ):void 
    {
        if ( _bitmap.bitmapData )
        {
            _bitmap.bitmapData.colorTransform( _bitmap.bitmapData.rect, new ColorTransform( 1, 1, 1, 0.8 ) );
        }
    }
}

/**********************************************
 * BackGround
**********************************************/
class BackGround extends Sprite
{
    private const MOON_SIZE:Number            = 100;
    private const GROUND_WIDTH:Number        = 600;
    private const DEPTH_MAX:Number            = 1000;
    
    private var _night:Sprite;
    private var _moon:Sprite;
    private var _mountain1:Sprite;
    private var _mountain2:Sprite;
    private var _ground:Sprite;
    private var _target:Sprite;
    
    public function BackGround()
    {
        var mn:Matrix                        = new Matrix();
        mn.createGradientBox( G.STAGE_WIDTH, G.STAGE_HEIGHT, 90 * Math.PI / 180, 0, 0 );

        _night                                = new Sprite();
        _night.graphics.beginGradientFill( GradientType.LINEAR, [ 0x4444cc, 0x000022 ], [ 1, 1 ], [ 0, 255 ], mn );
        _night.graphics.drawRect( 0, 0, G.STAGE_WIDTH, G.STAGE_HEIGHT );
        _night.graphics.endFill();
        addChild( _night );
        
        _moon                                = new Sprite();
        _moon.graphics.beginFill( 0xffff00 );
        _moon.graphics.drawCircle( 0, 0, MOON_SIZE );
        _moon.graphics.endFill();
        _moon.x                                = 100;
        _moon.y                                = -200;
        _moon.z                                = DEPTH_MAX - 1;
        addChild( _moon );
        
        var mm:Matrix                        = new Matrix();
        mm.createGradientBox( G.STAGE_WIDTH, G.STAGE_HEIGHT, 60 * Math.PI / 180, 0, -G.STAGE_HEIGHT );
        
        _mountain1                            = new Sprite();
        _mountain1.graphics.beginGradientFill( GradientType.LINEAR, [ 0x008800, 0x114411 ], [ 1, 1 ], [ 0, 255 ], mm );
        _mountain1.graphics.moveTo( 0, 0 );
        _mountain1.graphics.curveTo( 200, -700, 600, 0 );
        _mountain1.graphics.endFill();
        _mountain1.x                        = G.STAGE_WIDTH + GROUND_WIDTH / 2 - 600;
        _mountain1.y                        = G.STAGE_HEIGHT;
        _mountain1.z                        = DEPTH_MAX;
        addChild( _mountain1 );
        
        _mountain2                            = new Sprite();
        _mountain2.graphics.beginGradientFill( GradientType.LINEAR, [ 0x008800, 0x114411 ], [ 1, 1 ], [ 0, 255 ], mm );
        _mountain2.graphics.moveTo( 0, 0 );
        _mountain2.graphics.curveTo( 600, -600, 800, 0 );
        _mountain2.graphics.endFill();
        _mountain2.x                        = -GROUND_WIDTH / 2;
        _mountain2.y                        = G.STAGE_HEIGHT;
        _mountain2.z                        = DEPTH_MAX;
        addChild( _mountain2 );
        
        var mg:Matrix                        = new Matrix();
        mg.createGradientBox( G.STAGE_WIDTH, G.STAGE_HEIGHT, 90 * Math.PI / 180, 0, 0 );
        
        _ground                                = new Sprite();
        _ground.graphics.beginGradientFill( GradientType.LINEAR, [ 0x804000, 0x402000 ], [ 1, 1 ], [ 0, 255 ], mg );
        _ground.graphics.drawRect( -GROUND_WIDTH/2, 0, G.STAGE_WIDTH + GROUND_WIDTH, 1000 );
        _ground.graphics.endFill();
        _ground.y                            = G.STAGE_HEIGHT;
        _ground.rotationX                    = 90;
        addChild( _ground );
        
        _target                                = new Sprite();
        _target.graphics.beginFill( 0xffff88, 0.75 );
        _target.graphics.moveTo( -10, 0 );
        _target.graphics.lineTo( 0, -220 );
        _target.graphics.lineTo( 10, 0 );
        _target.graphics.endFill();
        _target.y                            = G.STAGE_HEIGHT;
        _target.rotationX                    = -90;
        addChild( _target );
        
    }
    
    public function setTargetPosition( x:Number ):void
    {
        _target.x                            = x;
    }
}

/**********************************************
 * Mob Base
**********************************************/
class MobObject extends Sprite
{
    protected const GROUND_HEIGHT:int        = 400;
    protected const FADE_RATE:Number        = 0.03;
    
    protected var _shadow:Shadow;
    protected var _gravity:Number;
    protected var _anti_gravity:Boolean;
    
    protected var _v:Vector3D;
    
    public function get shadow():Shadow { return _shadow; }
    
    public function MobObject( shadow:Shadow, shadow_size:int, gravity:Number )
    {
        _shadow                                = shadow;        
        _shadow.create( shadow_size );
        _gravity                            = gravity;
        _anti_gravity                        = false;
        _v                                    = new Vector3D();
    }
    
    public final function update():void
    {
        if ( !_anti_gravity )
        {
            _v.y                                += _gravity;
        }
        
        if ( isFading() )
        {
            alpha                            -= FADE_RATE;
            _shadow.alpha                    -= FADE_RATE / 2;

            y                                += _v.y;
        }
        else
        {
            x                                += _v.x;
            y                                += _v.y;
            z                                += _v.z;
            
            action();
        }

        if ( GROUND_HEIGHT < y )
        {
            y                                = GROUND_HEIGHT;
        }
        
        _shadow.scaleX = _shadow.scaleY        = 1 - ( GROUND_HEIGHT - y ) / 1000;
        _shadow.x                            = x;
        _shadow.y                            = GROUND_HEIGHT;
        _shadow.z                            = z;
    }

    public final function isRemovable():Boolean
    {
        return ( alpha < 0 ) ? true : false;
    }
    
    protected function action():void { }
    protected function isFading():Boolean { return true; }
    public function isHittable():Boolean { return false; }
    public function hit( damage:int = 0, side:Number = 0 ):int { return 0; }
    public function isComboEnable():Boolean { return false; }
    public function combo():int { return 0; }
    public function getDamage():int { return 0; }
    public function getCombo():Number { return 0; }
    public function isSpawnTama():Boolean { return false; }
    public function isSpawnMissile():Boolean { return false; }
}

/**********************************************
 * Mame
**********************************************/
class Mame extends MobObject
{
    private const GRAVITY:Number            = 0.5;
    private const INACCURACY_RATE:Number    = 4;
    private const LAUNCH:Number                = -5;
    private const SIZE_DEFAULT:Number        = 8;
    private const DAMAGE_DEFAULT:int        = 1;
    private const SPEED_RATE:Number            = 8;
    
    private var _vr:Number;
    
    private var _lv:int;
    private var _damage:int;
    
    private var _is_hittable:Boolean;
    
    public function Mame( shadow:Shadow, target_x:Number, target_y:Number, lv:int )
    {
        var size:Number                        = ( lv == 3 ) ? SIZE_DEFAULT * 10 : SIZE_DEFAULT;
        _damage                                = ( lv == 3 ) ? DAMAGE_DEFAULT * 50 : DAMAGE_DEFAULT;
        var speed:Number                    = ( lv < 2 ) ? SPEED_RATE + SPEED_RATE / 2 : SPEED_RATE * 2;
        _lv                                    = lv;
        
        super( shadow, size / 2, GRAVITY );
        
        graphics.beginFill( ( Math.random() < 0.5 ) ? 0xf0f0a0 : 0xc0c080 );
        graphics.drawEllipse( -size * 3 / 8, -size * 3 / 4, size * 3 / 4, size );
        graphics.endFill();
        
        _vr                                    = -25 + Math.random() * 50;
        
        x                                    = target_x;
        y                                    = target_y;
        z                                    = -100;

        _v.x                                = - INACCURACY_RATE / 2 +  Math.random() * INACCURACY_RATE;
        _v.y                                = LAUNCH - INACCURACY_RATE / 2 +  Math.random() * INACCURACY_RATE;
        _v.z                                = speed;
        
        _is_hittable                        = true;
    }
    
    protected override function action():void 
    {
        rotationZ                            += _vr;
    }
    
    protected override function isFading():Boolean
    {
        return ( GROUND_HEIGHT <= y ) ? true : false;
    }
    
    public override function isHittable():Boolean
    {
        return !isFading() && _is_hittable;
    }
    
    public override function hit( damage:int = 0, side:Number = 0 ):int
    {
        if ( _lv != 3 )
        {
            _v.z                                = -1;
            _v.x                                += -5 + Math.random() * 10;
            _v.y                                += -1 + Math.random() * 2;        
            
            _is_hittable                        = false;
        }
            
        return _damage;
    }
}

/**********************************************
 * Oni Base
**********************************************/
class Oni extends MobObject
{
    protected const GRAVITY:int                    = 5;
    protected const FALL_RATE:Number            = 10;
    protected const STAGGER_ROTATE:Number        = 30;
    protected const STAGGER_ROTATE_MAX:Number    = 30;
    protected const STAGGER_BRAKE:Number        = 0.8;
    
    protected const PHASE_POP:int            = 0;
    protected const PHASE_SETUP:int            = 1;
    protected const PHASE_MOVE:int            = 2;
    protected const PHASE_PREATTACK:int        = 3;
    protected const PHASE_ATTACK:int        = 4;
    protected const PHASE_ATTACKEND:int        = 5;
    
    protected var _phase:int;
    protected var _step:int;
    protected var _life:int;
    protected var _invul:Boolean;
    protected var _invul_combo:Boolean;
    protected var _end:Boolean;
    protected var _kill_score:int;
    protected var _hit_score:int;
    protected var _stagger_count:int;
    protected var _stagger_rate:Number;
    
    protected var _size:Number;
    
    protected var _phase_function:Array        = [ phasePop, phaseSetup, phaseMove, phasePreAttack, phaseAttack, phaseAttackEnd ];
    
    public function Oni( shadow:Shadow, size:Number, life:int )
    {
        super( shadow, size, GRAVITY );
        
        _phase                                = 0;
        _life                                = life;
        _invul                                = false;
        _size                                = size;
        _stagger_rate                        = 1;
    }
    
    protected override function action():void 
    {
        if ( _life <= 0 )
        {
            rotationX                        -= FALL_RATE;
            rotationY                        = 0;
            _v.x                            = 0;
            _v.z                            = 0;
        }
        else
        {
            rotationY                            *= STAGGER_BRAKE;
            
            _phase_function[_phase]();
            nophaseAction();
        }
        
        if ( x < G.POP_X_MIN ) x                = G.POP_X_MIN;
        else if ( G.POP_X_MAX < x ) x            = G.POP_X_MAX;
    }
    
    protected override function isFading():Boolean
    {
        return ( _life <= 0 && rotationX <= -90 ) || _end;
    }
    
    public override function isHittable():Boolean
    {
        return ( 0 < _life ) && !_invul;
    }
    
    public override function hit( damage:int = 0, side:Number = 0 ):int
    {
        _life                                -= damage;

        if ( 0 < side && -STAGGER_ROTATE_MAX < rotationY )
        {
            rotationY                        += STAGGER_ROTATE * _stagger_rate;
        }
        else if ( side < 0 && rotationY < STAGGER_ROTATE_MAX )
        {
            rotationY                        -= STAGGER_ROTATE * _stagger_rate;
        }
        
        if ( _life <= 0 )
        {
            _anti_gravity                    = false;
            
            return _kill_score;
        }

        return _hit_score;
    }
    
    public override function isComboEnable():Boolean
    {
        return ( 0 < _life ) && !_invul && !_invul_combo;
    }
    
    public override function combo():int
    {
        _life -= 100;
        
        if ( _life < 0 )
        {
            _anti_gravity                    = false;
            
            return _kill_score;
        }
        
        return 0;
    }
    
    public override function getCombo():Number
    {
        if ( 0 < _life || rotationX < -80 || -45 < rotationX )
        {
            return 0;
        }
        
        var range:Number        = _size * Math.sin( 45 );
        
        return range;
    }
    
    protected function nophaseAction():void { }
    protected function phasePop():void { _phase++; }
    protected function phaseSetup():void { _phase++; }
    protected function phaseMove():void { _phase++; }
    protected function phasePreAttack():void { _phase++; }
    protected function phaseAttack():void
    {
        if ( z < 0 )
        {
            _v.x                                = 0;
            _v.y                                = 0;
            _v.z                                = 0;
            _invul                                = true;
        }
    }
    protected function phaseAttackEnd():void { _end = true; _v.x = 0; _v.y = 0; _v.z = 0; _anti_gravity = true; }
    
    public override function getDamage():int
    {
        if ( _phase == PHASE_ATTACK && _invul )
        {
            _phase++;
            return 1;
        }
        
        return 0;
    }
}

/**********************************************
 * Red-Oni
**********************************************/
class RedOni extends Oni
{
    private const SIZE_RATE:Number            = 40;
    private const LIFE_RATE:Number            = 4;
    private const HSCORE_RATE:int            = 1;
    private const KSCORE_RATE:int            = 10;
    private const ATTACK_RANGE:Number        = 100;
    private const COLOR:uint                = 0xff3333;
        
    private const SPEED:Number                = 1;
    
    public function RedOni( lv:int, shadow:Shadow )
    {
        var size:Number                        = SIZE_RATE + ( lv - 1 ) * SIZE_RATE / 2;
        var life:int                        = LIFE_RATE + ( lv - 1 ) * LIFE_RATE * 4;
        _hit_score                            = HSCORE_RATE + ( lv - 1 ) * HSCORE_RATE;
        _kill_score                            = KSCORE_RATE + ( lv - 1 ) * KSCORE_RATE;
                
        super( shadow, size, life );
        
        graphics.lineStyle( 1 );
        graphics.beginFill( COLOR );
        graphics.drawCircle( 0, -_size, _size );
        graphics.endFill();
    }
    
    protected override function phasePop():void
    {
        if ( GROUND_HEIGHT <= y )
        {
            _phase++;
        }
    }
    
    protected override function phaseSetup():void
    {
        switch( _step )
        {
        case 0:
        case 1:
        case 2:
            break;
            
        case 3:
        case 4:
        case 5:
        case 6:
            graphics.clear();
            graphics.lineStyle( 1 );
            for ( var i:int = _step; 3 <= i; --i )
            {
                graphics.beginFill( 0xffffff );
                graphics.moveTo( -_size / 4, -_size * 3 / 2 );
                graphics.curveTo( -_size / 2, -_size * 3 / 2 -_size * i * 3 / 10, -_size * 3 / 4, -_size * 3 / 2 );
                graphics.endFill();
                graphics.beginFill( 0xffffff );
                graphics.moveTo( _size / 4, -_size * 3 / 2 );
                graphics.curveTo( _size / 2, -_size * 3 / 2 -_size * i * 3 / 10, _size * 3 / 4, -_size * 3 / 2 );
                graphics.endFill();
            }
            graphics.beginFill( COLOR );
            graphics.drawCircle( 0, -_size, _size );
            graphics.endFill();
            break;
        
        case 7:
            graphics.lineStyle( _size / 10, 0xffffff );
            graphics.beginFill( 0x0 );
            graphics.drawCircle( -_size / 2, -_size * 7 / 6, _size / 10 );
            graphics.endFill();
            break;
        
        case 8:
            graphics.beginFill( 0x0 );
            graphics.drawCircle( _size / 2, -_size * 7 / 6, _size / 10 );
            graphics.endFill();
            break;
        
        case 9:
            graphics.lineStyle( 1 );
            graphics.beginFill( 0xffffff );
            graphics.moveTo( -_size / 2, -_size * 3 / 4 );
            graphics.curveTo( 0, 0, _size / 2, -_size * 3 / 4 );
            graphics.endFill();
            break;
        
        default:
            _v.z                            = -SPEED;
            _phase++;
            _step                            = 0;
            break;
        }
        
        _step++;
    }
    
    protected override function phaseMove():void
    {
        if ( z < ATTACK_RANGE )
        {
            _v.z                                = 0;
            _phase++;
        }
    }
    
    protected override function phasePreAttack():void
    {
        if ( z < ATTACK_RANGE )
        {
            _v.x                                = 0;
            _v.y                                = -30 - Math.random() * 20;
            _v.z                                = -10;
            _phase++;
        }
    }
}

/**********************************************
 * Blue-Oni
**********************************************/
class BlueOni extends Oni
{
    private const SIZE_RATE:Number            = 30;
    private const LIFE_RATE:Number            = 2;
    private const HSCORE_RATE:int            = 2;
    private const KSCORE_RATE:int            = 20;
    private const ATTACK_RANGE:Number        = 100;
    private const COLOR:uint                = 0x3333ff;
    
    private const SPEED:Number                = 1.5
        
    private var _ay:Number;
    
    public function BlueOni( lv:int, shadow:Shadow )
    {
        var size:Number                        = SIZE_RATE - ( lv - 1 ) * SIZE_RATE / 4;
        var life:int                        = LIFE_RATE + ( lv - 1 ) * LIFE_RATE;
        _hit_score                            = HSCORE_RATE + ( lv - 1 ) * HSCORE_RATE;
        _kill_score                            = KSCORE_RATE + ( lv - 1 ) * KSCORE_RATE;
        
        super( shadow, size, life );
        
        graphics.lineStyle( 1 );
        graphics.beginFill( COLOR );
        graphics.drawCircle( 0, -_size, _size );
        graphics.endFill();
    }
    
    protected override function phasePop():void
    {
        if ( GROUND_HEIGHT / 4 <= y
        &&     Math.random() < 0.2 )
        {
            _anti_gravity                        = true;
            _v.y                                = 0;
            _phase++;
        }
        else if ( GROUND_HEIGHT * 3 / 4 <= y )
        {
            _anti_gravity                        = true;
            _v.y                                = 0;
            _phase++;
        }
    }
    
    protected override function phaseSetup():void
    {
        switch( _step )
        {
        case 0:
        case 1:
            graphics.clear();
            graphics.lineStyle( 1 );
            graphics.beginFill( COLOR );
            graphics.moveTo( 0, -_size );
            graphics.lineTo( -_size, -_size * 2 );
            graphics.lineTo( -_size * 2, -_size );
            graphics.curveTo( -_size, -_size * 2, 0, -_size );
            graphics.lineTo( _size, -_size * 2 );
            graphics.lineTo( _size * 2, -_size );
            graphics.curveTo( _size, -_size * 2, 0, -_size );
            graphics.endFill();
            graphics.beginFill( COLOR );
            graphics.drawCircle( 0, -_size, _size );
            graphics.endFill();
        case 2:
            break;
            
        case 3:
        case 4:
        case 5:
        case 6:
            graphics.clear();
            graphics.lineStyle( 1 );
            for ( var i:int = _step; 3 <= i; --i )
            {
                graphics.beginFill( 0xffffff );
                graphics.moveTo( -_size / 4, -_size * 3 / 2 );
                graphics.curveTo( -_size / 2, -_size * 3 / 2 -_size * i * 3 / 10, -_size * 3 / 4, -_size * 3 / 2 );
                graphics.endFill();
                graphics.beginFill( 0xffffff );
                graphics.moveTo( _size / 4, -_size * 3 / 2 );
                graphics.curveTo( _size / 2, -_size * 3 / 2 -_size * i * 3 / 10, _size * 3 / 4, -_size * 3 / 2 );
                graphics.endFill();
            }
            graphics.beginFill( COLOR );
            graphics.moveTo( 0, -_size );
            graphics.lineTo( -_size, -_size * 2 );
            graphics.lineTo( -_size * 2, -_size );
            graphics.curveTo( -_size, -_size * 2, 0, -_size );
            graphics.lineTo( _size, -_size * 2 );
            graphics.lineTo( _size * 2, -_size );
            graphics.curveTo( _size, -_size * 2, 0, -_size );
            graphics.endFill();
            graphics.beginFill( COLOR );
            graphics.drawCircle( 0, -_size, _size );
            graphics.endFill();
            break;
        
        case 7:
            graphics.beginFill( 0x0 );
            graphics.drawCircle( -_size / 2, -_size * 7 / 6, _size / 10 );
            graphics.endFill();
            break;
        
        case 8:
            graphics.beginFill( 0x0 );
            graphics.drawCircle( _size / 2, -_size * 7 / 6, _size / 10 );
            graphics.endFill();
            break;
        
        case 9:
            graphics.lineStyle( 1 );
            graphics.beginFill( 0xffffff );
            graphics.moveTo( -_size / 4, -_size * 3 / 4 );
            graphics.lineTo( 0, -_size / 2 );
            graphics.lineTo( _size / 4, -_size * 3 / 4 );
            graphics.endFill();
            break;
            
        default:
            _v.z                            = -SPEED;
            _ay                                = 1;
            _phase++;
            _step                            = 0;
            break;
        }
        
        _step++;
    }
    
    protected override function phaseMove():void
    {
        if ( 0 < _life )
        {
            _v.y                                += _ay;
            
            if ( 5 < _v.y ) _ay = -1;
            else if ( _v.y < -5 ) _ay = 1;
        }
        
        if ( z < ATTACK_RANGE )
        {
            _v.z                                = 0;
            _phase++;
        }
    }
    
    protected override function phasePreAttack():void
    {
        if ( z < ATTACK_RANGE )
        {
            _v.x                                = 0;
            _v.y                                = ( G.STAGE_HEIGHT / 2 < y ) ? -Math.random() * 10 : Math.random() * 10;
            _v.z                                = -10;
            
            _phase++;
        }
    }
}

/**********************************************
 * Green-Oni
**********************************************/
class GreenOni extends Oni
{
    private const SIZE_RATE:Number            = 25;
    private const LIFE_RATE:Number            = 3;
    private const HSCORE_RATE:int            = 3;
    private const KSCORE_RATE:int            = 30;
    private const ATTACK_RANGE:Number        = 100;
    private const COLOR:uint                = 0x33aa33;
    
    private const SLIDE_SPEED_RATE:Number    = 15;
    private const SLIDE_BRAKE:Number        = 0.8;
    private const SLIDE_REVERSE_RANGE:Number    = 5;
    private const SLIDE_COUNT_MIN:int        = 15;
    private const SLIDE_COUNT_MAX:int        = 60;    
    private const SPEED_RATE:Number            = 2;
    
    private var _slide_speed:Number;
    private var _slide_count:int;
    private var _speed:Number;
    
    public function GreenOni( lv:int, shadow:Shadow )
    {
        var size:Number                        = SIZE_RATE;
        var life:int                        = LIFE_RATE + ( lv - 1 ) * LIFE_RATE;
        _hit_score                            = HSCORE_RATE + ( lv - 1 ) * HSCORE_RATE;
        _kill_score                            = KSCORE_RATE + ( lv - 1 ) * KSCORE_RATE;
        _slide_speed                        = SLIDE_SPEED_RATE + ( lv - 1 ) * SLIDE_SPEED_RATE / 2;
        _speed                                = SPEED_RATE + ( lv - 1 ) * SPEED_RATE / 2;
        
        super( shadow, size, life );
        
        graphics.lineStyle( 1 );
        graphics.beginFill( COLOR );
        graphics.drawCircle( 0, -_size, _size );
        graphics.endFill();
    }
    
    protected override function phasePop():void
    {
        if ( GROUND_HEIGHT <= y )
        {
            _phase++;
        }
    }
    
    protected override function phaseSetup():void
    {
        switch( _step )
        {
        case 0:
        case 1:
        case 2:
            break;
            
        case 3:
        case 4:
        case 5:
        case 6:
            graphics.clear();
            graphics.lineStyle( 1 );
            for ( var i:int = _step; 3 <= i; --i )
            {
                graphics.beginFill( 0xffffff );
                graphics.moveTo( -_size / 4, -_size * 3 / 2 );
                graphics.curveTo( -_size / 2, -_size * 3 / 2 -_size * i * 3 / 10, -_size * 3 / 4, -_size * 3 / 2 );
                graphics.endFill();
                graphics.beginFill( 0xffffff );
                graphics.moveTo( _size / 4, -_size * 3 / 2 );
                graphics.curveTo( _size / 2, -_size * 3 / 2 -_size * i * 3 / 10, _size * 3 / 4, -_size * 3 / 2 );
                graphics.endFill();
            }
            graphics.beginFill( COLOR );
            graphics.drawCircle( 0, -_size, _size );
            graphics.endFill();
            break;
        
        case 7:
            graphics.lineStyle( 2 );
            graphics.moveTo( -_size * 3 / 8, -_size * 7 / 6 );
            graphics.lineTo( -_size * 5 / 8, -_size * 7 / 6 );
            break;
        
        case 8:
            graphics.moveTo( _size * 3 / 8, -_size * 7 / 6 );
            graphics.lineTo( _size * 5 / 8, -_size * 7 / 6 );
            break;
        
        case 9:
            graphics.lineStyle( 1 );
            graphics.moveTo( -_size / 4, -_size / 2 );
            graphics.lineTo( 0, -_size * 3 / 4 );
            graphics.lineTo( _size / 4, -_size / 2 );
            break;
        
        default:
            _v.z                            = -_speed;
            _phase++;
            _step                            = 0;
            _slide_count                    = SLIDE_COUNT_MIN + Math.floor( Math.random() * ( SLIDE_COUNT_MAX - SLIDE_COUNT_MIN ) );
            break;
        }
        
        _step++;
    }
    
    protected override function phaseMove():void
    {
        _slide_count--;
        
        if ( _slide_count <= 0 )
        {
            _v.x                                = ( Math.random() < 0.5 ) ? _slide_speed : -_slide_speed;
            _slide_count                        = SLIDE_COUNT_MIN + Math.floor( Math.random() * ( SLIDE_COUNT_MAX - SLIDE_COUNT_MIN ) );

        }
        
        if ( ( x < G.POP_X_MIN + SLIDE_REVERSE_RANGE && _v.x < 0 )
        ||     ( G.POP_X_MAX - SLIDE_REVERSE_RANGE < x && 0 < _v.x ) )
        {
            _v.x                                *= -1;
        }
        
        _v.x                                    *= SLIDE_BRAKE;
        
        if ( z < ATTACK_RANGE )
        {
            _v.z                                = 0;
            _phase++;
        }
    }
    
    protected override function phasePreAttack():void
    {
        if ( z < ATTACK_RANGE )
        {
            _v.x                                = 0;
            _v.y                                = -30 - Math.random() * 20;
            _v.z                                = -10;
            _phase++;
        }
    }
}

/**********************************************
 * Tama-Oni
**********************************************/
class TamaOni extends Oni
{
    private const SIZE_RATE:Number            = 10;
    private const LIFE_RATE:Number            = 1;
    private const HSCORE_RATE:int            = 1;
    private const KSCORE_RATE:int            = 40;
    private const ATTACK_RANGE:Number        = 100;
    private const COLOR:uint                = 0x666666;
        
    private const SPEED:Number                = 15;
    private const ACCURACY:Number            = 2;
    
    public function TamaOni( lv:int, shadow:Shadow )
    {
        var size:Number                        = SIZE_RATE
        var life:int                        = LIFE_RATE;
        _hit_score                            = HSCORE_RATE;
        _kill_score                            = KSCORE_RATE;
                
        super( shadow, size, life );
        
        graphics.lineStyle( 1 );
        graphics.beginFill( 0xffffff );
        graphics.moveTo( -_size / 4, -_size * 3 / 2 );
        graphics.lineTo( 0, -_size * 3 / 2 -_size * 6 * 3 / 10 );
        graphics.lineTo( _size / 4, -_size * 3 / 2 );
        graphics.endFill();
        
        graphics.lineStyle( 1 );
        graphics.beginFill( COLOR );
        graphics.drawCircle( 0, -_size, _size );
        graphics.endFill();
        
        graphics.lineStyle( 1 );
        graphics.moveTo( -_size * 3 / 8, -_size * 6 / 6 );
        graphics.lineTo( -_size * 5 / 8, -_size * 8 / 6 );
        graphics.moveTo( -_size * 5 / 8, -_size * 6 / 6 );
        graphics.lineTo( -_size * 3 / 8, -_size * 8 / 6 );
        graphics.moveTo( _size * 3 / 8, -_size * 6 / 6 );
        graphics.lineTo( _size * 5 / 8, -_size * 8 / 6 );
        graphics.moveTo( _size * 5 / 8, -_size * 6 / 6 );
        graphics.lineTo( _size * 3 / 8, -_size * 8 / 6 );
    }
    
    protected override function phasePop():void
    {
        _anti_gravity                        = true;
        _v.x                                = ACCURACY - Math.random() * ACCURACY * 2;
        _v.z                                = -SPEED;
        _v.y                                = ACCURACY - Math.random() * ACCURACY * 2;
        _phase++;
    }
    
    protected override function phaseMove():void
    {
        if ( z < ATTACK_RANGE )
        {
            _phase++;
        }
    }
}

/**********************************************
 * Missile-Oni
**********************************************/
class MissileOni extends Oni
{
    private const SIZE_RATE:Number            = 10;
    private const LIFE_RATE:Number            = 1;
    private const HSCORE_RATE:int            = 1;
    private const KSCORE_RATE:int            = 60;
    private const ATTACK_RANGE:Number        = 100;
    private const COLOR:uint                = 0xff3333;
        
    private const SPEED:Number                = 10;
    private const ACCURACY:Number            = 10;
    private const LAUNCH_X:Number            = 10;
    private const LAUNCH_Y_MIN:Number        = 25;
    private const LAUNCH_Y_MAX:Number        = 45;
    private const LAUNCH_BRAKE:Number        = 0.9;
    
    public function MissileOni( lv:int, shadow:Shadow )
    {
        var size:Number                        = SIZE_RATE
        var life:int                        = LIFE_RATE;
        _hit_score                            = HSCORE_RATE;
        _kill_score                            = KSCORE_RATE;
                
        super( shadow, size, life );
        
        graphics.lineStyle( 1 );
        graphics.beginFill( 0xffffff );
        graphics.moveTo( -_size / 4, -_size * 3 / 2 );
        graphics.lineTo( 0, -_size * 3 / 2 -_size * 6 * 3 / 10 );
        graphics.lineTo( _size / 4, -_size * 3 / 2 );
        graphics.endFill();
        
        graphics.lineStyle( 1 );
        graphics.beginFill( COLOR );
        graphics.drawCircle( 0, -_size, _size );
        graphics.endFill();
        
        graphics.lineStyle( 1 );
        graphics.moveTo( -_size * 3 / 8, -_size * 7 / 6 );
        graphics.lineTo( -_size * 5 / 8, -_size * 6 / 6 );
        graphics.moveTo( _size * 3 / 8, -_size * 7 / 6 );
        graphics.lineTo( _size * 5 / 8, -_size * 6 / 6 );
        
        graphics.moveTo( -_size / 4, -_size / 2 );
        graphics.lineTo( _size / 4, -_size / 2 );
    }
    
    protected override function phasePop():void
    {
        _anti_gravity                        = true;
        _v.x                                = LAUNCH_X / 2 - Math.random() * LAUNCH_X * 2;
        _v.y                                = - LAUNCH_Y_MIN - Math.random() * ( LAUNCH_Y_MAX - LAUNCH_Y_MIN );
        _phase++;
    }
    
    protected override function phaseSetup():void
    {
        _v.y                                *= LAUNCH_BRAKE;
        
        if ( Math.abs( _v.y ) < 1 )
        {
            
            var target_x:Number                = G.STAGE_WIDTH / 2 - ACCURACY + Math.random() * ACCURACY * 2;
            var target_y:Number                = G.STAGE_HEIGHT / 2 - ACCURACY + Math.random() * ACCURACY * 2;
            
            _v.x                            = ( target_x - x ) / ( z / SPEED );
            _v.y                            = ( target_y - y ) / ( z / SPEED );
            _v.z                            = -SPEED;
            
            _phase++;
        }
    }
    
    protected override function phaseMove():void
    {
        if ( z < ATTACK_RANGE )
        {
            _phase++;
        }
    }
}

/**********************************************
 * Oni-Tank
**********************************************/
class OniTank extends Oni
{
    private const SIZE_RATE:Number            = 100;
    private const LIFE_RATE:Number            = 2000;
    private const HSCORE_RATE:int            = 1;
    private const KSCORE_RATE:int            = 5000;
    private const HCOLOR:uint                = 0xff0000;
    private const BCOLOR:uint                = 0x880000;
    private const CCOLOR:uint                = 0x550000;
        
    private const SPEED:Number                = 1;
    private const TAMA_TIMER:int            = 50;
    private const MISSILE_TIMER:int            = 300;
    private const COOLDOWN_TIMER:int        = 200;
    private const MISSILE_LAUNCH_TIME:int    = 30;
    
    private var _tama_count:int;
    private var _missile_count:int;
    
    public function OniTank( lv:int, shadow:Shadow )
    {
        var size:Number                        = SIZE_RATE
        var life:int                        = LIFE_RATE;
        _hit_score                            = HSCORE_RATE;
        _kill_score                            = KSCORE_RATE;
                
        super( shadow, size, life );
        
        _stagger_rate                        = 0.1;
        
        graphics.beginFill( 0x0 );
        graphics.drawCircle( -75, -25, 25 );
        graphics.drawCircle( 75, -25, 25 );
        graphics.endFill();
        graphics.beginFill( 0x0 );
        graphics.drawRect( -75, -50, 150, 50 );
        graphics.endFill();
        
        var mm:Matrix                        = new Matrix();
        mm.createGradientBox( size / 4, size / 4, 60 * Math.PI / 180, -size / 2, -size );
        
        graphics.beginGradientFill( GradientType.LINEAR, [ 0x804000, 0x402000 ], [ 1, 1 ], [ 0, 255 ], mm );
        graphics.moveTo( 90, -60 );
        graphics.lineTo( 90, -190 );
        graphics.lineTo( 95, -190 );
        graphics.lineTo( 95, -60 );
        graphics.endFill();
        
        graphics.beginGradientFill( GradientType.LINEAR, [ 0xffffff, 0x888888 ], [ 1, 1 ], [ 0, 255 ], mm );
        graphics.moveTo( 100, -190 );
        graphics.lineTo( 160, -190 );
        graphics.lineTo( 160, -130 );
        graphics.lineTo( 100, -130 );
        graphics.endFill();
        
        
        
        
        var mark_x:Number                    = 130;
        var mark_y:Number                    = -135;
        var mark_size:Number                = 20;
        
        graphics.lineStyle( 1 );
        for ( var i:int = 6; 3 <= i; --i )
        {
            graphics.beginFill( 0xffffff );
            graphics.moveTo( mark_x - mark_size / 4, mark_y - mark_size * 3 / 2 );
            graphics.curveTo( mark_x - mark_size / 2, mark_y - mark_size * 3 / 2 -mark_size * i * 3 / 10, mark_x - mark_size * 3 / 4, mark_y - mark_size * 3 / 2 );
            graphics.endFill();
            graphics.beginFill( 0xffffff );
            graphics.moveTo( mark_x + mark_size / 4, mark_y - mark_size * 3 / 2 );
            graphics.curveTo( mark_x + mark_size / 2, mark_y - mark_size * 3 / 2 -mark_size * i * 3 / 10, mark_x + mark_size * 3 / 4, mark_y - mark_size * 3 / 2 );
            graphics.endFill();
        }
        graphics.beginFill( 0xff0000 );
        graphics.drawCircle( mark_x, mark_y - mark_size, mark_size );
        graphics.endFill();
        
        graphics.lineStyle( mark_size / 10, 0xffffff );
        graphics.beginFill( 0x0 );
        graphics.drawCircle( mark_x - mark_size / 2, mark_y - mark_size * 7 / 6, mark_size / 10 );
        graphics.endFill();
        
        graphics.beginFill( 0x0 );
        graphics.drawCircle( mark_x + mark_size / 2, mark_y - mark_size * 7 / 6, mark_size / 10 );
        graphics.endFill();
        
        graphics.lineStyle( 1 );
        graphics.beginFill( 0xffffff );
        graphics.moveTo( mark_x - mark_size / 2, mark_y - mark_size * 3 / 4 );
        graphics.curveTo( mark_x, mark_y, mark_x + mark_size / 2, mark_y - mark_size * 3 / 4 );
        graphics.endFill();
        
        
        
        
        
        var mbt:Matrix                        = new Matrix();
        mbt.createGradientBox( size / 2, size / 2, 60 * Math.PI / 180, -size / 2, -size );
        
        graphics.lineStyle();
        graphics.beginGradientFill( GradientType.LINEAR, [ HCOLOR, BCOLOR ], [ 1, 1 ], [ 0, 150 ], mbt );
        graphics.moveTo( -70, -60 );
        graphics.lineTo( 30, -60 );
        graphics.lineTo( 40, -75 );
        graphics.lineTo( 10, -105 );
        graphics.lineTo( -50, -105 );
        graphics.lineTo( -80, -75 );
        graphics.lineTo( -70, -60 );
        graphics.endFill();
        
        var mlt:Matrix                        = new Matrix();
        mlt.createGradientBox( size / 4, size / 4, -90 * Math.PI / 180, 0, -size );
        var mlb:Matrix                        = new Matrix();
        mlb.createGradientBox( size / 4, size / 4, 90 * Math.PI / 180, 0, -size );
        
        graphics.beginGradientFill( GradientType.LINEAR, [ HCOLOR, BCOLOR ], [ 1, 1 ], [ 0, 255 ], mlt );
        graphics.drawRect( 40, -95, 40, 20 );
        graphics.endFill();
        graphics.beginGradientFill( GradientType.LINEAR, [ HCOLOR, BCOLOR ], [ 1, 1 ], [ 0, 255 ], mlb );
        graphics.drawRect( 40, -75, 40, 10 );
        graphics.endFill();
        graphics.beginFill( 0x0 );
        graphics.drawCircle( 45, -90, 3 );
        graphics.drawCircle( 52.5, -90, 3 );
        graphics.drawCircle( 60, -90, 3 );
        graphics.drawCircle( 67.5, -90, 3 );
        graphics.drawCircle( 75, -90, 3 );
        graphics.drawCircle( 48.75, -85, 3 );
        graphics.drawCircle( 56.25, -85, 3 );
        graphics.drawCircle( 63.75, -85, 3 );
        graphics.drawCircle( 71.25, -85, 3 );
        graphics.drawCircle( 45, -80, 3 );
        graphics.drawCircle( 52.5, -80, 3 );
        graphics.drawCircle( 60, -80, 3 );
        graphics.drawCircle( 67.5, -80, 3 );
        graphics.drawCircle( 75, -80, 3 );
        graphics.endFill();
        
        var mbb:Matrix                        = new Matrix();
        mbb.createGradientBox( size / 2, size / 2, 90 * Math.PI / 180, -size / 2, -size / 2 );
        
        graphics.beginGradientFill( GradientType.LINEAR, [ HCOLOR, BCOLOR ], [ 1, 1 ], [ 0, 255 ], mbb );
        graphics.moveTo( -120, -40 );
        graphics.lineTo( -100, -15 );
        graphics.lineTo( 80, -15 );
        graphics.lineTo( 120, -40 );
        graphics.lineTo( 120, -60 );
        graphics.lineTo( -90, -70 );
        graphics.lineTo( -120, -40 );
        graphics.endFill();
        
        graphics.beginFill( CCOLOR );
        graphics.drawCircle( -20, -85, 14 );
        graphics.endFill();
        graphics.beginFill( 0x0 );
        graphics.drawCircle( -20, -85, 10 );
        graphics.endFill();
        
        var label:TextField                    = new TextField();
        label.selectable                    = false;
        label.textColor                        = 0x000000;
        label.text                            = "O-N-I";
        label.scaleX = label.scaleY            = 4;
        label.x                                = -75;
        label.y                                = -75;
        addChild( label );

    }
    
    protected override function action():void 
    {
        if ( _life <= 0 )
        {
            rotationX                        -= FALL_RATE;
            rotationY                        = 0;
            _v.x                            = 0;
            _v.z                            = 0;
        }
        else
        {
            rotationY                            *= STAGGER_BRAKE;
            
            _phase_function[_phase]();
            nophaseAction();
        }
    }
    
    protected override function phasePop():void
    {
        _v.x                                = -SPEED;
        
        if ( x < G.STAGE_WIDTH / 2 )
        {
            _v.x                            = 0;
            _tama_count                        = TAMA_TIMER;
            _missile_count                    = MISSILE_TIMER;
            _phase++;
        }
    }
    
    protected override function phaseMove():void
    {
        _missile_count--;
        
        if ( _missile_count < MISSILE_LAUNCH_TIME )
        {
            if ( _missile_count < 0 )
            {
                _missile_count                    = COOLDOWN_TIMER + MISSILE_TIMER;
            }
            
            _tama_count                            = COOLDOWN_TIMER + TAMA_TIMER;
        }
        
        _tama_count--;
        
        if ( _tama_count < 0 )
        {
            _tama_count                            = TAMA_TIMER;
        }
    }
    
    public override function isSpawnTama():Boolean
    {
        if ( _phase == PHASE_MOVE && 0 < _life )
        {
            return !_tama_count;
        }
        
        return false;
    }
    
    public override function isSpawnMissile():Boolean
    {
        if ( _phase == PHASE_MOVE && 0 < _life )
        {
            return ( _missile_count < MISSILE_LAUNCH_TIME && !( _missile_count % 3 ) ) ? true : false ;
        }
        
        return false;
    }
}

/**********************************************
 * Last-Oni
**********************************************/
class LastOni extends Oni
{
    private const SIZE_RATE:Number            = 40;
    private const LIFE_RATE:Number            = 4;
    private const HSCORE_RATE:int            = 1;
    private const KSCORE_RATE:int            = 1;
    private const ATTACK_RANGE:Number        = 100;
    private const COLOR:uint                = 0xff3333;
        
    private const SPEED:Number                = 1;
    
    public function LastOni( lv:int, shadow:Shadow )
    {
        var size:Number                        = SIZE_RATE;
        var life:int                        = 5;
        _hit_score                            = HSCORE_RATE;
        _kill_score                            = KSCORE_RATE;
                
        super( shadow, size, life );
        
        var mm:Matrix                        = new Matrix();
        mm.createGradientBox( 25, 25, 60 * Math.PI / 180, -50, -80 );
        
        graphics.beginGradientFill( GradientType.LINEAR, [ 0x404040, 0x202020 ], [ 1, 1 ], [ 0, 255 ], mm );
        graphics.moveTo( _size - 5, -_size / 2 );
        graphics.lineTo( _size - 5, -_size / 2 - 130 );
        graphics.lineTo( _size, -_size / 2 - 130 );
        graphics.lineTo( _size, -_size / 2 );
        graphics.endFill();
        graphics.beginGradientFill( GradientType.LINEAR, [ 0xffffff, 0x888888 ], [ 1, 1 ], [ 0, 255 ], mm );
        graphics.moveTo( size + 5, -_size / 2 - 130 );
        graphics.lineTo( size + 65, -_size / 2 - 130 );
        graphics.lineTo( size + 65, -_size / 2 - 70 );
        graphics.lineTo( size + 5, -_size / 2 - 70 );
        graphics.endFill();
        
        graphics.lineStyle( 1 );
        for ( var i:int = 6; 3 <= i; --i )
        {
            graphics.beginFill( 0xffffff );
            graphics.moveTo( -_size / 4, -_size * 3 / 2 );
            graphics.curveTo( -_size / 2, -_size * 3 / 2 -_size * i * 3 / 10, -_size * 3 / 4, -_size * 3 / 2 );
            graphics.endFill();
            graphics.beginFill( 0xffffff );
            graphics.moveTo( _size / 4, -_size * 3 / 2 );
            graphics.curveTo( _size / 2, -_size * 3 / 2 -_size * i * 3 / 10, _size * 3 / 4, -_size * 3 / 2 );
            graphics.endFill();
        }
        graphics.beginFill( COLOR );
        graphics.drawCircle( 0, -_size, _size );
        graphics.endFill();
        
        graphics.lineStyle( 1 );
        graphics.moveTo( -_size * 3 / 8, -_size * 6 / 6 );
        graphics.lineTo( -_size * 5 / 8, -_size * 8 / 6 );
        graphics.moveTo( -_size * 5 / 8, -_size * 6 / 6 );
        graphics.lineTo( -_size * 3 / 8, -_size * 8 / 6 );
        graphics.moveTo( _size * 3 / 8, -_size * 6 / 6 );
        graphics.lineTo( _size * 5 / 8, -_size * 8 / 6 );
        graphics.moveTo( _size * 5 / 8, -_size * 6 / 6 );
        graphics.lineTo( _size * 3 / 8, -_size * 8 / 6 );
        
        graphics.lineStyle( 1 );
        graphics.moveTo( -_size / 4, -_size / 2 );
        graphics.lineTo( 0, -_size * 3 / 4 );
        graphics.lineTo( _size / 4, -_size / 2 );
    }
    
    protected override function phasePop():void
    {
        if ( GROUND_HEIGHT <= y )
        {
            _phase++;
        }
    }
    
    protected override function phaseSetup():void
    {
        _v.z                            = -SPEED;
        _phase++;
    }
    
    protected override function phaseMove():void
    {
        if ( z < ATTACK_RANGE )
        {
            _v.z                                = 0;
        }
    }
}