シーン:ログイン・プレイモード

ここではログイン・プレイモード画面の制御方法について説明しています。

この画面では、通信プレイを行うためのログイン処理と、シングルかダブルかを選択するプレイモード選択を行います。なお、ログイン処理はシステムが行いますが、ログイン画面の表示はスクリプトにて指示する必要があります。

ログイン画面ではID、パスワードの入力が専用のフレーム内に表示されます。この時、スキンデザインに合わせられるようにフレームの色をRGB値で指定することが出来ます。

なお、ログイン画面はウィンドウサイズに合わせて自動的にスケーリング表示されるため、スクリプト側では基本的にログインフレームを表示する場所を考えて描画関数を呼び出すだけです。

ログイン画面が終わればそのままプレイモード選択画面となり、この時プレイモード開始のコールバックが呼び出されますが、その際リソースの初期化は行われません。これはログイン画面を後ろに残したままプレイモードの選択を行う場合を想定しているためで、プレイモード開始時にリソースが開放されてしまった場合、再度ロードし直す際に一瞬画面が停止してしまうといった問題を回避出来ます。このため、このシーンで使用するリソースはログイン画面開始時のコールバック内で全てロードしておくような制御を行ってください。

※ログイン画面の上にプレイモード選択画面を表示
外部スクリプトファイル
システムスキンのサンプルでは、ログイン・プレイモード画面の処理は_03_playmode.luaファイルにまとめられています。script.luaからこのファイルをinclude()関数を使って取り込むことで、最終的にscript.luaに定義されたものとして読み込まれます。
スクリプトによる制御方法
まずログイン画面に遷移すると一度だけOnStartLogin()が呼び出されるので、ここでログインとプレイモード画面で使用するリソースをロードしたり、変数の初期化などを行います。

次にログイン画面中は毎フレームOnRunLogin()が呼ばれるので、ここでログイン画面用の演算と画面描画などを行います。

この中でスキンの背景などを描画したのち、hdxDrawLoginFrame()を呼び出すことでその上にログインフレームを表示することが出来ます。ただし、このログインフレームはhdxOpenLoginFrame()を呼び出すまで表示は行われません。これを利用して、まず独自デザインのログイン画面のアニメーションを行ってから、そのあとでログインフレームを表示させるといったタイミングを調整することが出来ます。

なお、このゲームはログインを行わないスキンというのは実質作成出来ません。必ずどこかでhdxOpenLoginFrame()を呼び出す必要があり、これを呼び出さなかった場合はこの先に遷移することは出来ません。

ログインしたかログインがキャンセルされるとOnStartPlayMode()が呼び出されます。ここでプレイモード用の初期化を行いますが、ここでリソースなどをロードすると一瞬処理落ちが発生するため、ここでは基本的に変数などの初期化のみを行います。なお、OnStartPlayMode()の引数にはログイン状態とプレイモードの初期選択位置が渡されるので、これを最初のプレイモード表示に利用します。なお、ログインエラーはシステムの表示が行われるため、特にスクリプト側で処理をする必要はありません。

プレイモード画面中は毎フレームOnRunPlayMode()が呼ばれるので、ここでプレイモード用の演算と画面描画などを行います。

スクラッチを回すことで選択中のプレイモードが移動しますが、この時プレイモードが変化するごとにOnChangePlayMode()が呼び出されます。また、この関数の引数には新たに選択された項目が渡されるので、これを利用して画面に反映させます。

鍵盤が押されプレイモードが決定されるとOnEndPlayMode()が呼び出されます。また、この時最後に決定したプレイモードが引数に渡されますが、タッチ操作などによりOnChangePlayMode()が呼び出されずに直接この関数が呼び出されることがあるため、OnChangePlayMode()と同様に必ず画面に反映させてください。

OnEndPlayMode()が呼び出されたあとはhdxNextScene()を呼び出してこのシーンを終了させますが、もし決定時の演出を行いたい場合はOnEndPlayMode()内では演出を開始させるだけにして、OnRunPlayMode()内でその演出が終了するのを待ってからhdxNextScene()を呼び出すようにします。
サンプルコード
このサンプルでは以下の処理を行っています。

ログイン・プレイモード画面用スクリプト

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ログイン・プレイモード選択
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// ログインステート
LOGINST_TVANIME     = 0;
LOGINST_LOGIN       = 1;

g_dwLoginState = LOGINST_TVANIME;

///////////////////////////////////////////////////////////////////////
// ログイン画面が呼び出される際に呼び出される。
///////////////////////////////////////////////////////////////////////
function OnStartLogin()
    // ステート初期化
    g_dwLoginState = LOGINST_TVANIME;

    // 3Dモデルロード
    hdxMatrixRotationX( 0,hdxToRadian(90) );        // 3dsMax座標補正
    hdxLoadModel( 0,"title.x",0 );

    // アニメーションロード
    hdxLoadAnime( 0,"pm_tvanime.hda",0 );           // TVアニメ
    hdxCtrlAnime( 0,CTRLMODE_AUTO_END,0,0,-1 );     // 最初から最後まで再生

    hdxLoadAnime( 1,"pm_playmode.hda",0 );          // プレイモード背景
    hdxCtrlAnime( 1,CTRLMODE_MANUAL,-1,0,-1 );      // 初期状態では非表示とする
    
    hdxLoadAnime( 2,"pm_cursor.hda",0 );            // プレイモードカーソル
    hdxCtrlAnime( 2,CTRLMODE_MANUAL,-1,0,-1 );      // 初期状態では非表示とする

    hdxLoadAnime( 3,"pm_finish.hda",10 );           // プレイモード終了アニメ(サウンドは10~)
    hdxCtrlAnime( 3,CTRLMODE_MANUAL,-1,0,-1 );      // 初期状態では非表示とする

    hdxLoadAnime( 4,"lighting.hda",0 );             // 背景ライティング
    hdxCtrlAnime( 4,CTRLMODE_AUTO_LOOP,0,0,-1 );    // 

    hdxLoadAnime( 5,"pm_logo.hda",0 );              // charatbeatHDX VIOLET onlineロゴ
    hdxCtrlAnime( 5,CTRLMODE_AUTO_LOOP,0,75,-1 );   // 開始位置は-1のままで、終了位置まで来たら指定したフレームに戻りループさせる

    // プレイモード用画像のロード
    hdxLoadImage( 0,"pm_image.tga" );
    // 切り抜き
    hdxSetPutRange( 0,0,544,384,458,380,0,0 );          // FRAME_SINGLE
    hdxSetPutRange( 1,0,544,0,458,380,0,0 );            // FRAME_DOUBLE
    hdxSetPutRange( 2,0,0,624,224,144,0,0 );            // LIGHT_SINGLE
    hdxSetPutRange( 3,0,0,472,401,144,0,0 );            // LIGHT_DOUBLE
    hdxSetPutRange( 4,0,0,0,542,464,40,35 );            // SELECT_CURSOR
    hdxSetPutRange( 5,0,232,624,148,30,74,15 );         // STANDARD_OFF
    hdxSetPutRange( 6,0,384,624,148,30,74,15 );         // EXPERT_OFF
    hdxSetPutRange( 7,0,232,656,148,30,74,15 );         // DANI_OFF
    hdxSetPutRange( 8,0,384,656,148,30,74,15 );         // FREE_OFF
    hdxSetPutRange( 9,0,232,688,148,30,74,15 );         // STANDARD_ON
    hdxSetPutRange( 10,0,384,688,148,30,74,15 );        // EXPERT_ON
    hdxSetPutRange( 11,0,232,720,148,30,74,15 );        // DANI_ON
    hdxSetPutRange( 12,0,384,720,148,30,74,15 );        // FREE_ON

    // サウンドロード
    hdxLoadSound( 0,"pm_bgm.wav" );
    hdxLoadSound( 1,"pm_cursor.wav" );

    // BGM再生
    hdxPlaySound( 0,TRUE );
end

///////////////////////////////////////////////////////////////////////
// ログイン画面で毎フレーム呼び出されるので、ここで演算と描画処理を行う。
///////////////////////////////////////////////////////////////////////
function OnRunLogin( upd_frm )

    ///////////////////////////////////
    // 処理
    ///////////////////////////////////
    if( g_dwLoginState==LOGINST_TVANIME ) then
        if( hdxIsEndAnime(0)==TRUE ) then
            // TV表示が完了したらログインフレーム表示開始
            hdxOpenLoginFrame();
            g_dwLoginState = LOGINST_LOGIN;
        end
    end


    ///////////////////////////////////
    // 描画
    ///////////////////////////////////

    // 3Dモデル
    hdxSetZBuffer( TRUE );
    hdxMatrixRotationY( 0, hdxToRadian( ((hdxGetTime()%(360*60))/60) ) );
    hdxSetLookAt( 0,0,40, 0,0,0, 0,1,0 );
    hdxSetViewport( 0,0,RENDER_WIDTH,RENDER_HEIGHT );
    hdxDrawModel( 0,0 );                                // 背景オブジェクト
    hdxSetZBuffer( FALSE );

    hdxDrawAnime( 4, 0, 0, 1.0, 1.0 );                  // ライティング

    // アニメ
    hdxDrawAnime( 0, 640, 360, 1.0, 1.0 );              // TV
    hdxDrawAnime( 5, 0, 0, 1.0, 1.0 );                  // ロゴ

    // ログインシステムフレーム(開始していなければ何もしない)
    hdxDrawLoginFrame( 0xA689FF );
end

// プレイモードステート
PMST_OPEN   = 0;
PMST_SELECT = 1;
PMST_END    = 2;

g_dwPMState = PMST_OPEN;
g_dwPMSelect = 0;                   // 最後に選択されているプレイモード

///////////////////////////////////////////////////////////////////////
// ログイン画面でログインが成功したか、ログインせずに開始された際に呼び出される。
//   login : 0=未ログイン、1=ログイン済み
//   pmode : プレイモードの初期値(0=シングル1P、1=シングル2P、2=ダブル)
///////////////////////////////////////////////////////////////////////
function OnStartPlayMode( login,pmode )
    trace( "OnStartPlayMode : "..login..","..pmode );

    // プレイモードの初期値を保存
    g_dwPMSelect = pmode;

    // ステート初期化
    g_dwPMState = PMST_OPEN;

    // プレイモード背景開始
    hdxCtrlAnime( 1,CTRLMODE_AUTO_END,0,0,-1 );

    // プレイモードカーソル開始
    hdxCtrlAnime( 2,CTRLMODE_AUTO_END,0,0,30 );         // 左右から登場まで
end


///////////////////////////////////////////////////////////////////////
// プレイモード画面で毎フレーム呼び出されるので、ここで演算と描画処理を行う。
///////////////////////////////////////////////////////////////////////
function OnRunPlayMode( upd_frm )
    ///////////////////////////////////
    // 処理
    ///////////////////////////////////
    if( g_dwPMState==PMST_OPEN ) then
        // プレイモードフレームオープン
        if( hdxIsEndAnime(1)==TRUE and hdxIsEndAnime(2)==TRUE ) then
            // 背景とカーソル移動が完了した場合
            trace( "プレイモード選択許可" );
            hdxEnablePlayMode();
            g_dwPMState = PMST_SELECT;
        end
    elseif( g_dwPMState==PMST_SELECT ) then
        // 選択中
    elseif( g_dwPMState==PMST_END ) then
        // 決定後
        if( hdxIsEndAnime(3)==TRUE ) then
            trace( "プレイモード終了" );
            hdxNextScene();
        end
    else

    end


    ///////////////////////////////////
    // 描画
    ///////////////////////////////////

    // 3Dモデル
    hdxSetZBuffer( TRUE );
    hdxMatrixRotationY( 0, hdxToRadian( ((hdxGetTime()%(360*60))/60) ) );
    hdxSetLookAt( 0,0,40, 0,0,0, 0,1,0 );
    hdxSetViewport( 0,0,RENDER_WIDTH,RENDER_HEIGHT );
    hdxDrawModel( 0,0 );                                        // 背景オブジェクト
    hdxSetZBuffer( FALSE );

    hdxDrawAnime( 4, 0, 0, 1.0, 1.0 );                          // ライティング

    // アニメ
    hdxDrawAnime( 0, 640, 360, 1.0, 1.0 );                      // TV
    hdxDrawAnime( 5, 0, 0, 1.0, 1.0 );                          // ロゴ

    // ログインシステムフレーム(開始していなければ何もしない)
    hdxDrawLoginFrame( 0xA689FF );

    // ログイン画面のさらに上に描画
    hdxDrawAnime( 1, 0, 0, 1.0, 1.0 );                          // プレイモード背景
    hdxDrawAnime2( 2, 0, 0, 1.0, 1.0, "_pmCursorDraw" );        // カーソル表示(コールバック指定あり)

    // 終了アニメ
    hdxDrawAnime( 3, 0, 0, 1.0, 1.0 );

end

// カーソル内の各オブジェクトの表示
function _pmCursorDraw( layer,x,y,frm_x,frm_y,frm_sx,frm_sy,frm_alpha,frm_rot )

    if( layer==0 ) then
        // シングルフレーム
        local _x = frm_x + x;
        local _y = frm_y + y;
        hdxPut( 0,_x,_y );

        // プレイ可能なゲームモード表示
        local game_mode = hdxIsSupportedGameMode();
        if( game_mode["standard"]==TRUE )   then    hdxPut(  9,150+_x,291+_y ); else hdxPut( 5,150+_x,291+_y ); end
        if( game_mode["expert"]==TRUE )     then    hdxPut( 10,307+_x,291+_y ); else hdxPut( 6,307+_x,291+_y ); end
        if( game_mode["class"]==TRUE )      then    hdxPut( 11,150+_x,326+_y ); else hdxPut( 7,150+_x,326+_y ); end
        if( game_mode["free"]==TRUE )       then    hdxPut( 12,307+_x,326+_y ); else hdxPut( 8,307+_x,326+_y ); end


        if( g_dwPMSelect==0 or g_dwPMSelect==1 ) then
            // 選択中なら
            hdxSetBlendMode( BLEND_ADD );

            // キーボードのライト
            if( g_dwPMSelect==0 ) then
                // 左側
                hdxSetPutStatus( 2, math.sin((hdxGetTime()%900)/2.5*math.pi/180)/8+0.4,1,1,0 );     // 点滅
                hdxPut( 2,_x+29,_y+116 );
            else
                // 右側
                hdxSetPutStatus( 2, math.sin((hdxGetTime()%900)/2.5*math.pi/180)/8+0.4,1,1,0 );     // 点滅
                hdxPut( 2,_x+205,_y+116 );
            end

            // カーソル
            hdxSetPutStatus( 4, math.sin((hdxGetTime()%900)/2.5*math.pi/180)/8+0.4,1,1,0 );         // カーソル枠点滅
            hdxPut( 4,_x,_y );
            hdxSetBlendMode( BLEND_NORMAL );
        end

        return TRUE;

    elseif( layer==1 ) then
        // ダブルフレーム
        local _x = frm_x + x;
        local _y = frm_y + y;
        hdxPut( 1,_x,_y );

        // プレイ可能なゲームモード表示
        local game_mode = hdxIsSupportedGameMode();
        if( game_mode["standard"]==TRUE )   then    hdxPut(  9,150+_x,291+_y ); else hdxPut( 5,150+_x,291+_y ); end
        if( game_mode["expert"]==TRUE )     then    hdxPut( 10,307+_x,291+_y ); else hdxPut( 6,307+_x,291+_y ); end
        if( game_mode["class"]==TRUE )      then    hdxPut( 11,150+_x,326+_y ); else hdxPut( 7,150+_x,326+_y ); end
        if( game_mode["free"]==TRUE )       then    hdxPut( 12,307+_x,326+_y ); else hdxPut( 8,307+_x,326+_y ); end

        if( g_dwPMSelect==2 ) then
            // 選択中なら
            hdxSetBlendMode( BLEND_ADD );

            // キーボードのライト
            hdxSetPutStatus( 3, math.sin((hdxGetTime()%900)/2.5*math.pi/180)/8+0.4,1,1,0 );         // 点滅
            hdxPut( 3,_x+28,_y+116 );

            // カーソル
            hdxSetPutStatus( 4, math.sin((hdxGetTime()%900)/2.5*math.pi/180)/8+0.4,1,1,0 );         // カーソル枠点滅
            hdxPut( 4,_x,_y );
            hdxSetBlendMode( BLEND_NORMAL );
        end

        return TRUE;
    end

    // それ以外はデフォルト
    return FALSE;
end


///////////////////////////////////////////////////////////////////////
// プレイモードが選択されるごとに呼び出される。
//   pmode : 0=シングル1P、1=シングル2P、2=ダブル
///////////////////////////////////////////////////////////////////////
function OnChangePlayMode( pmode )
    // 選択変更
    g_dwPMSelect = pmode;

    // SE再生
    hdxPlaySound( 1,FALSE );
end

///////////////////////////////////////////////////////////////////////
// プレイモードが確定した際に呼び出される。
///////////////////////////////////////////////////////////////////////
function OnEndPlayMode( pmode )
    // 選択変更
    g_dwPMSelect = pmode;

    // BGM停止
    hdxStopSound( 0 );

    // 終了アニメ開始
    hdxCtrlAnime( 3,CTRLMODE_AUTO_END,0,0,-1 );

    g_dwPMState = PMST_END;
end