★シーンの循環と共用データ★


「ゲームオーバーシーン」「ゲームクリアシーン」を追加しましたが、結局これらのシーンでゲームは止まってしまいます。

例えば「ゲームオーバーシーン」でマウスのボタンを押すと、実際にゲームが終了するようにするとか、

「ゲームクリアシーン」でマウスのボタンを押すと、もう1度ゲームが出来るとかの工夫をしてみましょう。


ゲームオーバー → 終了


「SceneGameover.cpp」を開き、「Update関数」に次のコードを追加します。

//=============================================================================
// シーンの実行時に繰り返し呼び出される更新処理関数
//=============================================================================
void SceneGameover::Update()
{
    if (m_pEngine->GetMouseButtonSync(DIK_LBUTTON)) {
        m_nowSceneData.Set(Common::SCENE_EXIT, false, NULL);
    }
}

ゲームクリア → 再ゲーム


「SceneClear.cpp」を開き、「Update関数」に次のコードを追加します。

//=============================================================================
// シーンの実行時に繰り返し呼び出される更新処理関数
//=============================================================================
void SceneGameover::Update()
{
    if (m_pEngine->GetMouseButtonSync(DIK_LBUTTON)) {
        m_nowSceneData.Set(Common::SCENE_GAME, false, NULL);
    }
}

実行して確認してください。

「A」を選択する限りゲームは何度でも出来ますが、「K」を選択すると終了するようになりました。

「タイトルシーン」なども組み合わせると、色々な事が出来そうです。


複数のシーンで共用するデータ


例えば、プレイヤーのステータスなどを考えてみると、ゲームシーンでも必要になりますし、ステータス表示のシーンを作るとそこでも必要になりそうです。

ゲームのスコアなども、ゲームシーンだけでなくランキングシーンなどを作る時にも必要になるでしょう。

このように複数のシーンで共用するデータの扱いについて説明します。

今回のサンプルゲームは「A」を選択する限りゲームが続きます。

そこで、何回ゲームをクリアしたか保管して表示するようにしてみましょう。


勝敗は「ゲームシーン」で判定していますのでクリア回数を数えるのは「ゲームシーン」です。

クリア回数は「ゲームクリアシーン」で表示したいと思います。

「GameData.h」を開いてください。

名前空間「Common」に次のような記述があります。

//-----------------------------------------------------------------------------
// 複数のシーンで共用するデータ
//-----------------------------------------------------------------------------
namespace Common
{
    //-----------------------------------------------------------------------------
    // シーンを追加した際に定数を追加します。
    //-----------------------------------------------------------------------------
    enum {
        SCENE_INIT,
        SCENE_GAME,
        SCENE_GAMEOVER,
        SCENE_CLEAR,
        SCENE_EXIT,
    };

    //-----------------------------------------------------------------------------
    // 複数のシーンで共用するデータを構造体にまとめます。
    //-----------------------------------------------------------------------------
    struct CommonData {

    };
}

ここで変数や構造体、クラスを宣言すると複数のシーンで共用する事が出来るようになります。

早速、変数を追加してみましょう。

//-----------------------------------------------------------------------------
// 複数のシーンで共用するデータを構造体にまとめます。
//-----------------------------------------------------------------------------
struct CommonData {

    int clearCount;
};

共用するデータの初期化


次に共用するデータの初期化を行います。

初期値は「SceneGame」などの「Start関数」で設定してはいけません。

そのシーンが実行される度に初期化されますので、クリア回数は増えていきません。

共用するデータの初期化は「SceneInit.cpp」で行います。

「SceneInit.cpp」を開き、「Start関数」に初期化コードを追加しましょう。

//=============================================================================
// シーンの実行時に1度だけ呼び出される開始処理関数
//=============================================================================
void SceneInit::Start()
{
    //--------------------------------------//
    // 複数のシーンで共用するデータの初期化 //
    //--------------------------------------//

    m_gameData.clearCount = 0;
}

「GameData.h」で構造体(CommonData)に追加されたメンバは、「m_gameData」と言う実体のメンバとして各シーンで扱う事が出来ます。


共有データの使用


「SceneGame.cpp」を開き「Update関数」に次のコードを追加します。

//=============================================================================
// シーンの実行時に繰り返し呼び出される更新処理関数
//=============================================================================
void SceneGame::Update()
{
    if (m_pEngine->GetKeyStateSync(DIK_F1)) {
        m_pEngine->ScreenShot();
    }

    if (m_pEngine->GetMouseButton(DIK_LBUTTON)) {

        point = m_pEngine->GetMousePosition();

        //左のカードの判定
        if (point.x >= 146 && point.x < 246 && point.y >= 150 && point.y < 300) {
            m_bChoiceLeft = true;
            m_bSelected = true;
        }

        //右のカードの判定
        if (point.x >= 394 && point.x < 494 && point.y >= 150 && point.y < 300) {
            m_bChoiceLeft = false;
            m_bSelected = true;
        }
    }

    if (m_bSelected) {
        if (m_bChoiceLeft) {
            if (m_left == 1) {
                m_gameData.clearCount++;
                m_nowSceneData.Set(Common::SCENE_CLEAR, false, NULL);
            }
            else {
                m_nowSceneData.Set(Common::SCENE_GAMEOVER, false, NULL);
            }
        }
        else {
            if (m_right == 1) {
                m_gameData.clearCount++;
                m_nowSceneData.Set(Common::SCENE_CLEAR, false, NULL);
            }
            else {
                m_nowSceneData.Set(Common::SCENE_GAMEOVER, false, NULL);
            }
        }
    }
}

これで「勝った」場合、クリア回数が1増えるはずです。


では、「SceneClear.cpp」を開き、「Draw関数」でクリア回数を表示しましょう。

その前にDrawPrintf関数を使うため、フォントを追加しなければなりません。

「GameBase.h」を開き、定数を追加します。

//-----------------------------------------------------------------------------
//ゲーム中で使用するテクスチャ、BGM、SE、フォントのパス付ファイル名を書きます。
//-----------------------------------------------------------------------------
namespace KeyString
{
    const std::string TEXTURE_TRUMP = "Resource\\Texture\\Trump.png";

    const std::string TEXTURE_RESULT = "Resource\\Texture\\Result.png";

    const std::string FONT_GOTHIC = "MS ゴシック";
}

「SceneClear.cpp」を開き、「Start関数」で追加、「Exit関数」で解放を追加します。

//=============================================================================
// シーンの実行時に1度だけ呼び出される開始処理関数
//=============================================================================
void SceneClear::Start()
{
    m_pEngine->AddTexture(TEXTURE_RESULT);
    m_pEngine->AddFont(FONT_GOTHIC, 20);
}

//=============================================================================
// シーンの終了時に呼び出される終了処理関数
//=============================================================================
void SceneClear::Exit()
{
    m_pEngine->ReleaseFont(FONT_GOTHIC);
    m_pEngine->ReleaseTexture(TEXTURE_RESULT);
}

最後に「Draw関数」にクリア回数を転送するコードを追加します。

//=============================================================================
// シーンの実行時に繰り返し呼び出される描画処理関数
//=============================================================================
void SceneClear::Draw()
{
    SetRect(&m_sour, 0, 0, 640, 480);
    SetRect(&m_dest, 0, 0, 640, 480);
    m_pEngine->Blt(&m_dest, TEXTURE_RESULT, &m_sour);

    m_pEngine->DrawPrintf(180, 360, FONT_GOTHIC, D3DCOLOR_XRGB(255, 255, 255), "クリア回数 %d回", m_gameData.clearCount);
}

実行して確認してください。

<実行結果 クライアント領域のみ>


次回はサブシーンについて説明します。


次へ

戻る

目次へ