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

cev[CEV_BUTOBAS] .name("mg_ブトバス") {
    def {
        //使用する変数の個数
        NUM_OF_VAR = 256
        NUM_OF_STR = 0
        NUM_OF_PIC = 140
        //レイヤー
        BASE_LAYER = 6
        //ピクチャパス
        PATH_PALLET       = "cm\p8pa"
        PATH_FRAME        = "bs\fr"
        PATH_BACK         = "bs\ba"
        PATH_MAP_TILE     = "bs\mt"
        PATH_SMALL_CHARA  = "bs\cs"
        PATH_MIDDLE_CHARA = "bs\cm"
        PATH_SMALL_EFFECT = "bs\es"
        PATH_POWERUP      = "bs\pu"
        PATH_SMALL_NUM    = "bs\sn"
        PATH_FONT         = "bs\fo"
        PATH_TITLE        = "bs\ti"
        PATH_STAGE_DATA   = "bs\st"
        //ピクチャID
        PIC_HEAD        = 1
        PIC_STAGE_DATA  = 2
        PIC_BACK        = 3//+0_+2
        PIC_MAP_TILE    = 6//+0_+63
        PIC_CHARA_SMALL = 70//+0_+9
        PIC_CHARA_MIDDLE= 80//+0_+9
        PIC_EFFECT      = 90//+0_+7
        PIC_ADD_SCORE   = 100//+0_+2
        PIC_TITLE       = 105//+0_+2
        PIC_GAUGE       = 108
        PIC_POWERUP     = 109
        PIC_SCORE       = 110//+0_+5
        PIC_STAGE       = 116//+0_+4
        PIC_STRING_BACK = 121
        PIC_STRING      = 122//+0_+11
        PIC_FADE        = 135
        PIC_FRAME       = 136

        //シーン
        SC_ST_TITLE = 0
        SC_ST_ALLCLEAR
        SC_ST_GAME
        SC_ST_START
        SC_ST_LOAD
        SC_ST_CLEAR
        SC_ST_GAMEOVER

        //トリガー
        TR_BIT_INIT_PIC    = 1 << 0
        TR_BIT_INIT_CHARA  = 1 << 1
        TR_BIT_SCORE       = 1 << 2
        TR_BIT_ADD_SCORE   = 1 << 3
        TR_BIT_POWERUP     = 1 << 4
        TR_BIT_STAGE       = 1 << 5

        //ステージ
        MAP_SIZE = 8
        MAP_TILE_SIZE = 16
        MAP_X = 8
        MAP_Y = 12

        //プレイヤー
        PL_INIT_X = (MAP_X + 3 * MAP_TILE_SIZE + MAP_TILE_SIZE / 2) * UNIT_POS
        PL_INIT_Y = (MAP_Y + 5 * MAP_TILE_SIZE + MAP_TILE_SIZE / 2) * UNIT_POS
        PL_MOVE_SPEED = 2 * UNIT_POS
        PL_DUSH_SPEED = 5 * UNIT_POS
        PL_DUSH_TIMER = 8
        PL_DUSH_MASS = 10
        MASS_CORRECT = 4
        PL_INV_TIME = 60

        GET_MASS = (CH_MASS_PLAYER + powerUp * 4)

        //キャラクター
        //自機、アイテム、敵合わせて１０体まで置ける
        MAX_CHARA = 10

        MC_STATE = 0
        MC_TIMER
        MC_TYPE
        MC_BIT
        MC_DIR
        MC_ANG
        MC_MASS
        MC_PARAM_1
        MC_PARAM_2
        MC_X
        MC_Y
        MC_VX
        MC_VY
        SIZE_OF_CHARA

        CH_ID_PLAYER = 0
        CH_ID_ENEMY = 1

        CH_ST_NONE = 0
        CH_ST_DELETE
        CH_ST_INIT
        CH_ST_WAIT
        CH_ST_FALL
        CH_ST_ENABLE
        CH_ST_ACTIVE

        CH_TY_NONE = 0
        CH_TY_PLAYER
        CH_TY_POWERUP
        CH_TY_BOMB
        CH_TY_G_SLIME
        CH_TY_R_SLIME
        CH_TY_WIND
        CH_TY_BURST
        CH_TY_SHIELD
        CH_TY_BALL

        CH_MASS_PLAYER  = 10
        CH_MASS_POWERUP = 10
        CH_MASS_BOMB    = 10
        CH_MASS_G_SLIME =  8
        CH_MASS_R_SLIME = 12
        CH_MASS_WIND    = 18
        CH_MASS_BURST   = 10
        CH_MASS_SHIELD  = 30
        CH_MASS_BALL    = 50

        CH_CELL_PLAYER  = 1
        CH_CELL_POWERUP = 13
        CH_CELL_BOMB    = 19
        CH_CELL_G_SLIME = 25
        CH_CELL_R_SLIME = 31
        CH_CELL_WIND    = 37
        CH_CELL_BURST   = 49
        CH_CELL_SHIELD  = 61
        CH_CELL_BALL    = 1

        CH_DIR_RIGHT = 0
        CH_DIR_DOWN
        CH_DIR_LEFT
        CH_DIR_UP

        CH_BIT_PLAYER   = 1 << 0
        CH_BIT_ITEM     = 1 << 1
        CH_BIT_ENEMY    = 1 << 2
        CH_BIT_FALL     = 1 << 3
        CH_BIT_LOOP     = 1 << 4
        CH_BIT_MIDDLE   = 1 << 5
        CH_BIT_COLL     = 1 << 6
        CH_BIT_AWAY     = 1 << 7
        CH_BIT_COLLMAP  = 1 << 8
        CH_BIT_BRAKE    = 1 << 9
        CH_BIT_1DIR     = 1 << 10
        CH_BIT_2DIR     = 1 << 11
        CH_BIT_4DIR     = 1 << 12
        CH_BIT_FAST     = 1 << 13
        CH_BIT_BRINK    = 1 << 14

        CH_RAD_SMALL  =  6 * UNIT_POS
        CH_RAD_MIDDLE = 12 * UNIT_POS
        CH_RAD_ITEM   =  8 * UNIT_POS

        CH_HIT_POWER   = 8 * UNIT_POS
        CH_FALL_OFFSET = 2 * UNIT_POS
        CH_REMAIN_DIV  = 120

        //エフェクト
        MAX_EFFECT = 8

        ME_TYPE = 0
        ME_TIMER
        ME_X
        ME_Y
        SIZE_OF_EFFECT

        EF_TY_NONE = 0
        EF_TY_HIT
        EF_TY_EXP
        EF_TY_DUSH

        //強化
        MAX_POWERUP = 2
        POWERUP_X = SCREEN_WIDTH / 2
        POWERUP_Y = 6

        //ゲージ
        MAX_GAUGE = 1000
        GAUGE_X = SCREEN_WIDTH / 2
        GAUGE_Y = 10

        GET_GAUGE_SPEED = [15, 22, 30][powerUp]

        //スコア
        MAX_SCORE = 99999
        SCORE_DIGIT = 5
        SCORE_TIME = 90
        SCORE_X = 42
        SCORE_Y = 1
        ADD_SCORE_DIGIT = 3

        SCORE_POWERUP = 200
        SCORE_ENEMY_S = 100
        SCORE_ENEMY_M = 300
        SCORE_BOMB    = 150

        //文字列
        LI_ST_NONE = 0
        LI_ST_DELETE
        LI_ST_FIX
        LI_ST_PUT
        LI_ST_EASING

        //ステージ
        MAX_BACKGROUND = 3
        MAX_STAGE = 24
        STAGE_DATA_ROW = 8

        STAGE_NUM_X = 104
        STAGE_NUM_Y = 1
        STAGE_NUM_DIGIT = 2
        STAGE_NUM_PIC = 5

        STAGE_PX_MAP_MIN = 1
        STAGE_PX_MAP_MAX = 2
        STAGE_PX_CHARA_MIN = 9
        STAGE_PX_CHARA_MAX = 16

        //
        OUT_RANGE = -320
        UNIT_POS = 10
        SCREEN_WIDTH  = 128
        SCREEN_HEIGHT = 128
        FADE_TIME = 16
        MAX_STRING = 12
        CLOUD_WIDTH  = SCREEN_WIDTH / 2
        CLOUD_NUMER = 3
        REF_X = 104
        REF_Y = 56
        MID_FONT_WIDTH = 8
        SML_FONT_WIDTH  = 4
        SML_SPR_SIZE  = 8
        MID_SPR_SIZE = 16

        //
        IN_GAME_SCREEN = sceneState >= SC_ST_GAME
        SCORABLE = sceneState != SC_ST_GAMEOVER
        INPUT_DECISION = (iptDec == 1 || iptY == -1) && sceneTimer > 30
    }

    //アルファベット
    def {
        _A = 1
        _B
        _C
        _D
        _E
        _F
        _G
        _H
        _I
        _J
        _K
        _L
        _M
        _N
        _O
        _P
        _Q
        _R
        _S
        _T
        _U
        _V
        _W
        _X
        _Y
        _Z
        _EX
        _QU
        _SP
        _U0
        _U1
        _U2
        _0
        _1
        _2
        _3
        _4
        _5
        _6
        _7
        _8
        _9
        _SL
    }

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

        backPicCmd = bl {
            PATH_BACK
            .grid(6,1)
            basePicCmd
        }

        mapTilePicCmd = bl {
            PATH_MAP_TILE
            .grid(2,1)
            basePicCmd
        }

        smallCharaPicCmd = bl {
            PATH_SMALL_CHARA
            .grid(12,6)
            basePicCmd
        }

        middleCharaPicCmd = bl {
            PATH_MIDDLE_CHARA
            .grid(8,1)
            basePicCmd
        }

        smallEffectPicCmd = bl {
            PATH_SMALL_EFFECT
            .grid(6,3)
            basePicCmd
        }

        powerUpPicCmd = bl {
            PATH_POWERUP
            .grid(1,4)
            basePicCmd
        }

        smallNumberPicCmd = bl {
            PATH_SMALL_NUM
            .grid(10,1)
            basePicCmd
        }
        
        fontPicCmd = bl {
            PATH_FONT
            .grid(16,3)
            basePicCmd
        }

        titlePicCmd = bl {
            PATH_TITLE
            .grid(2,1)
            basePicCmd
        }

        palletPicCmd = bl {
            PATH_PALLET
            .grid(16, 1)
            basePicCmd
        }
    }

    defv {
        varHead = TV_MINIGAME

        ipt
        pid
        cell
        state
        timer
        type
        bit
        dir
        ang
        angPl
        vel
        rad
        pA
        pB
        pC
        iA
        iB
        iC
        fA
        fB
        fC
        fD
        ax
        ay
        bx
        by
        cx
        cy
        dx
        dy

        triggerFlg
        sceneState
        sceneTimer
        fadeTimer

        iptX
        iptY
        iptDec

        lineState
        lineLen
        lineX
        lineY

        initHead

        score
        addScore
        addScoreTimer
        addScoreX
        addScoreY
        updateHighScore
        stageCount
        bgScroll
        bgNum
        effectIdx
        instCnt
        enemyCount
        powerUp
        dushGauge
        invTime

        mapData
        charaHead = __id(mapData) + MAP_SIZE * 1
        effectHead = __id(charaHead) + MAX_CHARA * SIZE_OF_CHARA
        varFoot = __id(effectHead) + MAX_EFFECT * SIZE_OF_EFFECT
    }
    //変数の範囲を見る
    commentRangeOfVariables(varFoot, TV_MINIGAME, NUM_OF_VAR, NUM_OF_STR, NUM_OF_PIC)

    //シーンの状態を変える
    __fn _changeSceneState $state bl {
        v[__id(sceneState)..__id(sceneTimer)] = [$state, -1]
    }
    //数値を表示する
    //fA, fB, ax, ay, pid, cell
    __fn _showCounter $num $pid $dig $width $x $y bl {
        fB = 1
        @loop $dig .dst(fA) bl {
            v[__id(ax)..__id(ay)] = [($x) - fA * $width, ($y)]
            pid  = ($pid) + fA
            cell = (($num) < fB && fB != 1) ? (0) : (_0 + ($num) % (fB * 10) / fB)
            @pic.show [pid] .pos(ax, ay) .topRight .scale(100) .cell(cell) fontPicCmd  
            //次の桁
            fB *= 10
        }
    }
    //文字を設置する
    //fA,fB,fC
    __fn _setString $arr $len $state $ix $iy $cx $cy bl {
        v[__id(lineState)..__id(lineY)] = [$state, $len, $cx, $cy]
        @foreach $arr .dst(fA) {
            fC = PIC_STRING + fB
            @pic.show[fC] .pos(REF_X + ($ix), REF_Y + ($iy)) .center .cell(fA) fontPicCmd
        }
    }
    //スコアを追加する
    __fn _addScore $score $combo $x $y bl {
        __if $combo > 0 bl {
            v[__id(addScore)..__id(addScoreY)] = [addScore + ($score), SCORE_TIME, $x, $y]
            bitOn(triggerFlg, TR_BIT_ADD_SCORE)
        } .else bl {
            score = min(score + $score, MAX_SCORE)
            bitOn(triggerFlg, TR_BIT_SCORE)
        }
    }
    //スクリーン座標をマップ座標に変換する
    __fn _getPanelPosition $dvDes $dvSrc $unit {
        v[__id($dvDes)..__id($dvDes) + 1] = [(v[__id($dvSrc)] - MAP_X * $unit + MAP_TILE_SIZE * MAP_SIZE * $unit) / (MAP_TILE_SIZE * $unit) - MAP_SIZE, (v[__id($dvSrc) + 1] - MAP_Y * $unit + MAP_TILE_SIZE * MAP_SIZE * $unit) / (MAP_TILE_SIZE * $unit) - MAP_SIZE]
    }
    //マップ座標からスクリーン座標に変換する
    __fn _getPanelPositionOnScreen $dvDes $dvSrc $add $unit {
        v[__id($dvDes)..__id($dvDes) + 1] = [(MAP_X + v[__id($dvSrc)] * MAP_TILE_SIZE + $add) * $unit, (MAP_Y + v[__id($dvSrc) + 1] * MAP_TILE_SIZE + $add) * $unit]
    }
    //角度差を取得する
    __fn _getAngleDiff $dvDes $angA $angB {
        v[__id($dvDes)] = ($angB - $angA + 360) % 360
        v[__id($dvDes)] -= v[__id($dvDes)] > 180 ? 360 : 0
    }
    //マップ座標からマップ情報を取得する
    __fn _getMapTile $dvDes $dvPos {
        v[__id($dvDes)] = v[__id(mapData) + v[__id($dvPos) + 1]] & (1 << v[__id($dvPos) + 0])
    }
    //マップタイルを消去する
    __fn _deleteMapTile $dvPos {
        v[__id(mapData) + v[__id($dvPos) + 1]] &= (-1) ^ (1 << v[__id($dvPos) + 0])
    }
    //フェードイン
    __fn _fadeIn bl {
        fadeTimer = FADE_TIME + 1
    }
    //キャラを初期化する
    __fn _initChara $ptr $block bl {
        $block
        v[$ptr..$ptr + SIZE_OF_CHARA - 1] = [$state, $timer, $type, $bit, $dir, $angle, $mass, $param1, $param2, $x, $y, $vx, $vy]
    }
    //キャラのポインタを取得する
    __fn _getCharaPtr $dvPtr $idx bl {
        v[__id($dvPtr)] = __id(charaHead) + ($idx) * SIZE_OF_CHARA
    }
    //キャラの状態を変える
    __fn _setCharaState $ptr $state bl {
        v[$ptr + MC_STATE..$ptr + MC_TIMER] = [$state, -1]
    }

    //エフェクトを初期化する
    __fn _initEffect $ptr $block bl {
        $block
        v[$ptr..$ptr + SIZE_OF_EFFECT - 1] = [$type, $timer, $x, $y]
    }
    //エフェクトのポインタを取得する
    __fn _getEffectPtr $dvPtr $idx bl {
        v[__id($dvPtr)] = __id(effectHead) + ($idx) * SIZE_OF_EFFECT
    }
    //エフェクトのインデックスを進める
    __fn _nextEffect bl {
        effectIdx += 1
        effectIdx %= MAX_EFFECT
    }
    //------------------------------------------------------------------------------------
    //開始処理
    bl {
        initPicturesAndVariables(PIC_HEAD, NUM_OF_PIC, TV_MINIGAME, NUM_OF_VAR, TS_MINIGAME, NUM_OF_STR)
        storeAndStopBGM()
        msgBottom()
        
        @scr.tint .rgbs(50, 50, 50, 100) .time(1)
        //枠
        @pic.show[PIC_FRAME] PATH_FRAME .pos(0, 0) .topLeft basePicCmd
        //ステージデータ
        @pic.show[PIC_STAGE_DATA] PATH_STAGE_DATA .pos(0,0) .topLeft .trans(100) basePicCmd
        //無敵モード
        //invincibleSwitch.on
        @label.jump "gameLoop"
    }

    //------------------------------------------------------------------------------------
    //ゲーム処理
    @label.set "gameLoop"
    bl {
        //入力抑制
        iptDec = 2
        //最初にハイスコアをタイトルに表示する
        score = butobasScore
        //タイトル
        _changeSceneState(SC_ST_TITLE)
        _fadeIn()

        //----------------------------
        //ループ
        @loop bl {
            @wait(0)
            //----------------------------
            //ポーズ
            pauseProcces(TRUE, ipt, "gameEnd")

            //----------------------------
            //入力
            V2_getInput(iptX)
            //決定
            @key.input .dst(ipt) .decision
            iptDec = ipt ? iptDec + 1 : 0

            //----------------------------
            //シーン
            sceneTimer += 1

            pseudoSwitchState(sceneState,
            //ゲームシーン
            [ SC_ST_GAME, bl {
                //BGM
                @if sceneTimer == 0 bl {
                    startBGM("burst1_fc", FALSE, 0, 90, 100, 50)
                }

                //ゲームオーバー
                //プレイヤーが落ちて少し経った後
                _getCharaPtr(pA, CH_ID_PLAYER)
                @if `v[pA + MC_STATE] == CH_ST_FALL && v[pA + MC_TIMER] >= 60 bl {
                    //パワーアップが無いとゲームオーバー
                    //無敵モードがONだと残機が無限になる
                    @if `powerUp <= 0 && !invincibleSwitch bl {
                        _changeSceneState(SC_ST_GAMEOVER)
                    //パワーアップを減らして再開する
                    } .else bl {
                        //プレイヤー復帰
                        _getCharaPtr(pA, CH_ID_PLAYER)
                        _initChara(pA, bl {
                            $type = CH_TY_PLAYER
                            $state = CH_ST_INIT
                            $dir = CH_DIR_UP
                            $angle = CH_DIR_UP * 90
                            $x = PL_INIT_X
                            $y = PL_INIT_Y
                        } )
                        dushGauge = 0
                        invTime = PL_INV_TIME
                        powerUp = max(powerUp - 1, 0)

                        bitOn(triggerFlg, TR_BIT_POWERUP)
                        @se.play "fc_up1" .opt(90, 110, 50)
                    }
                //敵が一体もいなくなるとステージクリア
                } .elif enemyCount <= 0 bl {
                    _changeSceneState(SC_ST_CLEAR)
                }
            },
            //スタート
            SC_ST_START, bl {
                //画面初期化
                bitOn(triggerFlg, TR_BIT_SCORE | TR_BIT_POWERUP | TR_BIT_STAGE)

                //ゲームスタート
                _changeSceneState(SC_ST_LOAD)
            },
            //ステージを読み込む
            SC_ST_LOAD, bl {
                @if sceneTimer == 0 bl {
                    //STAGE 00
                    by = stageCount + 1
                    bx = by / 10 + _0
                    by = by % 10 + _0
                    _setString([_S,_T,_A,_G,_E,_SP,bx,by], 8, LI_ST_EASING, SCREEN_WIDTH + 16, SCREEN_HEIGHT / 2, SCREEN_WIDTH  / 2, SCREEN_HEIGHT / 2)

                    //背景
                    bgNum = (stageCount / STAGE_DATA_ROW) % MAX_BACKGROUND

                    //ステージデータを初期化する
                    v[__id(mapData)..__id(mapData) + MAP_SIZE - 1] = 0x00

                    //ステージピクチャを初期化する
                    ipt = MAP_SIZE * MAP_SIZE
                    @loop ipt .dst(pid) bl {
                        pid += PIC_MAP_TILE
                        hidePicture(pid)
                    }

                    //プレイヤーの開始位置は共通
                    _getCharaPtr(pA, CH_ID_PLAYER)
                    _initChara(pA, bl {
                        $type = CH_TY_PLAYER
                        $state = CH_ST_INIT
                        $dir = CH_DIR_UP
                        $angle = CH_DIR_UP * 90
                        $x = PL_INIT_X
                        $y = PL_INIT_Y
                    } )

                    effectIdx = 0
                    instCnt = CH_ID_ENEMY
                    enemyCount = 0
                    dushGauge = 0
                    invTime = 0

                }

                //一行ずつ読み込む
                $FRAME = 4
                @if `!(sceneTimer % $FRAME) bl {
                    ax = stageCount * MAP_SIZE
                    ay = sceneTimer / $FRAME
                    @if `ay < MAP_SIZE bl {
                        @loop MAP_SIZE .dst(iA) bl {
                            //マップ座標
                            V2_set(bx, ax + iA, ay)

                            //ピクセルを取得する
                            V2_set(cx, bx % (STAGE_DATA_ROW * MAP_SIZE), by + (stageCount / STAGE_DATA_ROW) * MAP_SIZE)
                            @pic.getInfo [PIC_STAGE_DATA] .pixel(cx, cy, 1, 1) .dst(ipt) .ignoreA .static
                            
                            //青色
                            fA = ipt & 0x000000ff
                            //マップタイル
                            fB = -1
                            //キャラがいる所にも適当に設置する
                            fC = -1

                            @if `between(fA, STAGE_PX_MAP_MIN, STAGE_PX_MAP_MAX) bl {
                                fB = (fA - STAGE_PX_MAP_MIN) % 2
                            }

                            @if `between(fA, STAGE_PX_CHARA_MIN, STAGE_PX_CHARA_MAX) bl {
                                fB = 0
                                fC = fA - STAGE_PX_CHARA_MIN + CH_TY_POWERUP
                            }

                            //マップタイル
                            //キャラがいる所にも適当に設置する
                            @if fB >= 0 bl {
                                V2_set(bx,
                                    REF_X + MAP_X + iA * MAP_TILE_SIZE,
                                    REF_Y + MAP_Y + ay * MAP_TILE_SIZE
                                )

                                v[__id(mapData) + ay] |= 1 << iA

                                pid = iA + ay * MAP_SIZE + PIC_MAP_TILE
                                cell = fB + 1

                                @pic.show[pid] .pos(bx, by) .topLeft .scale(50) .cell(cell) mapTilePicCmd
                                @pic.move[pid] .relative .pos(0, 0) .scale(50) .trans(0) .time(1)
                            }

                            //敵キャラ
                            @if `fC >= 0 && instCnt < MAX_CHARA bl {
                                V2_set(bx,
                                    (MAP_X + iA * MAP_TILE_SIZE + MAP_TILE_SIZE / 2) * UNIT_POS,
                                    (MAP_Y + ay * MAP_TILE_SIZE + MAP_TILE_SIZE / 2) * UNIT_POS
                                )

                                _getCharaPtr(pA, instCnt)
                                _initChara(pA, bl {
                                    $type = fC
                                    $state = CH_ST_INIT
                                    $dir = CH_DIR_DOWN
                                    $angle = CH_DIR_DOWN * 90
                                    $x = bx
                                    $y = by
                                } )

                                instCnt += 1
                            }
                        }
                    }
                }

                //開始する
                @if sceneTimer > 80 bl {
                    _changeSceneState(SC_ST_GAME)
                    lineState = LI_ST_DELETE

                    @se.play "fc_up1" .opt(90, 110, 50)
                }
            },
            //ステージクリア
            SC_ST_CLEAR, bl {
                //CLEAR
                @if sceneTimer == 0 bl {
                    _setString([_C,_L,_E,_A,_R], 5, LI_ST_EASING, SCREEN_WIDTH + 16, SCREEN_HEIGHT / 2, SCREEN_WIDTH  / 2, SCREEN_HEIGHT / 2)
                    @se.play "itemget2" .opt(100, 130, 50)
                }

                //次のステージへ
                @if `(stageCount + 1) < MAX_STAGE bl {
                    @if sceneTimer >= 90 bl {
                        stageCount += 1

                        //スコアの表示を消す
                        @if addScoreTimer > 0 bl {
                            addScoreTimer = 1
                        }

                        bitOn(triggerFlg, TR_BIT_INIT_CHARA | TR_BIT_STAGE)
                        _changeSceneState(SC_ST_LOAD)
                        lineState = LI_ST_DELETE
                    }
                } .else bl {
                    //クリア画面へ
                    @if sceneTimer >= 160 bl {
                        bitOn(triggerFlg, TR_BIT_INIT_CHARA | TR_BIT_INIT_PIC)
                        _changeSceneState(SC_ST_ALLCLEAR)
                        lineState = LI_ST_DELETE
                        _fadeIn()
                    }
                }
            },
            //全ステージクリア
            SC_ST_ALLCLEAR, bl {
                //ピクチャを設置する
                @if sceneTimer == 0 bl {
                    @pic.show[PIC_TITLE + 0] PATH_TITLE .pos(REF_X, REF_Y) .topLeft .cell(2) titlePicCmd
                    //スコアを表示する
                    bitOn(triggerFlg, TR_BIT_SCORE)
                    //BGMを止める
                    stopBGM(0)
                    @se.play "fc_clear06" .opt(90, 100, 50)
                }
                //タイトルに戻る
                @if `INPUT_DECISION bl {
                    _changeSceneState(SC_ST_TITLE)
                    bitOn(triggerFlg, TR_BIT_INIT_PIC)
                    _fadeIn()

                    //消去
                    lineState = LI_ST_DELETE
                    _fadeIn()

                    @se.stop
                    @se.play "fc_coin1" .opt(90, 80, 50)
                }
            },
            //ゲームオーバー
            SC_ST_GAMEOVER, bl {
                //GAMEOVER
                @if sceneTimer == 0 bl {
                    _setString([_G,_A,_M,_E,_O,_V,_E,_R], 8, LI_ST_EASING, SCREEN_WIDTH + 16, SCREEN_HEIGHT / 2, SCREEN_WIDTH  / 2, SCREEN_HEIGHT / 2)
                    stopBGM()

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

                //ボタンを押すとタイトルに戻る
                @if `INPUT_DECISION bl {
                    _changeSceneState(SC_ST_TITLE)

                    lineState = LI_ST_DELETE
                    bitOn(triggerFlg, TR_BIT_INIT_PIC)

                    _fadeIn()
                    @se.play "fc_coin1" .opt(90, 80, 50)
                }
            },
            //タイトル画面
            SC_ST_TITLE, bl {
                //ピクチャを設置する
                @if sceneTimer == 0 bl {
                    @pic.show[PIC_TITLE + 0] PATH_TITLE .pos(REF_X, REF_Y) .topLeft .cell(1) titlePicCmd
                    //スコアを表示する
                    bitOn(triggerFlg, TR_BIT_SCORE)
                    //BGMを止める
                    stopBGM(0)
                }
                //決定キーか上を押すと開始する
                @if `INPUT_DECISION bl {
                    _changeSceneState(SC_ST_START)

                    //変数初期化
                    assignVarUsingDeclared(initHead, varFoot, 0)
                    
                    score = 0
                    updateHighScore = FALSE

                    lineState = LI_ST_DELETE
                    bitOn(triggerFlg, TR_BIT_INIT_PIC)

                    _fadeIn()
                    @se.play "fc_coin1" .opt(90, 80, 50)
                }
            } ] )

            //----------------------------
            //ゲームシーン中の処理
            @if IN_GAME_SCREEN bl {
                //----------------------------
                //キャラクター
                //敵の数を数える
                enemyCount = 0

                @loop MAX_CHARA .dst(iA) bl {
                    _getCharaPtr(pA, iA)
                    state = v[pA + MC_STATE]
                    @if state <= CH_ST_NONE bl {
                        @continue
                    }
                    //タイマー
                    v[pA + MC_TIMER] += 1
                    timer = v[pA + MC_TIMER]
                    //一時変数
                    type = v[pA + MC_TYPE]
                    bit  = v[pA + MC_BIT]
                    dir  = v[pA + MC_DIR]
                    ang  = v[pA + MC_ANG]
                    cell = 0//共通処理の前に足しておく
                    rad  = (bit & CH_BIT_MIDDLE) ? (CH_RAD_MIDDLE) : (CH_RAD_SMALL)
                    vel  = 0

                    //敵かアイテムの場合、プレイヤーとの距離と角度を事前に測っておく
                    //dxに入れておく
                    //測れない場合、角度は-360になる
                    @if `bit & (CH_BIT_ITEM | CH_BIT_ENEMY) bl {
                        V2_set(dx, 0, 0)
                        angPl = -360

                        _getCharaPtr(pB, CH_ID_PLAYER)
                        @if `v[pB + MC_STATE] >= CH_ST_FALL bl {
                            V2_set(dx,
                                v[pB + MC_X] - v[pA + MC_X],
                                v[pB + MC_Y] - v[pA + MC_Y]
                            )
                            angPl = atan2(dy, dx, 1)
                        }
                    }

                    //タイプごとの処理
                    pseudoSwitchState(type,
                    //プレイヤー
                    //p1:ダッシュ持続
                    [CH_TY_PLAYER, bl {
                        cell = CH_CELL_PLAYER

                        pseudoSwitchState(state,
                        [CH_ST_ENABLE, bl {
                            //方向
                            //ダッシュ中は方向転換ができない
                            @if `(iptX || iptY) && v[pA + MC_PARAM_1] <= 0 bl {
                                ang = atan2(iptY, iptX, 1)
                            }
                            //ダッシュ
                            //何も入力していない場合は向いている方向へ飛ぶ
                            @if `iptDec == 1 && dushGauge <= 0 bl {
                                dushGauge = MAX_GAUGE
                                v[pA + MC_PARAM_1] = PL_DUSH_TIMER
                                //吹っ飛び状態がキャンセルされる
                                bitOff(bit, CH_BIT_AWAY)
                                //エフェクト
                                _getEffectPtr(pC, effectIdx)
                                _initEffect(pC, bl {
                                    $type = EF_TY_DUSH
                                    $x = v[pA + MC_X]
                                    $y = v[pA + MC_Y]
                                } )
                                _nextEffect()
                                @se.play "fc_laser1" .opt(100, 100, 50)
                            }

                            //吹っ飛ばされているとダッシュが中断される
                            @if `bit & CH_BIT_AWAY bl {
                                v[pA + MC_PARAM_1] = 0

                            } .else bl {
                                //ダッシュ中
                                @if `v[pA + MC_PARAM_1] > 0 bl {
                                    v[pA + MC_PARAM_1] -= 1
                                    vel = PL_DUSH_SPEED
                                //通常
                                } .elif `iptX || iptY bl {
                                    vel = PL_MOVE_SPEED
                                //停止
                                }
                            }

                            //重さと衝突判定
                            v[pA + MC_MASS] = GET_MASS
                            bitOn(bit, CH_BIT_FALL | CH_BIT_COLL)
                            //ダッシュ中は重くなり、落下しなくなる
                            @if `v[pA + MC_PARAM_1] > 0 bl {
                                v[pA + MC_MASS] += PL_DUSH_MASS
                                bitOff(bit, CH_BIT_FALL)
                            }
                            //点滅中は衝突せず、落下もしない
                            @if invTime > 0 bl {
                                cell = (invTime % 4 < 2) ? (0) : (cell)
                                bitOff(bit, CH_BIT_COLL | CH_BIT_FALL)
                            }
                        },
                        //初期化
                        CH_ST_INIT, bl {
                            state = CH_ST_WAIT
                            v[pA + MC_MASS] = CH_MASS_PLAYER
                            bitOn(bit, CH_BIT_PLAYER | CH_BIT_4DIR | CH_BIT_LOOP)
                        } ] )
                    },
                    //強化アイテム
                    CH_TY_POWERUP, bl {
                        cell = CH_CELL_POWERUP

                        pseudoSwitchState(state,
                        [CH_ST_ENABLE, bl {
                            cell += (timer % 60 >= 56) ? 1 : 0

                            //プレイヤーとの距離を測る
                            fA = CH_RAD_SMALL + CH_RAD_ITEM
                            @if `abs(dx) < fA && abs(dy) < fA bl {
                                //消える
                                state = CH_ST_DELETE
                                //パワーアップ済みの場合はスコアが得られる
                                @if powerUp >= MAX_POWERUP bl {
                                    @if `SCORABLE bl {
                                        _addScore(SCORE_POWERUP, 1, v[pA + MC_X] / UNIT_POS, v[pA + MC_Y] / UNIT_POS - 8)
                                        @se.play "fc_coin1" .opt(100, 80, 50)
                                    }
                                } .else bl {
                                    powerUp += 1
                                    bitOn(triggerFlg,TR_BIT_POWERUP)
                                    @se.play "fc_get1" .opt(80, 100, 50)
                                }
                            }
                        },
                        CH_ST_INIT, bl {
                            state = CH_ST_WAIT
                            v[pA + MC_MASS] = CH_MASS_POWERUP
                            bitOn(bit, CH_BIT_ITEM | CH_BIT_FALL | CH_BIT_COLL)
                        } ] )
                    },
                    //爆弾
                    //触れると一秒後に爆発し、床を壊す。着火するとすり抜けるようになる。
                    CH_TY_BOMB, bl {
                        cell = CH_CELL_BOMB

                        pseudoSwitchState(state,
                        [CH_ST_ENABLE, bl {
                            //触れると起動する
                            @if `bit & CH_BIT_AWAY bl {
                                state = CH_ST_ACTIVE
                                bitOff(bit, CH_BIT_COLL)
                            }                        
                        },
                        CH_ST_ACTIVE, {
                            //点滅
                            cell += (timer % 4 < 2) ? 1 : 0
                            //爆発する
                            @if timer >= 60 bl {
                                state = CH_ST_DELETE
                                bitOn(bit, CH_BIT_BRAKE)
                                @se.play "fc_explosion1" .opt(100, 100, 50)
                            }
                        },
                        CH_ST_INIT, bl {
                            state = CH_ST_WAIT
                            v[pA + MC_MASS] = CH_MASS_BOMB
                            bitOn(bit, CH_BIT_FALL | CH_BIT_COLL)
                        } ] )
                    },
                    //緑スライム
                    //停止、突進、回り込みをランダムに選び、不規則に動く
                    //p2:パターン
                    CH_TY_G_SLIME, {
                        cell = CH_CELL_G_SLIME

                        pseudoSwitchState(state,
                        [CH_ST_ENABLE, bl {
                            @if timer > 30 bl {
                                //連続で待機が選ばれない
                                @if `v[pA + MC_PARAM_2] <= 0 bl {
                                    v[pA + MC_PARAM_2] = rnd(1,3)
                                } .else bl {
                                    v[pA + MC_PARAM_2] = rnd(0,3)
                                }
                                v[pA + MC_TIMER] = 0
                            }
                            @if `v[pA + MC_PARAM_2] > 0 bl {
                                vel = 1 * UNIT_POS
                            }
                            @if `!(timer % 5) bl {
                                fA = v[pA + MC_PARAM_2]
                                fB = [angPl, angPl, angPl + 60, angPl - 60][fA] + 360//全体的に近づく
                                _getAngleDiff(fA, ang, fB)
                                ang += clamp(fA, -45, 45)
                            }
                        },
                        CH_ST_INIT, bl {
                            state = CH_ST_WAIT
                            v[pA + MC_MASS] = CH_MASS_G_SLIME
                            bitOn(bit, CH_BIT_ENEMY | CH_BIT_1DIR | CH_BIT_FALL | CH_BIT_COLL | CH_BIT_COLLMAP)
                        } ] )
                    },
                    //赤スライム
                    //停止、突進、回り込みをランダムに選び、不規則に動く
                    //シールドバリアと組むこともある
                    //p1:追従対象ID
                    //p2:パターン
                    CH_TY_R_SLIME, {
                        cell = CH_CELL_R_SLIME

                        pseudoSwitchState(state,
                        [CH_ST_ENABLE, bl {
                            iB = v[pA + MC_PARAM_1]
                            @if iB >= 0 bl {
                                _getCharaPtr(pB, iB)
                                //追従対象がいない
                                @if `v[pB + MC_STATE] < CH_ST_ENABLE bl {
                                    v[pA + MC_PARAM_1] = -1
                                    v[pA + MC_TIMER] = 0

                                //追従対象の前方に移動する
                                } .elif `!(bit & CH_BIT_BRINK) bl {
                                    fA = v[pB + MC_ANG]
                                    V2_getCosSin(bx, fA, 1, 20 * UNIT_POS)
                                    V2_set(ax,
                                        v[pB + MC_X] - v[pA + MC_X] + bx,
                                        v[pB + MC_Y] - v[pA + MC_Y] + by
                                    )
                                    V2_mag(fB, ax)
                                    vel = clamp(fB, -UNIT_POS, UNIT_POS)
                                    ang = atan2(ay, ax, 1)
                                }
                            //通常時
                            } .else bl {
                                //緑スライムと同じ
                                @if timer > 30 bl {
                                    //連続で待機が選ばれない
                                    @if `v[pA + MC_PARAM_2] <= 0 bl {
                                        v[pA + MC_PARAM_2] = rnd(1,3)
                                    } .else bl {
                                        v[pA + MC_PARAM_2] = rnd(0,3)
                                    }
                                    v[pA + MC_TIMER] = 0
                                }
                                @if `v[pA + MC_PARAM_2] > 0 bl {
                                    vel = 1 * UNIT_POS
                                }
                                @if `!(timer % 5) bl {
                                    fA = v[pA + MC_PARAM_2]
                                    fB = [angPl, angPl, angPl + 60, angPl - 60][fA] + 360//全体的に近づく
                                    _getAngleDiff(fA, ang, fB)
                                    ang += clamp(fA, -45, 45)
                                }
                            }
                        },
                        CH_ST_INIT, bl {
                            state = CH_ST_WAIT
                            v[pA + MC_MASS] = CH_MASS_R_SLIME
                            v[pA + MC_PARAM_1] = -1
                            bitOn(bit, CH_BIT_ENEMY | CH_BIT_1DIR | CH_BIT_FALL | CH_BIT_COLL | CH_BIT_COLLMAP)
                        } ] )
                    },
                    //ウィンド
                    //常に旋回しながら接近する
                    CH_TY_WIND, {
                        cell = CH_CELL_WIND

                        pseudoSwitchState(state,
                        [CH_ST_ENABLE, bl {
                            vel = 1 * UNIT_POS
                            @if `!(timer % 20) bl {
                                _getAngleDiff(fA, ang, angPl)
                                fC = angPl - (fA > 0 ? 1 : -1) * 40
                                _getAngleDiff(fA, ang, fC)
                                ang += clamp(fA, -60, 60)
                            }
                        },
                        CH_ST_INIT, bl {
                            state = CH_ST_WAIT
                            v[pA + MC_MASS] = CH_MASS_WIND
                            v[pA + MC_PARAM_1] = 32 * UNIT_POS//初期の目標距離
                            bitOn(bit, CH_BIT_ENEMY | CH_BIT_4DIR | CH_BIT_FALL | CH_BIT_COLL | CH_BIT_COLLMAP)
                        } ] )
                    },
                    //バースト
                    //一定時間停止した後、二度突進する
                    //吹っ飛び状態から復帰した瞬間に落下判定が生じる
                    //p1:吹っ飛び状態
                    CH_TY_BURST, {
                        cell = CH_CELL_BURST

                        pseudoSwitchState(state,
                        [CH_ST_ENABLE, bl {
                            fB = timer % 120                            
                            @if `between(fB, 60, 120) bl {
                                vel = 1 * UNIT_POS
                                @if `fB == 60 || fB == 90 bl {
                                    ang = ((angPl + 360 + 22) % 360) / 45 * 45
                                }
                            }

                            //状態を監視する
                            @if `v[pA + MC_PARAM_1] && !(bit & CH_BIT_AWAY) bl {
                                bitOn(bit, CH_BIT_FALL)
                            } .else bl {
                                bitOff(bit, CH_BIT_FALL)
                            }
                            v[pA + MC_PARAM_1] = bit & CH_BIT_AWAY
                        },
                        CH_ST_INIT, bl {
                            state = CH_ST_WAIT
                            v[pA + MC_MASS] = CH_MASS_BURST
                            bitOn(bit, CH_BIT_ENEMY | CH_BIT_4DIR | CH_BIT_FALL | CH_BIT_COLL)
                        } ] )
                    },
                    //シールド
                    //周囲の赤スライムを引き寄せ、周りに囲わせる
                    //p1:赤スライムのID
                    CH_TY_SHIELD, {
                        cell = CH_CELL_SHIELD

                        pseudoSwitchState(state,
                        [CH_ST_ENABLE, bl {
                            iB = v[pA + MC_PARAM_1]
                            @if iB >= 0 bl {
                                vel = 1 * UNIT_POS / 4

                                _getCharaPtr(pB, iB)
                                @if `v[pB + MC_STATE] < CH_ST_ENABLE bl {
                                    v[pA + MC_PARAM_1] = -1
                                }
                            //周辺を調べて、引き入れる赤スライムを探す
                            } .else bl {
                                vel = 8 * UNIT_POS / 10

                                @if `!(timer % 30) bl {
                                    @loop MAX_CHARA .dst(iB) bl {
                                        _getCharaPtr(pB, iB)
                                        fB = v[pB + MC_STATE]
                                        @if `v[pB + MC_TYPE] != CH_TY_R_SLIME || fB != CH_ST_ENABLE || v[pB + MC_PARAM_1] >= 0 bl {
                                            @continue
                                        }
                                        V2_set(ax,
                                            v[pA + MC_X] - v[pB + MC_X],
                                            v[pA + MC_Y] - v[pB + MC_Y]
                                        )
                                        V2_mag(fB, ax)
                                        @if fB < 32 * UNIT_POS bl {
                                            v[pA + MC_PARAM_1] = iB
                                            v[pB + MC_PARAM_1] = iA
                                            @break
                                        }
                                    }
                                }
                            }
                            @if `!(timer % 10) bl {
                                _getAngleDiff(fA, ang, angPl)
                                ang += clamp(fA, -20, 20)
                            }
                        },
                        CH_ST_INIT, bl {
                            state = CH_ST_WAIT
                            v[pA + MC_MASS] = CH_MASS_SHIELD
                            v[pA + MC_PARAM_1] = -1
                            bitOn(bit, CH_BIT_ENEMY | CH_BIT_4DIR | CH_BIT_FALL | CH_BIT_COLL | CH_BIT_COLLMAP)
                        } ] )
                    },
                    //ボール
                    //方向転換中は重さが減る
                    //p1:スリップ
                    CH_TY_BALL, {
                        cell = CH_CELL_BALL

                        pseudoSwitchState(state,
                        [CH_ST_ENABLE, bl {
                            vel = 1 * UNIT_POS / 2

                            @if `!(bit & CH_BIT_AWAY) && !(timer % 20) bl {
                                _getAngleDiff(fA, ang, angPl)
                                ang += clamp(fA, -30, 30)
                                v[pA + MC_PARAM_1] = abs(fA) >= 60 ? 1 : 0
                            }

                            @if `v[pA + MC_PARAM_1] bl {
                                v[pA + MC_MASS] = CH_MASS_BALL / 2
                                bitOn(bit, CH_BIT_FAST)
                            } .else bl {
                                v[pA + MC_MASS] = CH_MASS_BALL
                                bitOff(bit, CH_BIT_FAST)
                            }
                        },
                        CH_ST_INIT, bl {
                            state = CH_ST_WAIT
                            v[pA + MC_MASS] = CH_MASS_BALL
                            bitOn(bit, CH_BIT_ENEMY | CH_BIT_2DIR | CH_BIT_MIDDLE | CH_BIT_FALL | CH_BIT_COLL | CH_BIT_COLLMAP)
                        } ] )
                    } ] )

                    //通常
                    @if state >= CH_ST_ENABLE bl {
                        //速度
                        //吹っ飛ばされていると移動速度が減る
                        V2_set(ax, v[pA + MC_VX], v[pA + MC_VY])
                        @if `bit & CH_BIT_AWAY bl {
                            //減速する
                            V2_muldiv(ax, ax, 100, CH_REMAIN_DIV)
                            //完全に停止すると吹っ飛び状態を解除する
                            @if `abs(ax) <= 1 && abs(ay) <= 1 bl {
                                V2_set(ax, 0, 0)
                                bitOff(bit, CH_BIT_AWAY)
                            }      
                        } .else bl {
                            V2_getCosSin(ax, ang, 1, vel)
                        }
                        v[pA + MC_VX] = ax
                        v[pA + MC_VY] = ay

                        //移動
                        v[pA + MC_X] += v[pA + MC_VX]
                        v[pA + MC_Y] += v[pA + MC_VY]

                        //座標ループ
                        $MIN = -8 * UNIT_POS
                        $MAX = (SCREEN_WIDTH + 8) * UNIT_POS
                        @if `bit & CH_BIT_LOOP bl {
                            v[pA + MC_X] = (v[pA + MC_X] - $MIN + $MAX - $MIN) % ($MAX - $MIN) + $MIN
                            v[pA + MC_Y] = (v[pA + MC_Y] - $MIN + $MAX - $MIN) % ($MAX - $MIN) + $MIN
                        //座標を拘束
                        } .else bl {
                            v[pA + MC_X] = clamp(v[pA + MC_X], $MIN, $MAX)
                            v[pA + MC_Y] = clamp(v[pA + MC_Y], $MIN, $MAX)
                        }
                        //向きを0-360の範囲に留める
                        ang = (ang + 360) % 360
                        //向き変更
                        //移動方向と現在の向きを比較して向きを変える
                        _getAngleDiff(fA, ang, dir * 90)
                        @if `abs(fA) > 45 bl {
                            dir = ((ang + 360 + 45) % 360) / 90
                        }
                        //向きに合わせてセル番号を加算する
                        //吹っ飛ばされているとアニメーションしない
                        @if `bit & CH_BIT_AWAY bl {
                            fA = 0
                        } .else bl {
                            //フラグによってアニメーションが加速する
                            fB = timer * ((bit & CH_BIT_FAST) ? 2 : 1)
                            easyAnimation(fA, TRUE, 0, 1, fB, 6)
                        }
                        @if cell == 0 bl {
                            //セル番号がゼロだとスルーする
                        } .elif `bit & CH_BIT_4DIR bl {
                            cell += dir * 2 + fA
                        } .elif `bit & CH_BIT_2DIR bl {
                            cell += (dir % 2) * 2 + fA
                        } .elif `bit & CH_BIT_1DIR bl {
                            cell += fA
                        } .else bl {
                            //設定していない場合はアニメーションなし
                        }
                        //マップ端で方向が変わる
                        //吹っ飛んでいるときは判定しない
                        @if `(bit & CH_BIT_COLLMAP) && !(bit & CH_BIT_AWAY) bl {
                            bitOff(bit, CH_BIT_BRINK)

                            fB = rad - 2 * UNIT_POS
                            @loop 4 .dst(iB) bl {
                                //右、下、左、上
                                V2_set(cx,
                                    [ 1, 0, -1, 0][iB],
                                    [ 0, 1,  0,-1][iB]
                                )
                                V2_set(ax,
                                    v[pA + MC_X] + fB * cx,
                                    v[pA + MC_Y] + fB * cy + CH_FALL_OFFSET
                                )
                                _getPanelPosition(bx, ax, UNIT_POS)
                                @if `between(bx, 0, MAP_SIZE - 1) && between(by, 0, MAP_SIZE - 1) bl {
                                    _getMapTile(fA, bx)
                                } .else bl {
                                    fA = 0
                                }
                                @if fA == 0 bl {
                                    //反射
                                    getReflection(bx, by, fA,
                                    v[pA + MC_VX], v[pA + MC_VY], -cx * UNIT_NORMAL, -cy * UNIT_NORMAL, 0, 0, UNIT_REFLECTION, UNIT_REFLECTION)
                                    @if fA < 0 bl {
                                        ang = atan2(by, bx, 1)
                                        v[pA + MC_VX] = bx
                                        v[pA + MC_VY] = by
                                    }
                                    //反射はせずとも少しずつ寄っていく
                                    v[pA + MC_X] -= cx
                                    v[pA + MC_Y] -= cy
                                    //フラグ
                                    bitOn(bit, CH_BIT_BRINK)
                                }
                            }
                        }
                        //落下判定
                        //斜め四方を調べて、床に付いていなければ落ちる
                        //判定の広さは(半径-2)
                        @if `bit & CH_BIT_FALL bl {
                            fA = 0
                            fB = rad - 2 * UNIT_POS
                            @loop 5 .dst(iB) bl {
                                //中央、左上、右上、左下、右下
                                //判定を若干下にずらす
                                V2_set(ax,
                                    v[pA + MC_X] + fB * [0, -1, 1, -1, 1][iB],
                                    v[pA + MC_Y] + fB * [0 ,-1,-1,  1, 1][iB] + CH_FALL_OFFSET
                                )
                                _getPanelPosition(bx, ax, UNIT_POS)
                                @if `between(bx, 0, MAP_SIZE - 1) && between(by, 0, MAP_SIZE - 1) bl {
                                    _getMapTile(fA, bx)
                                    @if `fA bl {
                                        @break
                                    }
                                }
                            }
                            //落下する
                            @if fA <= 0 bl {
                                state = CH_ST_FALL
                                bitOff(bit, CH_BIT_COLL)
                            }
                        }
                    //落下
                    } .elif state == CH_ST_FALL bl {
                        @if timer == 0 bl {
                            @se.play "fc_fall1" .opt(90, 90, 50)
                        }

                        //位置をマップチップの中央に寄せる
                        $D = 2
                        V2_set(ax,
                            v[pA + MC_X],
                            v[pA + MC_Y] + CH_FALL_OFFSET
                        )
                        _getPanelPosition(bx, ax, UNIT_POS)
                        _getPanelPositionOnScreen(ax, bx, MAP_TILE_SIZE / 2, UNIT_POS)
                        v[pA + MC_X] += clamp(ax - v[pA + MC_X], -$D, $D)
                        v[pA + MC_Y] += clamp(ay - v[pA + MC_Y], -$D, $D)

                        //落下すると消える
                        @if timer >= (3 - 0 + 2) * 8 bl {
                            cell = 0
                            //プレイヤーは消えずにゲームの終了を待つ
                            @if type != CH_TY_PLAYER bl {
                                state = CH_ST_NONE
                            }
                            //スコアを得る
                            @if `bit & CH_BIT_ENEMY bl {
                                fA = (bit & CH_BIT_MIDDLE) ? (SCORE_ENEMY_M) : (SCORE_ENEMY_S)
                            } .elif `type == CH_TY_BOMB bl {
                                fA = SCORE_BOMB
                            } .else bl {
                                fA = 0
                            }
                            @if fA > 0 bl {
                                @if `SCORABLE bl {
                                    _addScore(fA, 1, v[pA + MC_X] / UNIT_POS, v[pA + MC_Y] / UNIT_POS - 8)
                                    @se.play "fc_coin1" .opt(70, 140, 50)
                                }
                            }
                        } .else bl {
                            //落下アニメーション
                            easyAnimation(fA, FALSE, 0, 3, timer, 8)
                            cell += fA
                            @if `bit & CH_BIT_4DIR bl {
                                cell += 8
                            } .elif `bit & CH_BIT_2DIR bl {
                                cell += 4
                            } .elif `bit & CH_BIT_1DIR bl {
                                cell += 2
                            } .else bl {
                                cell += 2
                            }
                        }
                    //待機状態
                    } .elif state == CH_ST_WAIT bl {
                        //ゲーム開始と同時に起動する
                        @if sceneState == SC_ST_GAME bl {
                            state = CH_ST_ENABLE
                        }
                        //向き
                        @if cell == 0 bl {
                            //セル番号がゼロだとスルーする
                        } .elif `bit & CH_BIT_4DIR bl {
                            cell += dir * 2
                        } .elif `bit & CH_BIT_2DIR bl {
                            cell += dir % 2 * 2
                        } .elif `bit & CH_BIT_1DIR bl {
                        } .else bl {
                        }
                    }

                    //爆破処理
                    @if `bit & CH_BIT_BRAKE bl {
                        //1Fのみ有効
                        bitOff(bit, CH_BIT_BRAKE)
                        //斜め四方を調べて、床があれば落ちる
                        //判定の広さは半径と同じ
                        fB = rad
                        @loop 5 .dst(iB) bl {
                            //中央、左上、右上、左下、右下
                            //判定を若干下にずらす
                            V2_set(ax,
                                v[pA + MC_X] + fB * [0, -1, 1, -1, 1][iB],
                                v[pA + MC_Y] + fB * [0, -1,-1,  1, 1][iB] + CH_FALL_OFFSET
                            )
                            _getPanelPosition(bx, ax, UNIT_POS)
                            @if `between(bx, 0, MAP_SIZE - 1) && between(by, 0, MAP_SIZE - 1) bl {
                                _getMapTile(fA, bx)
                                @if `fA bl {
                                    //マップ書き換え
                                    _deleteMapTile(bx)
                                    //ピクチャを非表示にする
                                    pid = PIC_MAP_TILE + bx + by * MAP_SIZE
                                    hidePicture(pid)
                                    //エフェクト
                                    _getEffectPtr(pC, effectIdx)
                                    _initEffect(pC, bl {
                                        $type = EF_TY_EXP
                                        $x = (MAP_X + bx * MAP_TILE_SIZE + MAP_TILE_SIZE / 2) * UNIT_POS
                                        $y = (MAP_Y + by * MAP_TILE_SIZE + MAP_TILE_SIZE / 2) * UNIT_POS
                                    } )
                                    _nextEffect()
                                }
                            }
                        }
                    }

                    //変数を更新する
                    @if `v[pA + MC_STATE] != state bl {
                        _setCharaState(pA, state)
                    }
                    v[pA + MC_BIT] = bit
                    v[pA + MC_DIR] = dir
                    v[pA + MC_ANG] = ang

                    //ピクチャID
                    pid = ((bit & CH_BIT_MIDDLE) ? (PIC_CHARA_MIDDLE) : (PIC_CHARA_SMALL)) + iA
                    //消去する
                    @if state == CH_ST_DELETE bl {
                        _setCharaState(pA, CH_ST_NONE)
                        hidePicture(pid)
                    } .else bl {
                        //敵の数をカウントする
                        @if `bit & CH_BIT_ENEMY bl {
                            enemyCount += 1
                        }
                        //ピクチャを更新する
                        V2_set(ax,
                            REF_X + v[pA + MC_X] / UNIT_POS,
                            REF_Y + v[pA + MC_Y] / UNIT_POS
                        )
                        //中
                        @if `bit & CH_BIT_MIDDLE bl {
                            @pic.show[pid] .pos(ax, ay) .center .cell(cell) middleCharaPicCmd
                        //小
                        } .else bl {
                            @pic.show[pid] .pos(ax, ay) .center .cell(cell) smallCharaPicCmd
                        }
                    }
                }

                //----------------------------
                //キャラクター同士の衝突判定
                //起動状態か、衝突フラグが立っていないと衝突しない
                @loop MAX_CHARA .dst(iA) bl {
                    _getCharaPtr(pA, iA)
                    @if `v[pA + MC_STATE] < CH_ST_ENABLE || !(v[pA + MC_BIT] & CH_BIT_COLL)  bl {
                        @continue
                    }
                    cell = MAX_CHARA - (iA + 1)
                    @loop cell .dst(iB) bl {
                        iB += iA + 1
                        _getCharaPtr(pB, iB)
                        @if `v[pB + MC_STATE] < CH_ST_ENABLE || !(v[pB + MC_BIT] & CH_BIT_COLL) bl {
                            @continue
                        }

                        //衝突の組み合わせ
                        $BITMASK_TYPE = (CH_BIT_PLAYER | CH_BIT_ITEM | CH_BIT_ENEMY)
                        bit = v[pA + MC_BIT] | v[pB + MC_BIT]
                        //質量の合計
                        ipt = v[pA + MC_MASS] + v[pB + MC_MASS]

                        //質量の合計がゼロ
                        //アイテムとプレイヤーの組み合わせ
                        //片方がプレイヤーでかつ、無敵状態
                        @if `ipt <= 0 || (bit & $BITMASK_TYPE) == (CH_BIT_PLAYER | CH_BIT_ITEM) bl {
                            @continue
                        }

                        //衝突判定
                        circleToCircle(timer, ax, ay, bx, by, cx, cy, dx, dy,
                        v[pA + MC_X], v[pA + MC_Y], v[pA + MC_X] + v[pA + MC_VX], v[pA + MC_Y] + v[pA + MC_VY] + v[pA + MC_VY], (v[pA + MC_BIT] & CH_BIT_MIDDLE) ? (CH_RAD_MIDDLE) : (CH_RAD_SMALL), v[pA + MC_MASS],
                        v[pB + MC_X], v[pB + MC_Y], v[pB + MC_X] + v[pB + MC_VX], v[pB + MC_Y] + v[pB + MC_VY] + v[pB + MC_VY], (v[pB + MC_BIT] & CH_BIT_MIDDLE) ? (CH_RAD_MIDDLE) : (CH_RAD_SMALL), v[pB + MC_MASS]
                        )
                        //衝突していない
                        @if timer < 0 bl {
                            @continue
                        }
                        //衝突角度
                        //8方向に制限する
                        //でないと難しくなる
                        ang = atan2(cy, cx, 1)
                        ang = ((ang + 360 + 22) % 360) / 45 * 45
                        V2_getCosSin(cx, ang, 1, UNIT_NORMAL)
                        //衝突の勢い
                        //敵同士だと半分になる
                        @if `(bit & $BITMASK_TYPE) == CH_BIT_ENEMY bl {
                            vel = CH_HIT_POWER / 2
                        } .else bl {
                            vel = CH_HIT_POWER
                        }
                        fA = muldiv(v[pB + MC_MASS], vel, ipt)
                        fB = muldiv(v[pA + MC_MASS], vel, ipt)
                        //位置と速度を修正し、ヒットフラグを立てる
                        v[pA + MC_VX] = muldiv(cx, fA, UNIT_NORMAL)
                        v[pA + MC_VY] = muldiv(cy, fA, UNIT_NORMAL)
                        v[pA + MC_X] = ax + muldiv(1000 - timer, v[pA + MC_VX], UNIT_SECOND)
                        v[pA + MC_Y] = ay + muldiv(1000 - timer, v[pA + MC_VY], UNIT_SECOND)
                        v[pA + MC_BIT] |= CH_BIT_AWAY

                        v[pB + MC_VX] = muldiv(cx, -fB, UNIT_NORMAL)
                        v[pB + MC_VY] = muldiv(cy, -fB, UNIT_NORMAL)
                        v[pB + MC_X] = bx + muldiv(1000 - timer, v[pB + MC_VX], UNIT_SECOND)
                        v[pB + MC_Y] = by + muldiv(1000 - timer, v[pB + MC_VY], UNIT_SECOND)
                        v[pB + MC_BIT] |= CH_BIT_AWAY

                        //敵同士だと音が小さくなり、エフェクトも出ない
                        @if `(bit & $BITMASK_TYPE) == CH_BIT_ENEMY bl {
                            @se.play "fc_punch1" .opt(60, 80, 50)

                        } .else bl {
                            fA = rnd(7, 9) * 10
                            @se.play "fc_punch1" .opt(100, fA, 50)

                            _getEffectPtr(pC, effectIdx)
                            _initEffect(pC, bl {
                                $type = EF_TY_HIT
                                $x = dx
                                $y = dy
                            } )
                            _nextEffect()
                        }
                    }
                }

                //----------------------------
                //エフェクト
                @loop MAX_EFFECT .dst(iA) bl {
                    _getEffectPtr(pA, iA)
                    type = v[pA + ME_TYPE]
                    @if type <= EF_TY_NONE bl {
                        @continue
                    }
                    //タイマー
                    v[pA + ME_TIMER] += 1
                    timer = v[pA + ME_TIMER]
                    //ピクチャID
                    //タイプごとに設定する
                    pid = PIC_EFFECT + iA
                    //セル番号
                    easyAnimation(cell, FALSE, 1, 6, timer, 3)
                    cell += (type - 1) * 6
                    //時間で消去する
                    @if timer >= (6 - 1 + 1) * 3 bl {
                        v[pA + ME_TYPE] = EF_TY_NONE
                        hidePicture(pid)
                    } .else bl {
                        //ピクチャ更新
                        V2_set(ax,
                            REF_X + v[pA + ME_X] / UNIT_POS,
                            REF_Y + v[pA + ME_Y] / UNIT_POS
                        )
                        @pic.show[pid] .pos(ax, ay) .center .cell(cell) smallEffectPicCmd
                    }
                }

                //----------------------------
                //スコア表示
                @if addScoreTimer > 0 bl {
                    addScoreTimer -= 1
                    @if addScoreTimer <= 0 bl {
                        //スコア表示を消す
                        @loop ADD_SCORE_DIGIT .dst(iA) bl {
                            pid = PIC_ADD_SCORE + iA
                            hidePicture(pid)
                        }
                    }
                }

                //----------------------------
                //背景スクロール
                bgScroll += 1
                bgScroll %= CLOUD_WIDTH * 4 * UNIT_POS
                @loop CLOUD_NUMER .dst(iA) bl {
                    pid = PIC_BACK + iA
                    cell = 1 + bgNum * 2 + (iA + bgScroll / UNIT_POS / CLOUD_WIDTH) % 2
                    V2_set(ax,
                        REF_X - CLOUD_WIDTH + iA * CLOUD_WIDTH + bgScroll / UNIT_POS % CLOUD_WIDTH,
                        REF_Y
                    )
                    @pic.show[pid] .pos(ax, ay) .topLeft .cell(cell) backPicCmd
                }

                //----------------------------
                //クールタイムと無敵時間
                //プレイヤーが操作可能な状態のとき
                _getCharaPtr(pA, CH_ID_PLAYER)
                @if `v[pA + MC_STATE] >= CH_ST_ENABLE bl {

                    @if invTime > 0 bl {
                        invTime -= 1
                    }

                    @if dushGauge > 0 bl {
                        dushGauge -= GET_GAUGE_SPEED

                        @if dushGauge <= 0 bl {
                            dushGauge = 0
                            @se.play "fc_jump1" .opt(80, 130, 50)
                        }
                    }

                    //ゲージ
                    V2_set(ax,
                        lerp(100 * 3, 0, dushGauge, MAX_GAUGE),
                        20
                    )
                    cell = dushGauge == 0 ? 12 : 13
                    @pic.show[PIC_GAUGE] .pos(REF_X + GAUGE_X, REF_Y + GAUGE_Y) .center .scale2(ax, ay) .cell(cell) palletPicCmd

                }
            }

            //----------------------------
            //文字列
            @if lineState > LI_ST_NONE bl {
                //削除
                @if lineState == LI_ST_DELETE bl {
                    @loop lineLen .dst(pid) bl {
                        pid += PIC_STRING
                        hidePicture(pid)
                    }
                    hidePicture(PIC_STRING_BACK)
                    lineState = LI_ST_NONE
                    lineLen = 0
                //何もしない
                } .elif lineState == LI_ST_FIX bl {

                //指定した位置に置く
                } .elif lineState == LI_ST_PUT bl {
                    lineState = LI_ST_FIX
                    @loop lineLen .dst(iA) bl {
                        pid = PIC_STRING + iA
                        V2_set(ax,
                            REF_X + lineX + iA * MID_FONT_WIDTH - lineLen * MID_FONT_WIDTH / 2 + MID_FONT_WIDTH / 2,
                            REF_Y + lineY
                        )
                        @pic.move[pid] .pos(ax, ay) .center
                    }
                    //黒帯
                    V2_set(ax,
                        REF_X + SCREEN_WIDTH / 2,
                        REF_Y + lineY
                    )
                    @pic.show[PIC_STRING_BACK] .pos(ax, ay) .center .scale2(100 * 16, 0) .cell(2) palletPicCmd
                    @pic.move[PIC_STRING_BACK] .relative .pos(0, 0) .trans(0) .scale2(0, 150) .time(2)

                //イージング
                } .elif lineState == LI_ST_EASING bl {
                    @loop lineLen .dst(iA) bl {
                        //時間差
                        @if `sceneTimer < iA * 4 bl {
                            @break
                        }
                        pid = PIC_STRING + iA
                        V2_set(ax,
                            REF_X + lineX + iA * MID_FONT_WIDTH - lineLen * MID_FONT_WIDTH / 2 + MID_FONT_WIDTH / 2,
                            REF_Y + lineY
                        )
                        @pic.move[pid] .pos(ax, ay) .center .time(1)
                    }
                    //黒帯
                    @if sceneTimer == 0 bl {
                        V2_set(ax,
                            REF_X + SCREEN_WIDTH / 2,
                            REF_Y + lineY
                        )
                        @pic.show[PIC_STRING_BACK] .pos(ax, ay) .center .scale2(100 * 16, 0) .cell(2) palletPicCmd
                        @pic.move[PIC_STRING_BACK] .relative .pos(0, 0) .trans(0) .scale2(0, 150) .time(1)
                    }
                }
            }
            
            //----------------------------
            //フェードイン
            @if fadeTimer > 0 bl {
                fadeTimer -= 1
                @if fadeTimer <= 0 bl {
                    hidePicture(PIC_FADE)
                } .else bl {
                    fA = lerp(100, 0, fadeTimer, FADE_TIME)
                    V2_set(ax,
                        REF_X + SCREEN_WIDTH  / 2,
                        REF_Y + lerp(SCREEN_HEIGHT / 2, 0, fA, 100)
                    )
                    V2_set(bx,
                        100 * 16,
                        lerp(100 * SCREEN_HEIGHT / 8, 0, fA, 100)
                    )
                    @pic.show[PIC_FADE] .pos(ax, ay) .center .scale2(bx, by) .cell(1) palletPicCmd
                }
            }

            //----------------------------
            triggerSwitchState(triggerFlg,
            [TR_BIT_INIT_PIC, bl {
                //タイトル
                hidePicture(PIC_TITLE + 0)
                //パワーアップ
                hidePicture(PIC_POWERUP)
                //ゲージ
                hidePicture(PIC_GAUGE)
                //背景
                @loop 3 .dst(pid) bl {
                    pid += PIC_BACK
                    hidePicture(pid)
                }
                //エフェクト(上)
                @loop MAX_EFFECT .dst(pid) bl {
                    pid += PIC_EFFECT
                    hidePicture(pid)
                }
                //キャラクタ(小)
                @loop MAX_CHARA .dst(pid) bl {
                    pid += PIC_CHARA_SMALL
                    hidePicture(pid)
                }
                //キャラクタ(中)
                @loop MAX_CHARA .dst(pid) bl {
                    pid += PIC_CHARA_MIDDLE
                    hidePicture(pid)
                }
                //スコア
                @loop SCORE_DIGIT .dst(pid) bl {
                    pid += PIC_SCORE
                    hidePicture(pid)
                }
                //ステージ番号
                @loop STAGE_NUM_PIC .dst(pid) bl {
                    pid += PIC_STAGE
                    hidePicture(pid)
                }
                //獲得スコア
                @loop ADD_SCORE_DIGIT .dst(pid) bl {
                    pid += PIC_ADD_SCORE
                    hidePicture(pid)
                }
                //マップタイル
                ipt = MAP_SIZE * MAP_SIZE
                @loop ipt .dst(pid) bl {
                    pid += PIC_MAP_TILE
                    hidePicture(pid)
                }
            },
            TR_BIT_INIT_CHARA, bl {
                //キャラを消去する
                @loop MAX_CHARA .dst(iA) {
                    _getCharaPtr(pA, iA)
                    @if `v[pA + MC_STATE] > CH_ST_DELETE bl {
                        v[pA + MC_STATE] = CH_ST_DELETE
                    }
                }
            },
            TR_BIT_SCORE, bl {
                _showCounter(score, PIC_SCORE, SCORE_DIGIT, MID_FONT_WIDTH, REF_X + SCORE_X, REF_Y + SCORE_Y)
                //ハイスコアの更新判定
                @if score > butobasScore bl {
                    //更新した瞬間に音が鳴る
                    //ハイスコアが0だった場合は除く
                    @if `butobasScore > 0 && !updateHighScore bl {
                        @se.play "itemget2" .opt(80, 130, 50)
                    }
                    updateHighScore = TRUE
                    butobasScore = score
                }
            },
            TR_BIT_ADD_SCORE, bl {
                //表示位置を画面内に収める
                addScoreX = clamp(addScoreX,  8, SCREEN_WIDTH  - 8)
                addScoreY = clamp(addScoreY, 16, SCREEN_HEIGHT - 4)

                fA = 0
                @loop ADD_SCORE_DIGIT .dst(iA) bl {
                    $NUM = pow(10, iA)
                    fA += (addScore / $NUM) > 0 ? 1 : 0
                }
                @if fA > 0 bl {
                    V2_set(ax,
                        REF_X + addScoreX + fA * SML_FONT_WIDTH / 2 + 2,
                        REF_Y + addScoreY
                    )
                    @loop ADD_SCORE_DIGIT .dst(iA) bl {
                        pid = PIC_ADD_SCORE + iA
                        $NUM = pow(10, iA)
                        cell = (iA >= fA) ? (0) : (1 + addScore / $NUM % 10)
                        @pic.show[pid] .pos(ax, ay) .topRight .cell(cell) smallNumberPicCmd
                        @pic.move[pid] .relative .pos(0, -8) .scale(0) .trans(0) .time(10)
                        ax -= SML_FONT_WIDTH
                    }
                    //スコア加算
                    score = min(score + addScore, MAX_SCORE)
                    addScore = 0
                    bitOn(triggerFlg, TR_BIT_SCORE)
                }
            },
            TR_BIT_POWERUP, bl {
                cell = 1 + powerUp
                @pic.show[PIC_POWERUP] .pos(REF_X + POWERUP_X, REF_Y + POWERUP_Y) .center .scale(200) .cell(cell) powerUpPicCmd
                @pic.move[PIC_POWERUP] .pos(REF_X + POWERUP_X, REF_Y + POWERUP_Y) .center .scale(100) .time(4)
            },
            TR_BIT_STAGE, bl {
                ipt = stageCount + 1
                _showCounter(ipt, PIC_STAGE, STAGE_NUM_DIGIT, MID_FONT_WIDTH, REF_X + STAGE_NUM_X, REF_Y + STAGE_NUM_Y)
                // /
                @pic.show[PIC_STAGE + 2] .pos(REF_X + STAGE_NUM_X + 8 * 0, REF_Y + STAGE_NUM_Y) .topLeft .cell(_SL) fontPicCmd
                // 最大値
                @pic.show[PIC_STAGE + 3] .pos(REF_X + STAGE_NUM_X + 8 * 1, REF_Y + STAGE_NUM_Y) .topLeft .cell(_0 + MAX_STAGE / 10) fontPicCmd
                @pic.show[PIC_STAGE + 4] .pos(REF_X + STAGE_NUM_X + 8 * 2, REF_Y + STAGE_NUM_Y) .topLeft .cell(_0 + MAX_STAGE % 10) fontPicCmd
            } ] )
        }
    }

    //------------------------------------------------------------------------------------
    //終了する
    @label.set "gameEnd"
    bl {
        initPicturesAndVariables(PIC_HEAD, NUM_OF_PIC, TV_MINIGAME, NUM_OF_VAR, TS_MINIGAME, NUM_OF_STR)
        restoreBGM()
        @scr.tint .rgbs(100, 100, 100, 100) .time(1) .wait
    }
}