シーン:コース結果画面

ここではエキスパートモードのコース結果画面の制御方法について説明しています。コース結果画面は、コース内の曲が全て終了したあとや途中でゲームオーバーになると表示されます。

コース結果画面ではコースクリアか失敗か、ランク、EXゲージなどのグラフ表示、コース内の全トータル数やコース順位などを表示します。コース結果画面中に何らかのボタンが押されると終了のコールバックが呼び出されるので、これを利用して次の結果情報へ遷移させます。全ての結果が終わったらこのシーンを終了させることで、再びコース結果画面へ戻ります。
外部スクリプトファイル
システムスキンのサンプルでは、コース結果画面の処理は_08_courseresult.luaファイルにまとめられています。script.luaからこのファイルをinclude()関数を使って取り込むことで、最終的にscript.luaに定義されたものとして読み込まれます。
スクリプトによる制御方法
コース結果画面に遷移するとOnStartCourseResult()が呼び出されるので、ここでコース結果画面で使用するリソースをロードしたり変数の初期化などを行います。

コース結果画面で参照するゲームの結果情報はhdxGetCourseResult()から取得できますが、この関数はコース結果画面に遷移した直後から使用可能なため、OnStartCourseResult()内で呼び出し、コースの結果によりどの画像をロードするかなどの判定に利用することが出来ます。

次にコース結果画面中は毎フレームOnRunCourseResult()が呼び出されるので、ここで演算と画面描画を行います。

結果画面で何らかのボタンが押されるとOnCourseResultNext()が呼び出されます。これを利用して次の情報に遷移したり、hdxEndScene()を呼び出してコース結果画面を終了させます。
サンプルコード
このサンプルでは以下の処理を行っています。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// コース結果画面
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EXPST_START     = 0;            // フレーム表示
EXPST_FADEIN    = 1;            // 数値表示
EXPST_WAIT      = 2;            // 入力待ち
EXPST_FADEOUT   = 3;            // 終了

exp_pid_num_rank    = 0;
exp_pid_num_rank2   = 1;
exp_pid_num_score   = 2;
exp_pid_rankfrm_01  = 3;
exp_pid_rankfrm_02  = 4;
exp_pid_rankfrm_03  = 5;
exp_pid_rankfrm_04  = 6;


g_dwExpState        = EXPST_START;
g_iExpFadeCount     = -1;                       // 数値表示カウンタ(-1=非表示、0~10=表示)
g_iExpPkGreatPer    = 0;                        // ピカグレートの全体の%値
g_iExpGreatPer      = 0;                        // グレートの全体の%値
g_iExpGoodPer       = 0;                        // グッドの全体の%値
g_iExpBadPer        = 0;                        // バッドの全体の%値
g_iExpPoorPer       = 0;                        // プアの全体の%値


///////////////////////////////////////////////////////////////////////
// コース結果画面の開始時に呼び出される。
///////////////////////////////////////////////////////////////////////
function OnStartCourseResult()
    // コースの結果を取得
    local course = hdxGetCourseResult();

    // 初期化
    g_dwExpState        = EXPST_START;
    g_iExpFadeCount     = -1;
    g_iExpPkGreatPer    = math.floor( course["pkgreat"] / course["total_notes"] * 100 );    // %値を算出
    g_iExpGreatPer      = math.floor( course["great"]   / course["total_notes"] * 100 );
    g_iExpGoodPer       = math.floor( course["good"]    / course["total_notes"] * 100 );
    g_iExpBadPer        = math.floor( course["bad"]     / course["total_notes"] * 100 );
    g_iExpPoorPer       = math.floor( course["poor"]    / course["total_notes"] * 100 );

    // 画像ロード
    hdxLoadImage( 0,"ex_object.tga" );
    // 切り抜き
    hdxSetPutRange( exp_pid_num_rank    ,0, 8,434,168,20,0,0 );             // num_rank
    hdxSetPutRange( exp_pid_num_rank2   ,0, 8,312,432,50,0,0 );             // num_rank2
    hdxSetPutRange( exp_pid_num_score   ,0, 8,386,408,24,0,0 );             // num_score
    hdxSetPutRange( exp_pid_rankfrm_01  ,0, 8,8,234,128,0,0 );              // rankfrm_01
    hdxSetPutRange( exp_pid_rankfrm_02  ,0, 266,8,234,128,0,0 );            // rankfrm_02
    hdxSetPutRange( exp_pid_rankfrm_03  ,0, 8,160,234,128,0,0 );            // rankfrm_03
    hdxSetPutRange( exp_pid_rankfrm_04  ,0, 266,160,234,128,0,0 );          // rankfrm_04


    // アニメロード
    hdxLoadAnime( 0,"ex_bg.hda" );
    hdxCtrlAnime( 0,CTRLMODE_AUTO_END,0,0,-1 );                 // 最後のフレームで止める

    hdxLoadAnime( 1,"ex_frame.hda" );
    hdxCtrlAnime( 1,CTRLMODE_AUTO_END,0,0,-1 );                 // 最後のフレームで止める

    hdxLoadAnime( 2,"ex_fadeout.hda" );                         // フェードアウト
    hdxCtrlAnime( 2,CTRLMODE_MANUAL,-1,0,-1 );                  // 非表示

    if( course["clear"]==TRUE ) then
        // クリア
        hdxLoadAnime( 3,"ex_clear.hda" );
    else
        // 失敗
        hdxLoadAnime( 3,"ex_failed.hda" );
    end
    hdxCtrlAnime( 3,CTRLMODE_AUTO_END,0,0,-1 );                 // 最後のフレームで止める

    hdxLoadAnime( 4,"res_djlevel_"..course["rank"]..".hda" );   // 今回のDJLEVELアニメ
    hdxCtrlAnime( 4,CTRLMODE_AUTO_END,0,0,-1 );                 // 最後のフレームで止める

    // ランキング用
    hdxLoadAnime( 10,"res_rank_frm.hda" );                      // 今回の順位表示フレーム
    hdxCtrlAnime( 10,CTRLMODE_AUTO_END,0,0,-1 );                // 最後のフレームで止める

    hdxLoadAnime( 11,"res_rank_list.hda" );                     // ベストランクリスト
    hdxCtrlAnime( 11,CTRLMODE_AUTO_END,0,0,-1 );                // 最後のフレームで止める

    // タイトル名
    hdxCreateFont( 0, "メイリオ", 30, course["title"], 0xFFFFFFFF, 0xFFF080FF, 1, 0xFF000000 );

    // ニックネームフォント構築
    for i=0,course["ranking_count"]-1 do
        hdxCreateFont( i+10, "メイリオ", 24, course["ranking_nickname"..i], 0xFFFFFF, 0xFFFFFF, 1, 0x360086 );
        trace( "["..i.."] "..course["ranking_nickname"..i] );
    end

    // サウンド
    if( course["clear"]==TRUE ) then
        // クリア
        hdxLoadSound( 0,"ex_clear.wav" );
    else
        // 失敗
        hdxLoadSound( 0,"ex_failed.wav" );
    end
    // 再生
    hdxPlaySound( 0,FALSE );

end


///////////////////////////////////////////////////////////////////////
// コース結果画面で毎フレーム呼び出されるので、ここで演算と描画処理を行う。
///////////////////////////////////////////////////////////////////////
function OnRunCourseResult( upd_frm )
    // コースの結果を取得
    local course = hdxGetCourseResult();

    ///////////////////////////////////
    // 処理
    ///////////////////////////////////
    if( g_dwExpState==EXPST_START ) then
        if( hdxIsEndAnime(1)==TRUE ) then
            // 数値表示可意思
            g_iExpFadeCount = 0;
            g_dwExpState    = EXPST_FADEIN;
        end
    elseif( g_dwExpState==EXPST_FADEIN ) then
        g_iExpFadeCount = g_iExpFadeCount + 1;
        if( g_iExpFadeCount>=10 ) then
            // キー入力待ちへ
            g_iExpFadeCount = 10;
            g_dwExpState    = EXPST_WAIT;
        end
    elseif( g_dwExpState==EXPST_WAIT ) then
        // キー入力待ち
    elseif( g_dwExpState==EXPST_FADEOUT ) then
        if( hdxIsEndAnime(2)==TRUE ) then
            // フェード終了ならコース選択へ戻る
            trace( "コース結果画面終了" );
            hdxNextScene();
        end
    end


    ///////////////////////////////////
    // 描画
    ///////////////////////////////////
    hdxDrawAnime( 0,  0,  0, 1.0, 1.0 );                    // BG
    hdxDrawAnime( 1,  0,  0, 1.0, 1.0 );                    // FRAME
    hdxDrawAnime( 3,970,270, 1.0, 1.0 );                    // クリア・失敗アニメ
    hdxDrawAnime( 4, 94, 30, 1.0, 1.0 );                    // DJLEVEL(通常の結果アニメを流用するため、オフセットをずらす)

    // 表示状態か
    if( g_iExpFadeCount>=0 ) then
        // アルファ値を算出
        alpha   = g_iExpFadeCount / 10.0;

        // スコア数値
        hdxPutInt( exp_pid_num_score, 418, 421, course["pkgreat"],          alpha, ALIGNTYPE_RIGHTBOTTOM );
        hdxPutInt( exp_pid_num_score, 418, 458, course["great"],            alpha, ALIGNTYPE_RIGHTBOTTOM );
        hdxPutInt( exp_pid_num_score, 418, 495, course["good"],             alpha, ALIGNTYPE_RIGHTBOTTOM );
        hdxPutInt( exp_pid_num_score, 418, 532, course["bad"],              alpha, ALIGNTYPE_RIGHTBOTTOM );
        hdxPutInt( exp_pid_num_score, 418, 569, course["poor"],             alpha, ALIGNTYPE_RIGHTBOTTOM );

        // %値
        hdxPutInt( exp_pid_num_score, 548, 421, g_iExpPkGreatPer,           alpha, ALIGNTYPE_RIGHTBOTTOM );
        hdxPutInt( exp_pid_num_score, 548, 458, g_iExpGreatPer,             alpha, ALIGNTYPE_RIGHTBOTTOM );
        hdxPutInt( exp_pid_num_score, 548, 495, g_iExpGoodPer,              alpha, ALIGNTYPE_RIGHTBOTTOM );
        hdxPutInt( exp_pid_num_score, 548, 532, g_iExpBadPer,               alpha, ALIGNTYPE_RIGHTBOTTOM );
        hdxPutInt( exp_pid_num_score, 548, 569, g_iExpPoorPer,              alpha, ALIGNTYPE_RIGHTBOTTOM );

        // トータルEXスコア
        hdxPutInt( exp_pid_num_score, 550, 632, course["total_exscore"],    alpha, ALIGNTYPE_RIGHTBOTTOM );

        // ランキング情報
        hdxDrawAnime2( 10, 1088, 100, 1.0, 1.0, "_expDrawRank" );           // 今回の順位(中心指定)
        hdxDrawAnime2( 11,  732, 390, 1.0, 1.0, "_expDrawRankList" );       // ランキングリスト

        // タイトル名
        local sz = hdxGetFontSize(0);
        if( sz["width"]<484 ) then
            // 幅が収まるなら等倍表示
            hdxDrawFont( 0, 622, 64, alpha, ALIGNTYPE_CENTER );
        else
            // はみ出すならスケーリング表示
            hdxSetFilterMode( FILTER_LINEAR );                  // バイリニア
            hdxDrawFontEx( 0, 381, 49, 484, 30, alpha ); 
            hdxSetFilterMode( FILTER_POINT );
        end
    end

    hdxDrawAnime( 2, 0, 0, 1.0, 1.0 );                  // フェード
end


// 今回のランク表示
function _expDrawRank( layer,x,y,frm_x,frm_y,frm_sx,frm_sy,frm_alpha,frm_rot )
    if( layer==0 ) then
        // ロケーターなら
        local course = hdxGetCourseResult();        // 結果を取得
        // 順位フレーム
        local frm_id;
        if( course["current_ranking"]==1 ) then
            frm_id = exp_pid_rankfrm_01;
        elseif( course["current_ranking"]==2 ) then
            frm_id = exp_pid_rankfrm_02;
        elseif( course["current_ranking"]==3 ) then
            frm_id = exp_pid_rankfrm_03;
        else
            frm_id = exp_pid_rankfrm_04;
        end
        hdxSetPutStatus( frm_id, frm_alpha, frm_sx, frm_sy, frm_rot );
        hdxPut( frm_id, x+frm_x-110, y+frm_y-57 );                          // 左上に移動

        // 順位
        hdxPutInt( exp_pid_num_rank2, x+frm_x, y+frm_y+20, course["current_ranking"], frm_alpha, ALIGNTYPE_CENTER );

        return TRUE;
    end

    return FALSE;
end

// ランキングリスト
function _expDrawRankList( layer,x,y,frm_x,frm_y,frm_sx,frm_sy,frm_alpha,frm_rot )
    if( layer==1 ) then
        // ロケーターなら
        local course = hdxGetCourseResult();        // 結果を取得

        for i=0,course["ranking_count"]-1 do
            hdxPutInt( exp_pid_num_rank, x+frm_x+41, y+frm_y+44+i*22, course["ranking_num"..i], frm_alpha, ALIGNTYPE_CENTER );              // 順位

            hdxSetViewport( x+frm_x+61, y+frm_y+32, 280, 219 );                                                                             // ニックネーム部分をマスク
            hdxDrawFont( i+10, x+frm_x+70, y+frm_y+30+i*22, frm_alpha, ALIGNTYPE_LEFTTOP );                                                 // ニックネーム
            hdxSetViewport( 0, 0, 0, 0 );

            hdxPutInt( exp_pid_num_rank, x+frm_x+430, y+frm_y+54+i*22, course["ranking_exscore"..i], frm_alpha, ALIGNTYPE_RIGHTBOTTOM );    // EXスコア
        end

        return TRUE;
    end

    return FALSE;
end

///////////////////////////////////////////////////////////////////////
// コース結果画面内で次の表示に遷移したい場合に呼び出される。
// 通常はSTARTボタンを押したときに呼び出されるので、このタイミングで結果画面を切り替えていく。
///////////////////////////////////////////////////////////////////////
function OnCourseResult()
    if( g_dwExpState==EXPST_WAIT ) then
        hdxCtrlAnime( 2,CTRLMODE_AUTO_END,0,0,-1 );     // フェードアウト開始
        g_dwExpState = EXPST_FADEOUT;
    end
end