#apply
#include "../_include.txt"
#include "../../define/_vector2.txt"
#include "../../define/_vector3.txt"


cev[CEV_CAT_LEG] .name("mg_猫脚クロス") {

    def {
        NUM_OF_VAR = 256
        NUM_OF_STR = 0
        NUM_OF_PIC = 72

        BASE_LAYER = 6

        PATH_BACK   = "cl\bg"
        PATH_BAR    = "cl\ba"
        PATH_LOGO   = "cl\lo"
        PATH_HPBAR  = "cl\hp"
        PATH_NAME   = "cl\sc"
        PATH_COUNT  = "cl\co"
        PATH_SHADOW = "cl\sh"
        PATH_SPRITE  = "cl\ma"

        PIC_HEAD      = 1
        PIC_BACK      = 2
        PIC_SHADOW    = 3//+0_+15
        PIC_SORTED    = 20//+0_+15
        PIC_SPRITE    = 40//+0_+15
        PIC_BAR       = 60
        PIC_LOGO      = 61
        PIC_HPBAR     = 62//+0_+1
        PIC_NAME      = 65
        PIC_TIME_CNT  = 66//+0_+2
        PIC_SCORE_CNT = 69//+0_+1

        //シーン
        SCENE_START = 0
        SCENE_GAME
        SCENE_TIMEUP
        SCENE_GAMEOVER
        SCENE_CHOICE

        //実績
        ACHIEVE_SCORE = 60

        //シーンに応じた判定処理
        IN_GAME = sceneState == SCENE_GAME//主人公を制御できる
        UPDATE_SPRITE = between(sceneState, SCENE_START, SCENE_GAMEOVER)//他のキャラを制御する

        //状態に応じた処理
        IN_DAMAGE_MOTION = between(state, SPR_STATE_DEFEATED, SPR_STATE_DAMAGE3)

        //トリガー
        TR_PL_HP    = 1 << 0
        TR_EN_HP    = 1 << 1
        TR_TIME_CNT = 1 << 2
        TR_SCORE    = 1 << 3

        //単位
        CC_U_POS = 10

        //表示
        OUT_RANGE       = -320
        COUNTER_WIDTH   = 16
        SPR_MUL_Z       = 2
        SPR_DIV_Z       = 3
        SPR_OFFSET_X    = 0
        SPR_OFFSET_Y    = 184 - 30
        SHADOW_OFFSET_Y = 184

        CENTER_X = 160
        CENTER_Y = 120

        HP_GAUGE_MAX   = HP_MAX
        HP_GAUGE_WIDTH = 8
        PL_HP_X  = 32
        PL_HP_Y  = 0
        EN_HP_X   = 32
        EN_HP_Y   = 16

        TIME_DIGIT = 3
        TIME_X = 184
        TIME_Y = 12

        SCORE_MAX = 99
        SCORE_DIGIT = 2
        SCORE_X = 288
        SCORE_Y = 12

        LOGO_X = 320 / 2
        LOGO_Y = 240 / 2 - 32

        HP_MAX = 12
        GAME_TIME = UNIT_FPS * 180
        AROUND_TIMER = UNIT_FPS * 5
        ATTACK_TIMER = UNIT_FPS * 3

        //動作
        STAGE_MIN_X = 0 * CC_U_POS
        STAGE_MAX_X = 320 * CC_U_POS
        STAGE_MIN_Y = 0 * CC_U_POS
        STAGE_MAX_Y = 240 * CC_U_POS
        STAGE_MIN_Z = 0 * CC_U_POS
        STAGE_MAX_Z = 76 * CC_U_POS

        GRAVITY = 2//重力加速度
        HITSTOP_NORMAL = 4//ヒットストップ
        HITSTOP_STRONG = 12
        SPR_WIDTH  = CC_U_POS * 20//キャラの幅(共通)
        SPR_HEIGHT = CC_U_POS * 48//キャラの高さ(共通)
        SPR_DEPTH  = CC_U_POS * 20//キャラの厚み(共通)
        PL_WALK_SPEED   = CC_U_POS * 3 / 2
        PL_SLIDE_SPEED  = CC_U_POS * 2
        PL_JUMP_SPEED_X = CC_U_POS * 2
        PL_JUMP_SPEED_Y = CC_U_POS * 3
        PL_JUMP_SPEED_Z = CC_U_POS * 2
        TARGET_MARGIN_X = 24 * CC_U_POS//敵の目標座標の補正
        TARGET_MARGIN_Z = 4 * CC_U_POS

        //攻撃属性
        ATK_TYPE_NONE = 0
        ATK_TYPE_DAMAGE1
        ATK_TYPE_DAMAGE2
        ATK_TYPE_DAMAGE3
        ATK_TYPE_ITEM1

        //攻撃ヒット時の効果音
        ATK_SOUND_NONE = 0
        ATK_SOUND_HIT1
        ATK_SOUND_HIT2
        ATK_SOUND_HIT3
        ATK_SOUND_DEFEATED
        ATK_SOUND_ITEM1

        //セル番号の頭
        CELL_PLAYER = 1
        CELL_HITEFF = 55
        CELL_ITEM1  = 51
        CELL_DAMAGE = 57
        CELL_ENEMY1 = 25
        CELL_ENEMY2 = 30
        CELL_ENEMY3 = 35
        CELL_ENEMY4 = 40
        CELL_ENEMY5 = 45

        //----------------------------
        //スプライトの状態
        SPR_STATE_NONE = 0
        SPR_STATE_DELETE
        SPR_STATE_CREATE
        SPR_STATE_DEFEATED
        SPR_STATE_DAMAGE1
        SPR_STATE_DAMAGE2
        SPR_STATE_DAMAGE3
        SPR_STATE_ENABLE = 7

        PL_STATE_STAND = 7//=enable
        PL_STATE_MOVE
        PL_STATE_JUMP
        PL_STATE_FALL
        PL_STATE_LAND
        PL_STATE_GR_ATK1
        PL_STATE_GR_ATK2
        PL_STATE_GR_ATK3
        PL_STATE_AI_ATK1
        PL_STATE_SP_N
        PL_STATE_SP_U
        PL_STATE_SP_D
        PL_STATE_SP_F
        PL_STATE_SP_SUPER

        EN_STATE_STAND = 7//=enable
        EN_STATE_MOVE
        EN_STATE_READY1
        EN_STATE_ATK1
        EN_STATE_ATK2

        //スプライトのタイプ
        SPR_TYPE_NONE = 0
        SPR_TYPE_PLAYER
        SPR_TYPE_ENEMY1
        SPR_TYPE_ENEMY2
        SPR_TYPE_ENEMY3
        SPR_TYPE_ENEMY4
        SPR_TYPE_ENEMY5
        SPR_TYPE_HITEFF
        SPR_TYPE_ITEM1

        //スプライトのフラグ
        SPR_FLAG_PLAYER  = 1 << 0
        SPR_FLAG_ENEMY   = 1 << 1
        SPR_FLAG_ITEM    = 1 << 2
        SPR_FLAG_HREV    = 1 << 3
        SPR_FLAG_SHADOW  = 1 << 4
        SPR_FLAG_GRAVITY = 1 << 5
        SPR_FLAG_RESET_V = 1 << 6
        SPR_FLAG_AROUND  = 1 << 7
        SPR_FLAG_AIR_ATK = 1 << 8
        SPR_FLAG_EVADE   = 1 << 9

        //スプライトの数
        SPR_NUM = 8
        SPR_NUM_PLAYER = 1
        SPR_NUM_ENEMY  = 5
        SPR_NUM_ITEM   = 1
        SPR_NUM_HITEFF = 1

        //スプライトIDの割り当て
        SPR_ID_PLAYER = 0
        SPR_ID_ENEMY  = 1
        SPR_ID_ITEM   = 6
        SPR_ID_HITEFF = 7

        //スプライトの構造とサイズ
        //member of sprite
        MS_PID = 0
        MS_CELL
        MS_TYPE
        MS_STATE
        MS_TIMER
        MS_FLAG
        MS_HIT
        MS_POINT
        MS_TX
        MS_TZ
        MS_X
        MS_Y
        MS_Z
        MS_VX
        MS_VY
        MS_VZ
        SIZE_OF_SPR

        //メンバ変数へのアクセス
        //試しとして今回は使わない
    }

    //ピクチャの共通コマンド
    def {
        basePicCmd = bl {
            .chromakey(1)
            .mapLayer(BASE_LAYER)
            .eraseWhenTransfer
            .affectedByTint
            .affectedByFlash
            .affectedByShake
        }

        //背景
        backPicCmd = bl {
            PATH_BACK
            .center
            basePicCmd
        }

        //㏋バー
        healthPicCmd = bl {
            PATH_HPBAR
            .topLeft
            .grid(1, 2)
            basePicCmd
        }

        //ロゴ
        logoPicCmd = bl {
            PATH_LOGO
            .center
            .grid(1, 3)
            basePicCmd
        }

        //カウント
        countPicCmd = bl {
            PATH_COUNT
            .topRight
            .grid(10, 1)
            basePicCmd
        }

        //スプライト
        spritePicCmd = bl {
            PATH_SPRITE
            .center
            .grid(8, 8)
            basePicCmd
        }

        //影
        shadowPicCmd = bl {
            PATH_SHADOW
            .center
            basePicCmd
        }
    }

    //変数定義
    defv {
        varHead = TV_MINIGAME

        initHead

        pA
        iA
        pB
        iB
        pid
        cell
        type
        state
        timer
        flag
        hit
        dir

        atkType
        atkTarget
        atkPoint
        atkSound
        atkRangeXY
        atkRangeZ
        atkX
        atkY
        atkZ

        tagAround
        tagMinX
        tagMaxX
        tagMinZ
        tagMaxZ

        moveSpeed
        moveType

        ftA
        ftB

        input
        alpha
        beta
        gamma
        sx
        sy
        sz
        ex
        ey
        ez
        px
        py
        pz

        sceneState
        sceneTimer
        triggerFlg

        timeLimit
        score
        hitStop
        slowMotion
        progressTimer
        progressCount
        enemyNum
        enemyAtkNum

        playerHpGauge
        enemyHpGauge

        backGroundColor
        zoomScale
        zoomX
        zoomY

        inputX
        inputY
        inputJump
        inputAtk
        inputSp

        initFoot//スプライトまで初期化されるとピクチャのソートが破綻してしまう

        sprHead
        sortDepth = (__id(sprHead)   + SPR_NUM * SIZE_OF_SPR )//ソート用配列
        sortSprId = (__id(sortDepth) + SPR_NUM)

        varFoot
    }

    commentRangeOfVariables(varFoot, TV_MINIGAME, NUM_OF_VAR, NUM_OF_STR, NUM_OF_PIC)

    //攻撃パラメータを設定する
    __fn _setAttackParams $arr {
        v[__id(atkType)..__id(atkZ)] = $arr
    }

    //目標座標パラメータを設定する
    __fn _setTargetParams $arr {
        v[__id(tagAround)..__id(tagMaxZ)] = $arr
    }

    //移動パラメータを設定する
    __fn _setMoveParams $arr {
        v[__id(moveSpeed)..__id(moveType)] = $arr
    }

    //スプライトのポインタを取得する
    __fn _getSprPtr $dvDst $idx bl {
        v[__id($dvDst)] = __id(sprHead) + SIZE_OF_SPR * ($idx)
    }

    //スプライトのメンバ変数を初期化する
    __fn _setSprMembers $ptr $arr bl {
        v[$ptr..$ptr + SIZE_OF_SPR - 1] = $arr
    }

    //スプライトのメンバ変数をデフォルト値で初期化する
    __fn _initSprMembers $ptr bl {
        ftA = v[$ptr + MS_PID]
        v[$ptr..$ptr + SIZE_OF_SPR - 1] = [ftA, 0, SPR_TYPE_NONE, SPR_STATE_NONE, -1,  0x00, 0, 0,  0, 0,  0, 0, 0,  0, 0, 0]
    }

    //スプライトを有効化し、ピクチャ番号以外のメンバ変数を初期化する
    __fn _setupSprite $ptr $type $x $y $z bl {
        ftA = v[$ptr + MS_PID]
        v[$ptr..$ptr + SIZE_OF_SPR - 1] = [ftA, 0, $type, SPR_STATE_CREATE, -1,  0x00, 0, 0,  0, 0,  $x, $y, $z,  0, 0, 0]
    }

    //スプライトのピクチャを初期化する
    //ポインタではなくインデックス番号を渡す
    __fn _initSpritePicture $idx bl {
        _getSprPtr(ftA, $idx)
        ftB  = v[ftA+MS_PID]
        @pic.show [ftB] .pos(OUT_RANGE, OUT_RANGE) .trans(100) spritePicCmd
        ftB = PIC_SHADOW + $idx
        @pic.show [ftB] .pos(OUT_RANGE, OUT_RANGE) .trans(100) shadowPicCmd
    }

    //スプライトの状態を変える
    __fn _changeSpriteState $ptr $state bl {
        v[$ptr+MS_STATE] = $state
        v[$ptr+MS_TIMER] = -1
    }

    //スプライトのパラメータを変える
    __fn _setSpriteTargetParams $ptr $x $z bl {
        v[$ptr+MS_TX..$ptr+MS_TZ] = [$x, $z]
    }

    //スプライトの位置を変える
    __fn _setSpritePosition $ptr $x $y $z bl {
        v[$ptr + MS_X..$ptr + MS_Z] = [$x, $y, $z]
    }

    //スプライトの速度を変える
    __fn _setSpriteVelocity $ptr $x $y $z bl {
        v[$ptr + MS_VX..$ptr + MS_VZ] = [$x, $y, $z]
    }

    //XZ軸の速度を変える
    __fn _setSpriteVel_XZ $ptr $x $z bl {
        v[$ptr + MS_VX] = $x
        v[$ptr + MS_VZ] = $z
    }

    //Y軸の速度を変える
    __fn _setSpriteVel_Y $ptr $y bl {
        v[$ptr + MS_VY] = $y
    }

    //数値を表示する
    //sx. ex. pid, cellを使用する
    __fn _showCounter $num $pid $dig $x $y bl {
        ey = 1
        @loop $dig .dst(ex) bl {
            v[__id(sx)..__id(sy)] = [($x) - ex * COUNTER_WIDTH, ($y)]
            pid  = ($pid) + ex
            cell = (($num) < ey && ey != 1) ? (0) : (1 + ($num) % (ey * 10) / ey)
            @pic.show [pid] .pos(sx, sy) .topRight .scale(100) .cell(cell) countPicCmd

            //次の桁
            ey *= 10
        }
    }

    //シーンの状態を変える
    __fn _changeSceneState $state bl {
        v[__id(sceneState)..__id(sceneTimer)] = [$state, -1]
    }

    //スコアを増やす
    __fn _addScore $add bl {
        score += $add
        bitOn(triggerFlg, TR_SCORE)
    }

    //ハイスコアを更新する
    __fn _updateHighScore bl {
        catLegScore = max(catLegScore, score)
    }

    //------------------------------------------------------------------------------------
    //開始処理
    bl {
        initPicturesAndVariables(PIC_HEAD, NUM_OF_PIC, TV_MINIGAME, NUM_OF_VAR, 0, 0)
        storeAndStopBGM()
        msgBottom()
        
        //ピクチャ
        @pic.show [PIC_BACK] .pos(CENTER_X, CENTER_Y) backPicCmd
        @pic.show [PIC_BAR]  PATH_BAR  .pos(0, 0) .topLeft basePicCmd
        @pic.show [PIC_NAME] PATH_NAME .pos(0, 0) .topLeft basePicCmd
        @pic.show [PIC_LOGO] .pos(OUT_RANGE, OUT_RANGE) .trans(100) .cell(0) logoPicCmd
        @pic.show [PIC_HPBAR + 0] .pos(OUT_RANGE, OUT_RANGE) .trans(100) .cell(1) healthPicCmd
        @pic.show [PIC_HPBAR + 1] .pos(OUT_RANGE, OUT_RANGE) .trans(100) .cell(2) healthPicCmd
        //スプライトを初期化し、ピクチャ番号を登録する
        @loop SPR_NUM .dst(iA) bl {
            _getSprPtr(pA, iA)
            //スプライト
            pid = PIC_SPRITE + iA
            v[pA+MS_PID] = pid
            @pic.show [pid] .pos(OUT_RANGE, OUT_RANGE) .cell(0) spritePicCmd
            //影
            pid = PIC_SHADOW + iA
            @pic.show [pid] .pos(OUT_RANGE, OUT_RANGE) .cell(0) shadowPicCmd
        }

        //暗転
        fastFadeInTintOnly(1)
        @label.jump "gameLoop"
    }

    //------------------------------------------------------------------------------------
    //ゲーム処理
    @label.set "gameLoop"
    bl {
        //変数を一括で初期化する
        assignVarUsingDeclared(initHead, initFoot, 0)
        //ピクチャを隠す
        hidePicture(PIC_LOGO)
        //シーン
        _changeSceneState(SCENE_START)
        triggerFlg = TR_PL_HP | TR_EN_HP | TR_TIME_CNT | TR_SCORE

        timeLimit = GAME_TIME
        score = 0

        playerHpGauge = 0
        enemyHpGauge  = 0

        //画面の拡大
        backGroundColor = 100
        zoomScale = 100
        V2_set(zoomX, CENTER_X, CENTER_Y)
        //ゲームモードによって拡大率を変える
        @if gameMode == 1 bl {
            zoomScale = 200
        }
        //全てのスプライトを初期化するが、ピクチャ番号は変えない
        @loop SPR_NUM .dst(iA) bl {
            _getSprPtr(pA, iA)
            _initSprMembers(pA)
            _initSpritePicture(iA)
        }
        //プレイヤーを登録する
        _getSprPtr(pA, SPR_ID_PLAYER)
        _setupSprite(pA, SPR_TYPE_PLAYER, 160 * CC_U_POS, 0, 20 * CC_U_POS)

        //----------------------------
        //ループ
        @loop bl {
            @wait(0)

            //----------------------------
            //ポーズ
            pauseProcces(TRUE, input, "gameEnd")

            //----------------------------
            //シーン

            //カウンタ
            sceneTimer += 1

            //疑似的なスイッチ文で分岐する
            pseudoSwitchState( sceneState,
                [SCENE_GAME, bl {
                    //制限時間
                    timeLimit -= 1
                    @if timeLimit <= 0 bl {
                        hitStop = 30
                        slowMotion = 120
                        
                        bitOn(triggerFlg, TR_TIME_CNT)
                        _changeSceneState(SCENE_TIMEUP)

                    //カウントダウン
                    } .elif `timeLimit % UNIT_FPS == 0 bl {
                        bitOn(triggerFlg, TR_TIME_CNT)

                        //効果音
                        @if `timeLimit / UNIT_FPS <= 10 bl {
                            @se.play "Cursor2" .opt(60, 100, 50)
                        }
                    }

                    //プレイヤーのHPがゼロになると終了する
                    @if playerHpGauge <= 0 bl {
                        hitStop = 30
                        slowMotion = 120

                        _changeSceneState(SCENE_GAMEOVER)
                    }

                    //カウンターがゼロになるか敵がいなくなると出現する
                    //カウンターがマイナスだと敵がいなくなるまで待つ
                    @if progressTimer > 0 bl {
                        progressTimer -= 1
                    }

                    @if `progressTimer == 0 || enemyNum <= 0 bl {
                        //空きを探す
                        @loop SPR_NUM_ENEMY .dst(iA) bl {
                            iA += SPR_ID_ENEMY
                            _getSprPtr(pA, iA)

                            @if `v[pA+MS_STATE] == SPR_STATE_NONE bl {
                                progressTimer = 60

                                //敵のタイプ
                                //進行度によってパターンが変わる

                                //40-43は全てフェイレン
                                @if `between(progressCount, 40, 43) bl {
                                    type = 4
                                
                                //10人ごとにフェイレン
                                } .elif `progressCount % 10 == 0 && progressCount > 0 bl {
                                    type = 4
                                    //敵がいなくなるまで待つ
                                    progressTimer = -1

                                //パンイチに加え、3体ごとにカース
                                } .elif progressCount < 10 bl {
                                    type = (progressCount % 3 == 0 && progressCount > 0) ? 1 : 0

                                //2種類に加え、3人ごとにアフロを追加する
                                } .elif progressCount < 20 bl {
                                    type = (progressCount % 3 == 0) ? 2 : rnd(0, 1)

                                //メカとアフロ
                                } .elif progressCount < 30 bl {
                                    type = (progressCount % 3 == 0) ? 3 : 2

                                //ランダム
                                //2体ごとに組み合わせが変わる
                                } .else bl {
                                    type = (progressCount % 4 < 2) ? rnd(0, 1) : rnd(2, 3)
                                }

                                //出現場所
                                alpha = rnd(0,3)
                                sx = [STAGE_MIN_X, STAGE_MAX_X][alpha / 2]
                                sz = [STAGE_MAX_Z - 32, STAGE_MIN_Z + 32][alpha % 2]

                                //敵を追加する
                                _setupSprite(pA, type + SPR_TYPE_ENEMY1, sx, 0, sz)

                                //進行度カウンター
                                progressCount += 1

                                @break
                            }
                        }
                    }
                },
                SCENE_START, bl {
                    @if sceneTimer == 0 bl {
                        @pic.show [PIC_LOGO] .pos(LOGO_X, LOGO_Y + 16) .scale(200) .cell(1) .rgbs(200,200,200,100) logoPicCmd
                        @pic.move [PIC_LOGO] .pos(LOGO_X, LOGO_Y) .scale(100) .rgbs(100, 100, 100, 100) .time(2)

                        @se.play "dora1" .opt(100, 100, 50)
                        stopBGM(0)
                    }

                    @if sceneTimer >= 60 bl {
                        hidePicture(PIC_LOGO)
                        _changeSceneState(SCENE_GAME)
                        
                        startBGM("nihao", FALSE, 0, 100, 100, 50)
                    }
                },
                SCENE_GAMEOVER, bl {
                    @if sceneTimer == 0 bl {
                        @pic.show [PIC_LOGO] .pos(LOGO_X, LOGO_Y + 16) .scale(200) .cell(2) .rgbs(200,200,200,100) logoPicCmd
                        @pic.move [PIC_LOGO] .pos(LOGO_X, LOGO_Y) .scale(100) .rgbs(100, 100, 100, 100) .time(2)
                        
                        @scr.flash .once(2) .rgbv(31, 31, 31, 16)
                        @se.play "dora1" .opt(100, 80, 50)
                    }

                    @if sceneTimer >= 180 bl {
                        _changeSceneState(SCENE_CHOICE)
                    }
                },
                SCENE_TIMEUP, bl {
                    @if sceneTimer == 0 bl {
                        @pic.show [PIC_LOGO] .pos(LOGO_X, LOGO_Y + 16) .scale(200) .cell(3) .rgbs(200,200,200,100) logoPicCmd
                        @pic.move [PIC_LOGO] .pos(LOGO_X, LOGO_Y) .scale(100) .rgbs(100, 100, 100, 100) .time(2)
                        
                        @scr.flash .once(2) .rgbv(31, 31, 31, 16)
                        @se.play "dora1" .opt(100, 110, 50)
                    }

                    @if sceneTimer >= 180 bl {
                        _changeSceneState(SCENE_CHOICE)
                    }

                },
                SCENE_CHOICE, bl {
                    replayProcess("gameLoop", "gameEnd")
                }],
                bl {}
            )

            //----------------------------
            //ヒットストップタイマー
            @if hitStop > 0 bl {
                hitStop -= 1
            }

            //スローモーションタイマー
            @if slowMotion > 0 bl {
                slowMotion -= 1
            }

            //----------------------------
            //プレイヤーの操作を受け付ける
            @if `IN_GAME bl {
                //前後左右入力
                V2_getInput(inputX)
                //攻撃
                @key.input .dst(input) {
                    .decision
                }
                inputAtk = input ? inputAtk + 1 : 0
                //ジャンプ
                @key.input .dst(input) {
                    .shift
                }
                inputJump = 0
                @if `input bl {
                    inputSp += 1

                } .elif inputSp > 0 bl {
                    inputSp = 0
                    inputJump = 1
                }

            //入力を初期化
            } .else bl {
                V2_set(inputX, 0, 0)
                v[__id(inputJump)..__id(inputSp)] = 0
            }

            //----------------------------
            //プレイヤーの状態を変える
            //ヒットストップ中でも操作を受け付ける為にここに置かれている
            _getSprPtr(pA, SPR_ID_PLAYER)
            state = v[pA+MS_STATE]

            @if state > SPR_STATE_CREATE bl {
                //必殺技
                __fn _specialAttack() {
                    state = type
                    bitOn(flag, SPR_FLAG_AIR_ATK)
                }

                //プレイヤーの位置をここで記録しておく
                V3_set(px, v[pA+MS_X], v[pA+MS_Y], v[pA+MS_Z])

                //一時変数
                timer = v[pA+MS_TIMER]
                flag  = v[pA+MS_FLAG]
                dir   = (v[pA+MS_FLAG] & SPR_FLAG_HREV) ? -1 : 1

                //入力
                alpha = between(inputAtk, 1, 8)
                beta  = inputSp > 0
                gamma = inputJump > 0

                //入力方向に応じて必殺技を出す
                //上>下>右>左の順に入力が優先される
                //上
                @if inputY < 0 bl {
                    type = PL_STATE_SP_U
                //下
                } .elif inputY > 0 bl {
                    type = PL_STATE_SP_D
                //左右
                } .elif inputX != 0 bl {
                    type = PL_STATE_SP_F
                //ニュートラル
                } .else bl {
                    type = PL_STATE_SP_N
                }

                //存在しない
                @if state == SPR_STATE_NONE bl {
                //立ち / 歩き
                } .elif `state == PL_STATE_STAND || state == PL_STATE_MOVE bl {
                    state = (inputX || inputY) ? PL_STATE_MOVE : PL_STATE_STAND
                    //攻撃フラグを初期化する
                    @if timer <= 0 bl {
                        bitOff(flag, SPR_FLAG_AIR_ATK | SPR_FLAG_EVADE)
                    }

                    //ジャンプ
                    @if `gamma bl {
                        state = PL_STATE_JUMP
                    //必殺技
                    } .elif `alpha && beta bl {
                        _specialAttack()
                    //通常攻撃
                    } .elif `alpha bl {
                        state = PL_STATE_GR_ATK1
                    }

                //ジャンプ / 落下中
                } .elif `between(state, PL_STATE_JUMP, PL_STATE_FALL) bl {
                    @if `inputAtk > 0 && !(flag & SPR_FLAG_AIR_ATK) bl {
                        @if `alpha && beta bl {
                            _specialAttack()
                        } .else bl {
                            state = PL_STATE_AI_ATK1
                        }
                    }

                //跳び蹴り
                } .elif state == PL_STATE_AI_ATK1 bl {
                    //追加入力
                    @if `timer > 8 bl {
                        @if `alpha && beta bl {
                            _specialAttack()
                        }
                    }

                //蹴り上げ
                } .elif state == PL_STATE_SP_N bl {
                    //追加入力
                    @if `timer > 8 bl {
                        @if `alpha && beta bl {
                            //蹴り上げはカッターに変換する
                            @if type == PL_STATE_SP_N bl {
                                type = PL_STATE_SP_U
                            }
                            _specialAttack()
                        }
                    }
                //カッター
                } .elif state == PL_STATE_SP_U bl {
                    //追加入力
                    @if `timer > 12 bl {
                        @if `alpha && beta && (type == PL_STATE_SP_F || type == PL_STATE_SP_D) bl {
                            _specialAttack()
                        }
                    }
                //地上攻撃
                } .elif `between(state, PL_STATE_GR_ATK1, PL_STATE_GR_ATK3) bl {
                    //タイミングは一緒
                    //押しっぱなしでいい
                    @if `timer > 12 && inputAtk > 0 bl {
                        @if state == PL_STATE_GR_ATK1 bl {
                            state = PL_STATE_GR_ATK2
                        } .elif state == PL_STATE_GR_ATK2 bl {
                            state = PL_STATE_GR_ATK3
                        }
                    }

                    //構え入力
                    @if `(timer > 12 || hitStop > 0) bl {
                        @if `gamma {
                            state = PL_STATE_JUMP
                        } .elif `alpha && beta bl {
                            _specialAttack()
                        }
                    }
                }

                //状態を更新する
                v[pA+MS_FLAG] = flag
                @if `state != v[pA+MS_STATE] bl {
                    _changeSpriteState(pA, state)
                }
            }

            //----------------------------
            //キャラクターを更新する
            //ヒットストップ中は行わない
            @if `hitStop <= 0 && slowMotion % 2 == 0 && UPDATE_SPRITE bl {
                //----------------------------
                //動作
                @loop SPR_NUM .dst(iA) bl {
                    _getSprPtr(pA, iA)
                    //スプライトの状態
                    state = v[pA+MS_STATE]
                    //スプライトのタイプ
                    type = v[pA+MS_TYPE]
                    //処理を省略する
                    @if `state == SPR_STATE_NONE ||
                        state == SPR_STATE_DELETE bl {
                        @continue
                    }
                    //攻撃属性を初期化する
                    atkType = ATK_TYPE_NONE
                    //移動指示を初期化する
                    tagAround = -1
                    //移動速度を初期化する
                    moveSpeed = -1
                    //時間経過
                    v[pA+MS_TIMER] += 1
                    timer = v[pA+MS_TIMER]
                    //以下の変数は後で代入される
                    //スプライトのセル番号
                    cell = v[pA+MS_CELL]
                    //スプライトのフラグ
                    flag = v[pA+MS_FLAG]
                    //向き
                    dir = (flag & SPR_FLAG_HREV) ? -1 : 1
                    //----------------------------
                    //共通動作
                    //敵 or プレイヤー
                    @if `flag & (SPR_FLAG_PLAYER | SPR_FLAG_ENEMY) bl {
                        //吹っ飛び or のけぞり
                        @if `IN_DAMAGE_MOTION bl {
                            //のけぞり動作
                            @if `between(state, SPR_STATE_DAMAGE1, SPR_STATE_DAMAGE3) bl {
                                //セル番号は食らった瞬間に設定される
                                //のけぞり属性
                                alpha = state - SPR_STATE_DAMAGE1
                                //硬直時間
                                beta = [10, 28, 0][alpha]
                                //後退速度
                                gamma = [CC_U_POS * -3, CC_U_POS * -4, CC_U_POS / -2][alpha]
                                //吹っ飛び
                                @if state == SPR_STATE_DAMAGE3 bl {
                                    //上昇
                                    @if timer == 0 bl {
                                        _setSpriteVelocity(pA,
                                            dir * gamma,
                                            4 * CC_U_POS,
                                            0
                                        )
                                    }
                                    //着地するとバウンドし、一定の速度以下になると復帰する
                                    @if `v[pA+MS_Y] <= STAGE_MIN_Y && v[pA+MS_VY] <= 0 bl {
                                        @if `v[pA+MS_VY] < -CC_U_POS * 2 bl {
                                            _setSpriteVel_Y(pA, 2 * CC_U_POS)
                                        } .else bl {
                                            state = SPR_STATE_ENABLE
                                        }
                                    }

                                //小のけぞり / 大のけぞり
                                } .else bl {
                                    //のけぞり
                                    @if timer == 0 bl {
                                        _setSpriteVelocity(pA, dir * gamma, 0, 0)
                                    //速度が半分になる
                                    } .elif `timer >= beta / 2 bl {
                                        v[pA+MS_VX] /= 2
                                    }

                                    //一定時間経ち、かつ地面に落ちていると復帰する
                                    @if `v[pA+MS_Y] <= STAGE_MIN_Y && timer >= beta bl {
                                        state = SPR_STATE_ENABLE
                                    }
                                }

                                //復帰直後の処理
                                @if state == SPR_STATE_ENABLE bl {
                                    //無敵状態を解除
                                    bitOff(flag, SPR_FLAG_EVADE)
                                    //速度を初期化
                                    bitOn(flag, SPR_FLAG_RESET_V)
                                    //タイマーを初期化
                                    timer = 0
                                    //ヒットパラメータを初期化
                                    v[pA+MS_HIT] = 0
                                }

                            //敗北
                            } .elif `state == SPR_STATE_DEFEATED bl {
                                //下で処理を行う
                                @if `flag & SPR_FLAG_PLAYER bl {
                                //敵は画面上に吹っ飛ぶ
                                } .else bl {
                                    //速度は1Fだけ設定する
                                    @if timer == 0 bl {
                                        _setSpriteVelocity(pA,
                                            dir * -8 * CC_U_POS,
                                            8 * CC_U_POS,
                                            0
                                        )

                                        //重力を切る
                                        bitOff(flag, SPR_FLAG_GRAVITY)
                                        //スコアを加算する
                                        _addScore(1)

                                    }

                                    //フェードアウト
                                    @if timer > 30 bl {
                                        //フェイレンに限ってはその場でアイテムを落とす
                                        @if type == SPR_TYPE_ENEMY5 bl {
                                            V3_set(sx, v[pA+MS_X], v[pA+MS_Y], v[pA+MS_Z])

                                            _getSprPtr(pB, SPR_ID_ITEM + 0)
                                            _setupSprite(pB, SPR_TYPE_ITEM1, sx, sy, sz)
                                        }
                                        //消去
                                        state = SPR_STATE_DELETE
                                    }
                                }
                            }

                            //吹っ飛び、のけぞり中は画面端で跳ね返る
                            alpha = v[pA+MS_VX]
                            beta = v[pA+MS_X] + alpha
                            @if `(alpha > 0 && beta > STAGE_MAX_X) || (alpha < 0 && beta < STAGE_MIN_X) bl {
                                v[pA+MS_VX] *= -1
                            }
                        }
                    }

                    //----------------------------
                    //分岐
                    pseudoSwitchState( type,
                        [SPR_TYPE_PLAYER, bl {
                            //地上攻撃の出だしは動かせる
                            @if `between(state, PL_STATE_GR_ATK1, PL_STATE_GR_ATK3) bl {
                                $F = 6
                                @if timer < $F bl {
                                    _setSpriteVelocity(pA,
                                        inputX * PL_SLIDE_SPEED,
                                        0,
                                        inputY * PL_SLIDE_SPEED * -1
                                    )

                                } .elif timer == $F bl {
                                    bitOn(flag, SPR_FLAG_RESET_V)
                                }
                            }

                            pseudoSwitchState(state,
                                [SPR_STATE_CREATE, bl {
                                    state = PL_STATE_STAND
                                    bitOn(flag, SPR_FLAG_SHADOW | SPR_FLAG_GRAVITY | SPR_FLAG_PLAYER)

                                    bitOn(triggerFlg, TR_PL_HP)
                                    playerHpGauge = HP_MAX

                                    v[pA+MS_POINT] = HP_MAX
                                },
                                SPR_STATE_DEFEATED, bl {
                                    @if timer == 0 bl {
                                        cell = 0 + CELL_DAMAGE
                                    } .elif timer == 20 bl {
                                        cell = 6 + CELL_PLAYER
                                    }
                                },
                                PL_STATE_STAND, bl {
                                    cell = 0 + CELL_PLAYER
                                    _setSpriteVel_XZ(pA, 0, 0)                                    
                                },
                                PL_STATE_MOVE, bl {
                                    cell = ((timer % 16 < 8) ? 1 : 0) + CELL_PLAYER

                                    @if inputX > 0 bl {
                                        dir = 1
                                    } .elif inputX < 0 bl {
                                        dir = -1
                                    }

                                    _setSpriteVel_XZ(pA,
                                        inputX * PL_WALK_SPEED,
                                        inputY * PL_WALK_SPEED * -1
                                    )                                    
                                },
                                PL_STATE_JUMP, bl {
                                    cell = 2 + CELL_PLAYER

                                    @if timer == 0 bl {
                                        @if inputX > 0 bl {
                                            dir = 1
                                        } .elif inputX < 0 bl {
                                            dir = -1
                                        }

                                        _setSpriteVelocity(pA,
                                            PL_JUMP_SPEED_X * inputX,
                                            PL_JUMP_SPEED_Y,
                                            PL_JUMP_SPEED_Z * inputY * -1
                                        )

                                        @se.play "jump_anim" .opt(60, 130, 50)

                                    } .elif timer > 24 bl {
                                        state = PL_STATE_FALL
                                    }
                                },
                                PL_STATE_FALL, bl {
                                    cell = 2 + CELL_PLAYER

                                    @if `v[pA+MS_Y] <= STAGE_MIN_Y bl {
                                        state = PL_STATE_LAND
                                        bitOn(flag, SPR_FLAG_RESET_V)
                                    }
                                },
                                PL_STATE_LAND, bl {
                                    cell = 3 + CELL_PLAYER

                                    @if timer > 8 bl {
                                        state = PL_STATE_STAND
                                    }

                                },
                                PL_STATE_GR_ATK1, bl {
                                    cell = 7 + CELL_PLAYER

                                    @if timer == 0 bl {
                                        @se.play "Evade2" .opt(80, 90, 50)
                                    } .elif timer >= 20 bl {
                                        state = PL_STATE_STAND
                                    }

                                    //攻撃判定
                                    @if `between(timer, 0, 4) bl {
                                        _setAttackParams( [ ATK_TYPE_DAMAGE1, SPR_FLAG_ENEMY, 1, ATK_SOUND_HIT1,
                                            4 * CC_U_POS, 4 * CC_U_POS,
                                            24 * CC_U_POS, 30 * CC_U_POS, 0 
                                        ] )
                                    }
                                },
                                PL_STATE_GR_ATK2, bl {
                                    cell = 8 + CELL_PLAYER

                                    @if timer == 0 bl {
                                        v[pA+MS_X] += 4 * dir * CC_U_POS
                                        @se.play "Evade2" .opt(80, 100, 50)
                                    } .elif timer >= 20 bl {
                                        state = PL_STATE_STAND
                                    }

                                    //攻撃判定
                                    @if `between(timer, 0, 4) bl {
                                        _setAttackParams( [ ATK_TYPE_DAMAGE1, SPR_FLAG_ENEMY, 1, ATK_SOUND_HIT1,
                                            4 * CC_U_POS, 6 * CC_U_POS,
                                            26 * CC_U_POS, 28 * CC_U_POS, 0 
                                        ] )
                                    }
                                },
                                PL_STATE_GR_ATK3, bl {
                                    cell = 9 + CELL_PLAYER

                                    @if timer == 0 bl {
                                        v[pA+MS_X] += 6 * dir * CC_U_POS
                                        @se.play "Evade2" .opt(80, 90, 50)
                                    } .elif timer >= 28 bl {
                                        state = PL_STATE_STAND
                                    }

                                    //攻撃判定
                                    @if `between(timer, 0, 6) bl {
                                        _setAttackParams( [ ATK_TYPE_DAMAGE2, SPR_FLAG_ENEMY, 1, ATK_SOUND_HIT2,
                                            4 * CC_U_POS, 8 * CC_U_POS,
                                            26 * CC_U_POS, 40 * CC_U_POS, 0 
                                        ] )
                                    }
                                },
                                PL_STATE_AI_ATK1, bl {
                                    cell = 11 + CELL_PLAYER

                                    @if timer == 0 bl {
                                        @se.play "Evade2" .opt(80, 100, 50)
                                    }

                                    @if `v[pA+MS_Y] <= STAGE_MIN_Y bl {
                                        state = PL_STATE_LAND
                                        bitOn(flag, SPR_FLAG_RESET_V)
                                    //状態が変わった直度に攻撃判定が入るとダメージが二重に入る事がある
                                    } .else bl {
                                        _setAttackParams( [ ATK_TYPE_DAMAGE2, SPR_FLAG_ENEMY, 1, ATK_SOUND_HIT2,
                                            6 * CC_U_POS, 8 * CC_U_POS,
                                            26 * CC_U_POS, 22 * CC_U_POS, 0 
                                        ] )
                                    }
                                    
                                },
                                PL_STATE_SP_N, bl {
                                    cell = 10 + CELL_PLAYER

                                    @if timer == 0 bl {
                                        _setSpriteVel_Y(pA, PL_JUMP_SPEED_Y)
                                        @se.play "jump_anim" .opt(60, 130, 50)
                                    } .elif timer >= 24 bl {
                                        state = PL_STATE_FALL
                                    }

                                    //攻撃判定
                                    @if `between(timer, 0, 4) bl {
                                        _setAttackParams( [ ATK_TYPE_DAMAGE3, SPR_FLAG_ENEMY, 1, ATK_SOUND_HIT3,
                                            8 * CC_U_POS, 8 * CC_U_POS,
                                            20 * CC_U_POS, 36 * CC_U_POS, 0 
                                        ] )
                                    }
                                    
                                },
                                PL_STATE_SP_U, bl {
                                    cell = (timer < 8 ? 12 : 13) + CELL_PLAYER

                                    //跳躍
                                    @if timer == 0 bl {
                                        bitOn(flag, SPR_FLAG_EVADE)

                                        _setSpriteVelocity(pA,
                                            2 * dir * CC_U_POS,
                                            3 * CC_U_POS,
                                            0
                                        )

                                        @se.play "jump_anim" .opt(60, 100, 50)

                                    //減速する
                                    } .elif timer == 4 bl {
                                        bitOff(flag, SPR_FLAG_EVADE)
                                        v[pA+MS_VX] /= 4

                                    } .elif timer >= 24 bl {
                                        state = PL_STATE_FALL
                                    }

                                    //攻撃判定
                                    @if `between(timer, 0, 8) bl {
                                        _setAttackParams( [ ATK_TYPE_DAMAGE3, SPR_FLAG_ENEMY, 2, ATK_SOUND_HIT3,
                                            10 * CC_U_POS, 12 * CC_U_POS,
                                            18 * CC_U_POS, 48 * CC_U_POS, 0 
                                        ] )
                                    }
                                },
                                PL_STATE_SP_D, bl {
                                    //セル
                                    @if timer == 0 bl {
                                        cell = 16 + CELL_PLAYER
                                    } .elif timer == 16 bl {
                                        cell = 17 + CELL_PLAYER
                                    } .elif timer == 18 bl {
                                        cell = 18 + CELL_PLAYER
                                    }

                                    //発生まで無敵状態
                                    //落下速度が早まる
                                    @if timer == 0 bl {
                                        bitOn(flag, SPR_FLAG_EVADE)
                                        _setSpriteVel_Y(pA, -4 * CC_U_POS)

                                    //少し前進する
                                    } .elif timer == 16 bl {
                                        v[pA+MS_X] += 6 * dir * CC_U_POS

                                        @se.play "Earth3" .opt(100, 80, 50)

                                    //無敵時間を解除
                                    } .elif timer == 18 bl {
                                        bitOff(flag, SPR_FLAG_EVADE)

                                    } .elif timer >= 38 bl {
                                        state = PL_STATE_STAND
                                    }

                                    //地上に降りると速度が初期化される
                                    @if `v[pA+MS_Y] <= STAGE_MIN_Y bl {
                                        bitOn(flag, SPR_FLAG_RESET_V)
                                    }

                                    //攻撃判定
                                    //下に大きな正方形がある
                                    @if `between(timer, 16, 20) bl {
                                        _setAttackParams( [ ATK_TYPE_DAMAGE2, SPR_FLAG_ENEMY, 2, ATK_SOUND_HIT2,
                                            26 * CC_U_POS, 12 * CC_U_POS,
                                            -6 * CC_U_POS, 0, 0 
                                        ] )
                                    }
                                },
                                PL_STATE_SP_F, bl {
                                    @if timer < 6 bl {
                                        cell = 4 + CELL_PLAYER
                                    } .elif `between(timer, 6, 20) bl {
                                        cell = (timer % 4 < 2 ? 14 : 15) + CELL_PLAYER
                                    } .else bl {
                                        cell = 15 + CELL_PLAYER
                                    }

                                    //振り向き and 速度初期化
                                    @if timer == 0 bl {
                                        bitOn(flag, SPR_FLAG_RESET_V)

                                        @if inputX > 0 bl {
                                            dir = 1
                                        } .elif inputX < 0 bl {
                                            dir = -1
                                        }

                                    //跳躍
                                    } .elif timer == 6 bl {
                                        _setSpriteVelocity(pA,
                                            4 * dir * CC_U_POS,
                                            3 * CC_U_POS,
                                            0
                                        )

                                        @se.play "jump_anim" .opt(60, 100, 50)

                                    //落下
                                    } .elif timer == 20 bl {
                                        //減速する
                                        v[pA+MS_VX] /= 4
                                        v[pA+MS_VY] = 0

                                    } .elif timer == 22 bl {
                                        state = PL_STATE_FALL
                                    }

                                    //攻撃判定
                                    @if `between(timer, 6, 20) bl {
                                        _setAttackParams( [ ATK_TYPE_DAMAGE2, SPR_FLAG_ENEMY, 2, ATK_SOUND_HIT2,
                                             8 * CC_U_POS,  8 * CC_U_POS,
                                            16 * CC_U_POS, 22 * CC_U_POS, 0 
                                        ] )
                                    }
                                }],
                                bl {}
                            )
                        },
                        //パンイチ
                        //手を挙げて接近し、攻撃を仕掛ける。意外と追尾性能が高い。
                        //しかも同時攻撃の制約が緩く、群れると危険。
                        SPR_TYPE_ENEMY1, bl {
                            pseudoSwitchState(state,
                                [SPR_STATE_CREATE, bl {
                                    bitOn(flag, SPR_FLAG_GRAVITY | SPR_FLAG_SHADOW | SPR_FLAG_ENEMY)
                                    v[pA+MS_POINT] = 4

                                    //少し前に向かって歩く
                                    state = EN_STATE_MOVE
                                    //振り向く
                                    bitOn(flag, SPR_FLAG_AROUND)
                                    _setTargetParams( [0, 32, 32, -32, 32] )
                                },
                                EN_STATE_STAND, bl {
                                    $RND1 = 40
                                    $TIME1 = 30
                                    $LENGTH1 = 16 * CC_U_POS
                                    $LENGTH2 = 72 * CC_U_POS

                                    //セル番号
                                    cell = 0 + CELL_ENEMY1
                                    //常に振り向く
                                    bitOn(flag, SPR_FLAG_AROUND)
                                    //タイマーをずらす
                                    @if timer == 0 bl {
                                        timer = rnd(0, 3) * 10
                                        v[pA+MS_TIMER] = timer
                                        //停止する
                                        _setMoveParams( [0, 0] )

                                    }

                                    //一定時間後、X軸の距離が近く、攻撃中の敵が4体以下で、一定確率で、ゲーム中ならば攻撃モーションに入る
                                    sx = abs(px - v[pA+MS_X])
                                    sz = abs(pz - v[pA+MS_Z])
                                    @if `IN_GAME && rnd(0, 99) < $RND1 && enemyAtkNum < 5 && sx < $LENGTH2 && timer > $TIME1 bl {
                                        state = EN_STATE_READY1
                                    //一定時間後、もしくは近づきすぎた
                                    } .elif `(sx < $LENGTH1 && sz < $LENGTH1) || timer > $TIME1 bl {
                                        state = EN_STATE_MOVE
                                        _setTargetParams( [20, 32, 64, -32, 32] )
                                    }
                                },
                                EN_STATE_MOVE, bl {
                                    $TIME1 = 120
                                    //セル番号
                                    cell = ((timer % 20 < 10) ? 1 : 0) + CELL_ENEMY1
                                    //常に振り向く
                                    bitOn(flag, SPR_FLAG_AROUND)
                                    //歩行速度
                                    _setMoveParams( [1 * CC_U_POS, 0] )
                                    //到着したか、時間が経った
                                    sx = v[pA+MS_TX] - v[pA+MS_X]
                                    sz = v[pA+MS_TZ] - v[pA+MS_Z]
                                    @if `(!sx && !sz) || timer > $TIME1 bl {
                                        state = EN_STATE_STAND
                                    }
                                },
                                EN_STATE_READY1, bl {
                                    $TIME1 = 20
                                    $TIME2 = 60
                                    //セル番号
                                    cell = ((timer % 16 < 8) ? 2 : 3) + CELL_ENEMY1
                                    //常に振り向く
                                    bitOn(flag, SPR_FLAG_AROUND)
                                    //威嚇
                                    @if timer == 0 bl {
                                        _setMoveParams( [0, 0] )
                                    //近づく
                                    } .elif timer > $TIME1 bl {
                                        //目標位置は毎F更新する
                                        _setMoveParams( [CC_U_POS * 3 / 2, 0] )
                                        _setSpriteTargetParams(pA, px - dir * 32 * CC_U_POS, pz)
                                        //到着したか、時間が経った
                                        sx = v[pA+MS_TX] - v[pA+MS_X]
                                        sz = v[pA+MS_TZ] - v[pA+MS_Z]
                                        @if `(!sx && sz && timer > $TIME1) || timer > $TIME2 bl {
                                            state = EN_STATE_ATK1
                                            @se.play "Evade2" .opt(80, 150, 50)
                                        }
                                    }
                                },
                                EN_STATE_ATK1, bl {
                                    $TIME1 = 60
                                    //セル番号
                                    cell = 4 + CELL_ENEMY1
                                    //停止する
                                    @if timer == 0 bl {
                                        _setSpriteVel_XZ(pA, 0, 0)
                                    //立ち状態に戻る
                                    } .elif timer > $TIME1 bl {
                                        state = EN_STATE_STAND
                                    }

                                    //攻撃判定
                                    @if `between(timer, 0, 4) bl {
                                        _setAttackParams( [ ATK_TYPE_DAMAGE1, SPR_FLAG_PLAYER, 1, ATK_SOUND_HIT1,
                                            4 * CC_U_POS, 6 * CC_U_POS,
                                            26 * CC_U_POS, 28 * CC_U_POS, 0 
                                        ] )
                                    }

                                } ],
                                bl {}
                            )
                        },
                        //スピリットカース
                        //小刻みに動き、大ジャンプからの急降下攻撃を行う。移動タイミングのずれがない。
                        SPR_TYPE_ENEMY2, bl {
                            pseudoSwitchState(state,
                                [SPR_STATE_CREATE, bl {
                                    bitOn(flag, SPR_FLAG_GRAVITY | SPR_FLAG_SHADOW | SPR_FLAG_ENEMY)
                                    v[pA+MS_POINT] = 4

                                    state = EN_STATE_MOVE
                                    bitOn(flag, SPR_FLAG_AROUND)
                                    _setTargetParams( [0, 32, 32, -32, 32] )
                                },
                                EN_STATE_STAND, bl {
                                    $RND1 = 40
                                    $TIME1 = 10
                                    $LENGTH1 = 16 * CC_U_POS
                                    $LENGTH2 = 128 * CC_U_POS

                                    cell = 0 + CELL_ENEMY2

                                    bitOn(flag, SPR_FLAG_AROUND)

                                    @if timer == 0 bl {
                                        _setSpriteVel_XZ(pA, 0, 0)
                                    }

                                    sx = abs(px - v[pA+MS_X])
                                    sz = abs(pz - v[pA+MS_Z])
                                    @if `IN_GAME && rnd(0, 99) < $RND1 && enemyAtkNum < 3 && sx < $LENGTH2 && timer > $TIME1 bl {
                                        state = EN_STATE_READY1

                                    } .elif `(sx < $LENGTH1 && sz < $LENGTH1) || timer > $TIME1 bl {
                                        state = EN_STATE_MOVE
                                        _setTargetParams( [30, 72, 128, -32, 32] )
                                    }
                                },
                                EN_STATE_MOVE, bl {
                                    $TIME1 = 20
                                    $TIME2 = 90

                                    @if `timer % $TIME1 == 0 bl {
                                        cell = 1 + CELL_ENEMY2

                                        //振り向く
                                        bitOn(flag, SPR_FLAG_AROUND)
                                        //小ジャンプ
                                        _setMoveParams( [CC_U_POS * 3 / 2, 0] )
                                        _setSpriteVel_Y(pA, CC_U_POS * 3 / 2)
                                    }

                                    //着地している
                                    @if `v[pA+MS_Y] <= STAGE_MIN_Y && v[pA+MS_VY] <= 0 bl {
                                        cell = 0 + CELL_ENEMY2
                                        _setSpriteVel_XZ(pA, 0, 0)

                                        //時間が経った
                                        @if `timer > $TIME2 bl {
                                            state = EN_STATE_STAND
                                        }
                                    }
                                },
                                EN_STATE_READY1, bl {
                                    $RND1 = 12
                                    $TIME1 = 20
                                    $TIME2 = 60

                                    //構える
                                    @if timer == 0 bl {
                                        cell = 4 + CELL_ENEMY2
                                        _setSpriteVel_XZ(pA, 0, 0)

                                    //ジャンプ
                                    } .elif timer == $TIME1 bl {
                                        cell = 1 + CELL_ENEMY2

                                        sx = px + rnd(-$RND1, $RND1) * CC_U_POS - v[pA+MS_X]
                                        sz = pz + rnd(-$RND1, $RND1) * CC_U_POS - v[pA+MS_Z]
                                        alpha = $TIME2 - $TIME1
                                        _setSpriteVelocity(pA, sx / alpha, 6 * CC_U_POS, sz / alpha)

                                        @se.play "jump_anim" .opt(60, 150, 50)

                                    //落下
                                    } .elif timer >= $TIME2 bl {
                                        state = EN_STATE_ATK1
                                    }

                                },
                                EN_STATE_ATK1, bl {
                                    $TIME1 = 20
                                    $TIME2 = 60

                                    @if `v[pA+MS_VY] > 0 bl {
                                        cell = 1 + CELL_ENEMY2
                                    } .elif `v[pA+MS_Y] <= STAGE_MIN_Y bl {
                                        cell = 4 + CELL_ENEMY2
                                    } .else bl {
                                        cell = (timer % 4 < 2 ? 2 : 3) + CELL_ENEMY2
                                    }
                                    
                                    @if timer == 0 bl {
                                        _setSpriteVelocity(pA, 0, -4 * CC_U_POS, 0)
                                        @se.play "Ice5" .opt(90, 80, 50)
                                    }

                                    @if timer > $TIME2 bl {
                                        state = EN_STATE_STAND
                                    }

                                    @if `between(timer, 0, $TIME1) bl {
                                        _setAttackParams( [ ATK_TYPE_DAMAGE2, SPR_FLAG_PLAYER, 1, ATK_SOUND_HIT2,
                                            12 * CC_U_POS, 12 * CC_U_POS,
                                            0, 16 * CC_U_POS, 0 
                                        ] )
                                    }

                                } ],
                                bl {}
                            )
                        },
                        //アフロ男
                        //ステップで距離を取り、駆け寄って２回攻撃を仕掛ける
                        SPR_TYPE_ENEMY3, bl {
                            pseudoSwitchState(state,
                                [SPR_STATE_CREATE, bl {
                                    bitOn(flag, SPR_FLAG_GRAVITY | SPR_FLAG_SHADOW | SPR_FLAG_ENEMY)
                                    v[pA+MS_POINT] = 6

                                    state = EN_STATE_MOVE
                                    bitOn(flag, SPR_FLAG_AROUND)
                                    _setTargetParams( [0, 32, 32, -32, 32] )

                                },
                                EN_STATE_STAND, bl {
                                    $RND1 = 60
                                    $TIME1 = 40
                                    $LENGTH1 = 32 * CC_U_POS
                                    $LENGTH2 = 96 * CC_U_POS

                                    cell = 0 + CELL_ENEMY3

                                    bitOn(flag, SPR_FLAG_AROUND)

                                    @if timer == 0 bl {
                                        timer = rnd(0, 2) * 10
                                        v[pA+MS_TIMER] = timer

                                        _setSpriteVel_XZ(pA, 0, 0)
                                    }

                                    sx = abs(px - v[pA+MS_X])
                                    sz = abs(pz - v[pA+MS_Z])
                                    @if `IN_GAME && rnd(0, 99) < $RND1 && enemyAtkNum < 3 && sx < $LENGTH2 && timer > $TIME1 bl {
                                        state = EN_STATE_READY1

                                    } .elif `(sx < $LENGTH1 && sz < $LENGTH1) || timer > $TIME1 bl {
                                        state = EN_STATE_MOVE
                                        _setTargetParams( [20, 48, 72, -48, 48] )
                                    }

                                },
                                EN_STATE_MOVE, bl {
                                    $TIME1 = 90
                                    cell = ((timer % 20 < 10) ? 1 : 0) + CELL_ENEMY3

                                    bitOn(flag, SPR_FLAG_AROUND)

                                    alpha = [3, 1, 0, 0][timer % 20 / 5]
                                    _setMoveParams( [alpha * CC_U_POS, 0] )

                                    sx = v[pA+MS_TX] - v[pA+MS_X]
                                    sz = v[pA+MS_TZ] - v[pA+MS_Z]
                                    @if `(!sx && !sz) || timer > $TIME1 bl {
                                        state = EN_STATE_STAND
                                    }
                                },
                                EN_STATE_READY1, bl {
                                    $TIME1 = 30
                                    $TIME2 = 60

                                    @if timer == 0 bl {
                                        cell = 2 + CELL_ENEMY3
                                        _setSpriteVel_XZ(pA, 0, 0)
                                        @se.play "Sword3" .opt(70, 100, 50)

                                    } .elif timer > $TIME1 bl {
                                        cell = ((timer % 6 < 3) ? 1 : 0) + CELL_ENEMY3

                                        bitOn(flag, SPR_FLAG_AROUND)

                                        _setMoveParams( [2 * CC_U_POS, 0] )
                                        _setSpriteTargetParams(pA, px - dir * 20 * CC_U_POS, pz)

                                        sx = v[pA+MS_TX] - v[pA+MS_X]
                                        sz = v[pA+MS_TZ] - v[pA+MS_Z]
                                        @if `(!sx && !sz) || timer > $TIME2 bl {
                                            state = EN_STATE_ATK1
                                        }
                                    }
                                },
                                EN_STATE_ATK1, bl {
                                    $TIME1 = 12
                                    $TIME2 = 40

                                    cell = (timer < $TIME1 ? 3 : 4) + CELL_ENEMY3

                                    //攻撃する時は少し前進する
                                    @if `between(timer, 0, 6) || between(timer, $TIME1, $TIME1 + 6) {
                                        _setSpriteVel_XZ(pA, dir * 2 * CC_U_POS, 0)
                                    } .else bl {
                                        _setSpriteVel_XZ(pA, 0, 0)
                                    }

                                    @if `timer == 0 || timer == $TIME1 bl {
                                        @se.play "Evade2" .opt(80, 120, 50)
                                    } .elif timer > $TIME2 bl {
                                        state = EN_STATE_STAND
                                    }

                                    //攻撃判定
                                    @if `between(timer, 0, 4) || between(timer, $TIME1, $TIME1 + 4) bl {
                                        alpha = timer < $TIME1 ? ATK_TYPE_DAMAGE1 : ATK_TYPE_DAMAGE2
                                        beta  = timer < $TIME1 ? ATK_SOUND_HIT1 : ATK_SOUND_HIT2

                                        _setAttackParams( [ alpha, SPR_FLAG_PLAYER, 1, beta,
                                            8 * CC_U_POS, 12 * CC_U_POS,
                                            28 * CC_U_POS, 24 * CC_U_POS, 0 
                                        ] )
                                    }
                                } ],
                                bl {}
                            )
                        },
                        //メカアレックス
                        //動きが鈍いが、近づくと肘打ちを仕掛ける。距離が離れているか、登場直後に突進攻撃を行う。
                        SPR_TYPE_ENEMY4, bl {
                            pseudoSwitchState(state,
                                [SPR_STATE_CREATE, bl {
                                    bitOn(flag, SPR_FLAG_GRAVITY | SPR_FLAG_SHADOW | SPR_FLAG_ENEMY)
                                    v[pA+MS_POINT] = 10

                                    bitOn(flag, SPR_FLAG_AROUND)

                                    //開幕突進
                                    state = EN_STATE_ATK2
                                },
                                EN_STATE_STAND, bl {
                                    $RND1 = 60
                                    $RND2 = 50
                                    $TIME1 = 60
                                    $TIME2 = 30
                                    $LENGTH1 = 24 * CC_U_POS
                                    $LENGTH2 = 64 * CC_U_POS
                                    $LENGTH3 = 18 * CC_U_POS
                                    $LENGTH4 = 112 * CC_U_POS

                                    cell = 0 + CELL_ENEMY4

                                    bitOn(flag, SPR_FLAG_AROUND)

                                    @if timer == 0 bl {
                                        timer = rnd(0, 2) * 5
                                        v[pA+MS_TIMER] = timer

                                        _setSpriteVel_XZ(pA, 0, 0)
                                    }

                                    sx = abs(px - v[pA+MS_X])
                                    sz = abs(pz - v[pA+MS_Z])

                                    //パンチの判定回数が多い
                                    @if `IN_GAME && rnd(0, 99) < $RND1 && enemyAtkNum < 3 && sx < $LENGTH2 && sz < $LENGTH3 && (timer == $TIME1 || timer == $TIME2) bl {
                                        state = EN_STATE_ATK1
                                    } .elif `IN_GAME && rnd(0, 99) < $RND2 && enemyAtkNum < 3 && sx > $LENGTH4 && sz < $LENGTH3 && timer == $TIME2 bl {
                                        state = EN_STATE_ATK2
                                    } .elif `(sx < $LENGTH1 && sz < $LENGTH1) || timer > $TIME1 bl {
                                        state = EN_STATE_MOVE
                                        _setTargetParams( [0, 48, 72, -24, 24] )
                                    }
                                },
                                EN_STATE_MOVE, bl {
                                    $TIME1 = 32
                                    cell = (timer < 16 ? 1 : 0) + CELL_ENEMY4

                                    @if timer == 0 bl {
                                        _setMoveParams( [2 * CC_U_POS, 0] )

                                    } .elif `timer == $TIME1 / 4 bl {
                                        v[pA+MS_VX] /= 2
                                        v[pA+MS_VZ] /= 2

                                    } .elif `timer == $TIME1 / 2 bl {
                                        _setSpriteVel_XZ(pA, 0, 0)
                                    }

                                    @if timer >= $TIME1 bl {
                                        state = EN_STATE_STAND
                                    }

                                },
                                EN_STATE_ATK1, bl {
                                    //パンチに予備動作は無い
                                    $TIME1 = 10
                                    $TIME2 = 50
                                    $TIME3 = 60

                                    alpha = 0
                                    @if timer == 0 bl {
                                        cell = 2 + CELL_ENEMY4
                                        alpha = 12
                                        _setSpriteVel_XZ(pA, 0, 0)

                                        @se.play "Evade2" .opt(80, 60, 50)

                                    } .elif timer == $TIME1 bl {
                                        cell = 3 + CELL_ENEMY4
                                        alpha = 12

                                    } .elif timer == $TIME2 bl {
                                        cell = 2 + CELL_ENEMY4
                                        alpha = -12

                                    } .elif timer == $TIME3 bl {
                                        cell = 0 + CELL_ENEMY4
                                        alpha = -12
                                        state = EN_STATE_STAND
                                    }

                                    @if alpha != 0 bl {
                                        v[pA+MS_X] += dir * alpha * CC_U_POS
                                    }

                                    //攻撃判定
                                    @if `between(timer, $TIME1, $TIME1 + 8) bl {
                                        _setAttackParams( [ ATK_TYPE_DAMAGE2, SPR_FLAG_PLAYER, 1, ATK_SOUND_HIT2,
                                            12 * CC_U_POS, 10 * CC_U_POS,
                                            26 * CC_U_POS, 40 * CC_U_POS, 0 
                                        ] )
                                    }
                                },
                                EN_STATE_ATK2, bl {
                                    $TIME1 = 40
                                    $TIME2 = 80
                                    $TIME3 = 120
                                    $TIME4 = 130

                                    @if `between(timer, $TIME1, $TIME2) bl {
                                        cell = (timer % 4 < 2 ? 3 : 4) + CELL_ENEMY4
                                    }

                                    @if timer == 0 bl {
                                        cell = 2 + CELL_ENEMY4
                                        _setSpriteVel_XZ(pA, 0, 0)
                                        @se.play "Attack1" .opt(70, 100, 50)

                                    } .elif timer == $TIME1 bl {
                                        v[pA+MS_VX] = dir * 5 * CC_U_POS
                                        @se.play "Earth9" .opt(80, 130, 50)

                                    } .elif `timer == $TIME2 bl {
                                        cell = 3 + CELL_ENEMY4
                                        v[pA+MS_VX] = 0

                                    } .elif `timer == $TIME3 bl {
                                        cell = 2 + CELL_ENEMY4
                                        
                                    } .elif `timer > $TIME4 bl {
                                        state = EN_STATE_STAND
                                    }

                                    //攻撃判定
                                    @if `between(timer, $TIME1, $TIME2) bl {
                                        _setAttackParams( [ ATK_TYPE_DAMAGE3, SPR_FLAG_PLAYER, 1, ATK_SOUND_HIT3,
                                            20 * CC_U_POS, 8 * CC_U_POS,
                                            16 * CC_U_POS, 32 * CC_U_POS, 0 
                                        ] )
                                    }
                                } ],
                                bl {}
                            )
                        },
                        //フェイレン
                        //遠いと飛び蹴り、近いとラリアットを仕掛ける。倒すとアイテムを落とす
                        SPR_TYPE_ENEMY5, bl {
                            pseudoSwitchState(state,
                                [SPR_STATE_CREATE, bl {
                                    bitOn(flag, SPR_FLAG_GRAVITY | SPR_FLAG_SHADOW | SPR_FLAG_ENEMY)
                                    v[pA+MS_POINT] = 8

                                    state = EN_STATE_MOVE
                                    bitOn(flag, SPR_FLAG_AROUND)
                                    _setTargetParams( [0, 32, 32, -32, 32] )
                                },
                                EN_STATE_STAND, bl {
                                    $RND1 = 50
                                    $RND2 = 50
                                    $TIME1 = 40
                                    $TIME2 = 10
                                    $LENGTH1 = 24 * CC_U_POS
                                    $LENGTH2 = 80 * CC_U_POS

                                    cell = 0 + CELL_ENEMY5

                                    bitOn(flag, SPR_FLAG_AROUND)

                                    @if timer == 0 bl {
                                        _setSpriteVel_XZ(pA, 0, 0)
                                    }

                                    sx = abs(px - v[pA+MS_X])
                                    sz = abs(pz - v[pA+MS_Z])

                                    @if `IN_GAME && rnd(0, 99) < $RND1 && enemyAtkNum < 3 && sx < $LENGTH2 && timer == $TIME2 bl {
                                        state = EN_STATE_ATK1

                                    } .elif `IN_GAME && rnd(0, 99) < $RND2 && enemyAtkNum < 3 && sx > $LENGTH2 && timer == $TIME2 bl {
                                        state = EN_STATE_ATK2

                                    } .elif `(sx < $LENGTH1 && sz < $LENGTH1) || timer > $TIME1 bl {
                                        state = EN_STATE_MOVE
                                        _setTargetParams( [30, 48, 96, -16, 16] )
                                    }

                                },
                                EN_STATE_MOVE, bl {
                                    $TIME1 = 72
                                    cell = ((timer % 16 < 8) ? 1 : 0) + CELL_ENEMY5

                                    bitOn(flag, SPR_FLAG_AROUND)

                                    alpha = [4, 2, 1, 0][timer % 16 / 4]
                                    _setMoveParams( [alpha * CC_U_POS, 0] )

                                    sx = v[pA+MS_TX] - v[pA+MS_X]
                                    sz = v[pA+MS_TZ] - v[pA+MS_Z]
                                    @if `(!sx && !sz) || timer > $TIME1 bl {
                                        state = EN_STATE_STAND
                                    }
                                },
                                EN_STATE_ATK1, bl {
                                    $TIME1 = 32
                                    $TIME2 = 64
                                    $TIME3 = 96

                                    @if `timer == 0 || timer == $TIME2 bl {
                                        cell = 2 + CELL_ENEMY5
                                        _setSpriteVel_XZ(pA, 0, 0)

                                    } .elif timer == $TIME1 bl {
                                        _setSpriteTargetParams(pA, px, pz)
                                        _setMoveParams( [5 * CC_U_POS / 2, 0] )//2.5
                                        @se.play "Wind5" .opt(70, 120, 50)

                                    } .elif timer >= $TIME3 bl {
                                        state = EN_STATE_STAND
                                    }

                                    @if `between(timer, $TIME1, $TIME2 - 1) bl {
                                        cell = ((timer % 8 < 4) ? 4 : 5) + CELL_ENEMY5
                                        @if `timer % 8 == 0 bl {
                                            dir *= -1
                                        }

                                        //攻撃判定
                                        _setAttackParams( [ ATK_TYPE_DAMAGE1, SPR_FLAG_PLAYER, 1, ATK_SOUND_HIT1,
                                            20 * CC_U_POS, 20 * CC_U_POS,
                                            0, 24 * CC_U_POS, 0 
                                        ] )
                                    }
                                },
                                EN_STATE_ATK2, bl {
                                    $TIME1 = 32
                                    $TIME3 = 96
                                    //着地
                                    @if `v[pA+MS_Y] <= STAGE_MIN_Y && v[pA+MS_VY] <= 0 bl {
                                        cell = 2 + CELL_ENEMY5
                                        bitOn(flag, SPR_FLAG_AROUND)
                                        _setSpriteVel_XZ(pA, 0, 0)

                                        @if timer >= $TIME3 bl {
                                            state = EN_STATE_STAND
                                        }

                                    //跳び蹴り
                                    } .else bl {
                                        cell = 3 + CELL_ENEMY5

                                        //攻撃判定
                                        _setAttackParams( [ ATK_TYPE_DAMAGE2, SPR_FLAG_PLAYER, 1, ATK_SOUND_HIT2,
                                            6 * CC_U_POS, 8 * CC_U_POS,
                                            26 * CC_U_POS, 22 * CC_U_POS, 0 
                                        ] )
                                    }

                                    @if timer == $TIME1 bl {
                                        _setSpriteTargetParams(pA, px, pz)
                                        _setMoveParams( [4 * CC_U_POS, 0] )
                                        _setSpriteVel_Y(pA, 3 * CC_U_POS)

                                        @se.play "jump_anim" .opt(60, 100, 50)
                                    }
                                } ],
                                bl {}
                            )
                        },
                        //ヒットエフェクト
                        SPR_TYPE_HITEFF, bl {
                            cell = (timer < 4 ? 0 : 1) + CELL_HITEFF
                            @if timer > 8 bl {
                                state = SPR_STATE_DELETE
                            }
                        },
                        //肉まん
                        SPR_TYPE_ITEM1, bl {
                            pseudoSwitchState(state,
                                [SPR_STATE_CREATE, bl {
                                    state = SPR_STATE_ENABLE
                                    bitOn(flag, SPR_FLAG_GRAVITY | SPR_FLAG_SHADOW | SPR_FLAG_ITEM)
                                },
                                SPR_STATE_ENABLE, bl {
                                    //7秒経つと点滅する
                                    cell = (timer > UNIT_FPS * 7 && timer % 4 < 2) ? 0 : CELL_ITEM1
                                    //取得されたか、10秒経ったときに消える
                                    @if `v[pA+MS_HIT] > 0 || timer >= UNIT_FPS * 10 bl {
                                        state = SPR_STATE_DELETE

                                    //回復判定
                                    } .else bl {
                                        _setAttackParams( [ ATK_TYPE_ITEM1, SPR_FLAG_PLAYER, -HP_MAX, ATK_SOUND_ITEM1,
                                            8 * CC_U_POS, 8 * CC_U_POS,
                                            0, 0, 0 
                                        ] )
                                    }
                                } ],
                                bl {}
                            )
                        } ],
                        bl {}
                    )

                    //----------------------------
                    //敵キャラの目標位置や速度を更新する
                    @if `(flag & SPR_FLAG_ENEMY) && !IN_DAMAGE_MOTION bl {
                        //目標位置を再設定
                        @if `tagAround >= 0 bl {
                            sx = px - v[pA+MS_X]
                            sz = pz - v[pA+MS_Z]

                            //たまに回り込む
                            //画面端にいると確実に回り込む
                            @if `rnd(0,99) < tagAround ||
                                !between(v[pA+MS_X], STAGE_MIN_X + TARGET_MARGIN_X, STAGE_MAX_X - TARGET_MARGIN_X) bl {
                                V2_set(ex,
                                    px - (sx > 0 ? -1 : 1) * rnd(tagMinX, tagMaxX) * CC_U_POS,
                                    pz + (sz > 0 ? -1 : 1) * tagMaxZ * CC_U_POS
                                )
                                
                            } .else bl {
                                V2_set(ex,
                                    px + (sx > 0 ? -1 : 1) * rnd(tagMinX, tagMaxX) * CC_U_POS,
                                    pz + rnd(tagMinZ, tagMaxZ) * CC_U_POS
                                )
                            }

                            //目標位置を設定する
                            _setSpriteTargetParams(pA,
                                clamp(ex, STAGE_MIN_X + TARGET_MARGIN_X, STAGE_MAX_X - TARGET_MARGIN_X),
                                clamp(ey, STAGE_MIN_Z + TARGET_MARGIN_Z, STAGE_MAX_Z - TARGET_MARGIN_Z)
                            )
                        }

                        //敵キャラの速度を更新する
                        //ゼロだと停止し、負数だと無視される
                        @if moveSpeed >= 0 bl {
                            //真っ直ぐ移動する
                            @if moveSpeed > 0 bl {
                                V2_set(sx,
                                    v[pA+MS_TX] - v[pA+MS_X],
                                    v[pA+MS_TZ] - v[pA+MS_Z]
                                )
                                V2_clampMag(sx, moveSpeed)

                            //停止する
                            } .else bl {
                                V2_set(sx, 0, 0)
                            }

                            //速度を更新する
                            _setSpriteVel_XZ(pA, sx, sy)
                        }

                        //プレイヤーの方向を向く
                        @if `flag & SPR_FLAG_AROUND bl {
                            bitOff(flag, SPR_FLAG_AROUND)
                            dir = (v[pA+MS_X] < px) ? 1 : -1
                        }
                    }

                    //重力加速度
                    @if `flag & SPR_FLAG_GRAVITY bl {
                        v[pA+MS_VY] -= GRAVITY
                        //着地
                        @if `v[pA+MS_Y] <= STAGE_MIN_Y && v[pA+MS_VY] <= 0 bl {
                            v[pA+MS_Y] = STAGE_MIN_Y
                            v[pA+MS_VY] = 0
                        }
                    }

                    //速度を一度だけ初期化する
                    @if `flag & SPR_FLAG_RESET_V bl {
                        bitOff(flag, SPR_FLAG_RESET_V)
                        _setSpriteVelocity(pA, 0, 0, 0)
                    }

                    //位置を更新する
                    _setSpritePosition(pA,
                        clamp(v[pA+MS_X] + v[pA+MS_VX], STAGE_MIN_X, STAGE_MAX_X),
                        clamp(v[pA+MS_Y] + v[pA+MS_VY], STAGE_MIN_Y, STAGE_MAX_Y),
                        clamp(v[pA+MS_Z] + v[pA+MS_VZ], STAGE_MIN_Z, STAGE_MAX_Z)
                    )

                    //向きを更新する
                    @if `dir > 0 && (flag & SPR_FLAG_HREV) bl {
                        bitOff(flag, SPR_FLAG_HREV)

                    } .elif `dir < 0 && !(flag & SPR_FLAG_HREV) bl {
                        bitOn(flag, SPR_FLAG_HREV)
                    }

                    //状態を更新する
                    @if `state != v[pA+MS_STATE] bl {
                        _changeSpriteState(pA, state)
                    }

                    //セル番号を更新する
                    v[pA+MS_CELL] = cell

                    //フラグを更新する
                    v[pA+MS_FLAG] = flag

                    //----------------------------
                    //攻撃判定
                    //ゲーム中でなければ無視される
                    @if `atkType != ATK_TYPE_NONE && IN_GAME bl {
                        @loop SPR_NUM .dst(iB) {
                            _getSprPtr(pB, iB)
                            //攻撃判定の識別番号
                            $ATTACK_ID = iA + (type << 8) + (state << 16)
                            //自分自身 or 攻撃対象ではない or 回避状態ではない or 無効な状態 or 体力がない or 攻撃IDが一致した
                            alpha = v[pB+MS_FLAG]
                            @if `iA == iB ||
                                 !(alpha & atkTarget) ||
                                 (alpha & SPR_FLAG_EVADE) ||
                                 v[pB+MS_STATE] <= SPR_STATE_CREATE ||
                                 v[pB+MS_POINT] <= 0 ||
                                 v[pB+MS_HIT] == $ATTACK_ID bl {
                                @continue
                            }

                            //範囲判定
                            V3_set(sx,
                                v[pA+MS_X] - v[pB+MS_X] + atkX * dir,
                                v[pA+MS_Y] - v[pB+MS_Y] + atkY,
                                v[pA+MS_Z] - v[pB+MS_Z] + atkZ
                            )

                            @if `!between(sx, -atkRangeXY - SPR_WIDTH / 2, atkRangeXY + SPR_WIDTH / 2) ||
                                 !between(sy, -atkRangeXY, atkRangeXY + SPR_HEIGHT) ||
                                 !between(sz, -atkRangeZ - SPR_DEPTH / 2, atkRangeZ + SPR_DEPTH / 2) bl {
                                @continue
                            }

                            //対象がプレイヤーで、無敵チート状態だった場合、無視する
                            @if invincibleSwitch.isOn bl {
                                @if `alpha & SPR_FLAG_PLAYER  bl {
                                    @continue
                                }
                            }

                            //攻撃側がアイテムだった場合、攻撃側の変数にポインタを入力する
                            @if `flag & SPR_FLAG_ITEM bl {
                                v[pA+MS_HIT] = pB

                            //アイテム出ない場合、連続ヒットを防ぐ為に攻撃側の状態を登録する
                            } .else bl {
                                v[pB+MS_HIT] = $ATTACK_ID
                            }
                            
                            //体力を増減させる
                            v[pB+MS_POINT] = clamp(v[pB+MS_POINT] - atkPoint, 0, HP_MAX)
                            //体力表示
                            alpha = v[pB+MS_FLAG]
                            @if `alpha & SPR_FLAG_PLAYER bl {
                                bitOn(triggerFlg, TR_PL_HP)
                                playerHpGauge = v[pB+MS_POINT]

                            } .elif `alpha & SPR_FLAG_ENEMY bl {
                                bitOn(triggerFlg, TR_EN_HP)
                                enemyHpGauge = v[pB+MS_POINT]
                            }

                            //のけぞりが発生する
                            @if `between(atkType, ATK_TYPE_DAMAGE1, ATK_TYPE_DAMAGE3) bl {
                                //速度を初期化する
                                _setSpriteVelocity(pB, 0, 0, 0)
                                //向きを変える
                                alpha = v[pB+MS_FLAG]
                                beta = v[pB+MS_STATE]

                                @if `v[pA+MS_X] < v[pB+MS_X] bl {
                                    bitOn(alpha, SPR_FLAG_HREV)

                                } .else bl {
                                    bitOff(alpha, SPR_FLAG_HREV)
                                }

                                //プレイヤーが二度連続でダメージを受けると無敵状態になる
                                @if `(alpha & SPR_FLAG_PLAYER) &&
                                    between(beta, SPR_STATE_DAMAGE1, SPR_STATE_DAMAGE3) bl {
                                    bitOn(alpha, SPR_FLAG_EVADE)
                                }

                                //フラグを更新する
                                v[pB+MS_FLAG] = alpha
                                //セル番号
                                //タイプによって固定
                                v[pB+MS_CELL] = v[pB+MS_TYPE] - 1 + CELL_DAMAGE
                                //食らい動作とヒットストップと効果音
                                //吹っ飛ばされる
                                @if `v[pB+MS_POINT] <= 0 bl {
                                    _changeSpriteState(pB, SPR_STATE_DEFEATED)
                                    //強めのヒットストップが入る
                                    hitStop = max(hitStop, HITSTOP_STRONG)
                                    //効果音をすり替える
                                    atkSound = ATK_SOUND_DEFEATED
                                //のけぞり
                                } .else bl {
                                    alpha = [SPR_STATE_DAMAGE1, SPR_STATE_DAMAGE2, SPR_STATE_DAMAGE3][atkType - ATK_TYPE_DAMAGE1]
                                    _changeSpriteState(pB, alpha)
                                    //ヒットストップ
                                    hitStop = max(hitStop, HITSTOP_NORMAL)
                                }

                                //最後にヒットエフェクトを表示する
                                //攻撃を受けたキャラよりも手前に設置する
                                _getSprPtr(alpha, SPR_ID_HITEFF)
                                _setupSprite(alpha,
                                    SPR_TYPE_HITEFF,
                                    v[pA+MS_X] + atkX * dir + rnd(-atkRangeXY, atkRangeXY),
                                    v[pA+MS_Y] + atkY + rnd(-atkRangeXY, atkRangeXY) - 32 * CC_U_POS,
                                    v[pB+MS_Z] - 4 * CC_U_POS
                                )
                            }

                            //効果音
                            pseudoSwitchState(atkSound,
                                [ATK_SOUND_HIT1, bl {
                                    beta = rnd(17, 19) * 5
                                    @se.play "kick1" .opt(100, beta, 50)
                                },
                                ATK_SOUND_HIT2, bl {
                                    beta = rnd(19, 21) * 5
                                    @se.play "punch2" .opt(100, beta, 50)
                                },
                                ATK_SOUND_HIT3, bl {
                                    beta = rnd(19, 21) * 5
                                    @se.play "Blow4" .opt(100, beta, 50)
                                },
                                ATK_SOUND_ITEM1, bl {
                                    @se.play "Recovery3" .opt(100, 100, 50)
                                },
                                ATK_SOUND_DEFEATED, bl {
                                    beta = rnd(18, 22) * 5
                                    @se.play "hit_db" .opt(100, beta, 50)
                                }],
                                bl {}
                            )
                        }
                    }
                }

                //----------------------------
                //敵キャラの数や状態をカウントする
                enemyNum = 0
                enemyAtkNum = 0
                @loop SPR_NUM .dst(iA) bl {
                    _getSprPtr(pA, iA)
                    //スプライトの状態
                    state = v[pA+MS_STATE]
                    //スプライトのフラグ
                    flag = v[pA+MS_FLAG]

                    //未使用 or 消去予約でないか、敵じゃない
                    @if `state <= SPR_STATE_DELETE || !(flag & SPR_FLAG_ENEMY) bl {
                        @continue
                    }

                    //カウント
                    enemyNum += 1

                    //攻撃状態の敵をカウントする
                    @if state >= EN_STATE_READY1 bl {
                        enemyAtkNum += 1
                    }
                }
            }

            //----------------------------
            //スプライトを更新する
            @if `UPDATE_SPRITE bl {
                //----------------------------
                //ズームの基準点を更新する
                //プレイヤーを中心に拡大する
                _getSprPtr(pA, SPR_ID_PLAYER)

                @if `v[pA+MS_STATE] != SPR_STATE_NONE bl {
                    //拡大するとプレイヤーに寄っていく
                    V2_set(sx,
                        v[pA+MS_X] / CC_U_POS + SPR_OFFSET_X,
                        (v[pA+MS_Z] / SPR_DIV_Z * -1 - v[pA+MS_Y]) / CC_U_POS + SPR_OFFSET_Y
                    )

                    V2_set(zoomX,
                        clamp(sx, 0 + 160 * 100 / zoomScale, 320 - 160 * 100 / zoomScale),
                        clamp(sy, 0 + 120 * 100 / zoomScale, 240 - 120 * 100 / zoomScale)
                    )
                }

                //----------------------------
                //背景位置と色を更新する
                alpha = backGroundColor
                beta = 100

                V2_set(ex,
                    muldiv(CENTER_X - zoomX, zoomScale, 100) + CENTER_X,
                    muldiv(CENTER_Y - zoomY, zoomScale, 100) + CENTER_Y
                )

                @pic.show [PIC_BACK] .pos(ex, ey) .scale(zoomScale) .rgbs(alpha, alpha, alpha, beta) backPicCmd


                //----------------------------
                //スプライトの位置を更新する
                //初期化が予約されていた場合は初期化も行う
                @loop SPR_NUM .dst(iA) bl {
                    _getSprPtr(pA, iA)
                    //状態
                    state = v[pA+MS_STATE]
                    //処理を省略する
                    @if state == SPR_STATE_NONE bl {
                        @continue
                    }
                    //初期化する
                    @if state == SPR_STATE_DELETE bl {
                        _initSprMembers(pA)
                        _initSpritePicture(iA)
                        @continue
                    }

                    //スプライト
                    pid  = v[pA+MS_PID]
                    cell = v[pA+MS_CELL]
                    flag = v[pA+MS_FLAG]

                    //表示位置
                    V2_set(sx,
                        v[pA+MS_X] / CC_U_POS + SPR_OFFSET_X,
                        (v[pA+MS_Z] * SPR_MUL_Z / SPR_DIV_Z * -1 - v[pA+MS_Y]) / CC_U_POS
                    )

                    //ズーム補正
                    V2_set(ex,
                        muldiv(sx - zoomX, zoomScale, 100) + CENTER_X,
                        muldiv(sy + SPR_OFFSET_Y - zoomY, zoomScale, 100) + CENTER_Y
                    )

                    //左右反転
                    @if `flag & SPR_FLAG_HREV bl {
                        @pic.show [pid] .pos(ex, ey) .scale(zoomScale) .cell(cell) .hrev spritePicCmd

                    //通常
                    } .else {
                        @pic.show [pid] .pos(ex, ey) .scale(zoomScale) .cell(cell) spritePicCmd
                    }

                    //影
                    pid = PIC_SHADOW + iA
                    //更新
                    @if `flag & SPR_FLAG_SHADOW bl {
                        //表示位置
                        V2_set(sx,
                            v[pA+MS_X] / CC_U_POS + SPR_OFFSET_X,
                            v[pA+MS_Z] * SPR_MUL_Z / SPR_DIV_Z * -1 / CC_U_POS
                        )
                        
                        //ズーム補正
                        V2_set(ex,
                            muldiv(sx - zoomX, zoomScale, 100) + CENTER_X,
                            muldiv(sy + SHADOW_OFFSET_Y - zoomY, zoomScale, 100) + CENTER_Y
                        )

                        @pic.show [pid] .pos(ex, ey) .scale(zoomScale) shadowPicCmd

                    //隔離
                    } .else bl {
                        @pic.show [pid] .pos(OUT_RANGE, OUT_RANGE) .trans(100) shadowPicCmd
                    }
                }

                //----------------------------
                //スプライトのピクチャIDをソートする
                //Z座標とスプライトIDを列挙し、ピクチャIDをスプライトID順に並べる
                sortSprId.enum(0, SPR_NUM)
                @loop SPR_NUM .dst(iA) bl {
                    _getSprPtr(pA, iA)
                    //奥行を登録する
                    v[__id(sortDepth) + iA] = v[pA+MS_Z]
                    //移動元ピクチャID
                    sx = v[pA+MS_PID]
                    //移動先ピクチャID
                    sy = iA + PIC_SORTED
                    @pic[sx].setId .move(sy, 1)
                }

                //Z座標でスプライトIDを降順に並べ替える
                sortDepth.sortDescending(SPR_NUM) .sync(sortSprId)

                //並び替えた順にピクチャIDを移動させる
                @loop SPR_NUM .dst(iB) bl {
                    //スプライトID
                    iA = v[__id(sortSprId) + iB]
                    //移動元ピクチャID
                    sx = iA + PIC_SORTED
                    //移動先ピクチャID
                    sy = iB + PIC_SPRITE
                    @pic[sx].setId .move(sy, 1)
                    //メンバー変数に代入
                    _getSprPtr(pA, iA)
                    v[pA+MS_PID] = sy
                }
            }

            //----------------------------
            //トリガー
            triggerSwitchState(triggerFlg,
            [TR_PL_HP, bl {
                //プレイヤーHP
                V2_set(sx,
                    PL_HP_X + HP_GAUGE_WIDTH * clamp(playerHpGauge, 0, HP_GAUGE_MAX),
                    PL_HP_Y
                )
                @pic.move[PIC_HPBAR + 0] .pos(sx, sy) .topRight
            },
            TR_EN_HP, bl {
                //敵HP
                V2_set(sx,
                    EN_HP_X + HP_GAUGE_WIDTH * clamp(enemyHpGauge, 0, HP_GAUGE_MAX),
                    EN_HP_Y
                )
                @pic.move[PIC_HPBAR + 1] .pos(sx, sy) .topRight
            },
            TR_TIME_CNT, bl {
                //時間
                input = timeLimit / UNIT_FPS
                _showCounter(input, PIC_TIME_CNT, TIME_DIGIT, TIME_X, TIME_Y)
            },
            TR_SCORE, bl {
                //スコア
                _showCounter(score, PIC_SCORE_CNT, SCORE_DIGIT, SCORE_X, SCORE_Y)
                //実績
                checkSetAchievement(achievedCatLeg, score >= ACHIEVE_SCORE)
            }] )
        }
    }

    //------------------------------------------------------------------------------------
    //終了する
    @label.set "gameEnd"
    bl {
        _updateHighScore()

        initPicturesAndVariables(PIC_HEAD, NUM_OF_PIC, TV_MINIGAME, NUM_OF_VAR, 0, 0)
        restoreBGM()
        fastFadeInTintOnly(1)
    }
}