今回はシーンは1つしか作りませんが、結果シーンにつなげられるよう勝敗判定を作りたいと思います。
複数のシーンで共用しますので「GameData.h」の「CommonData構造体」に変数を追加します。
//-----------------------------------------------------------------------------
// 複数のシーンで共用するデータを構造体にまとめます。
//-----------------------------------------------------------------------------
struct CommonData {
int m_result;
};
|
次にゲームが終了したかどうか判定するプログラムを作りましょう。
「Memory.h」を開き、メンバ関数を追加します。
//前方参照 class Card; class Player; class Memory { public: Memory(); ~Memory(); void Initialize(); void Shuffle(); void FaceUp(const POINT &refPoint, Player &refPlayer1, Player &refPlayer2); bool IsFinish() const; void DrawCard(Engine *pEngine); void DrawScore(Engine *pEngine, Player &refPlayer1, Player &refPlayer2) const; private: const int ADJUST_X; //中央に転送するための調整用X座標 const int ADJUST_Y; //中央に転送するための調整用Y座標 const int SHUFFLE; //シャッフル回数 const int RIGHT_LIMIT; //領域判定用の右端 const int BOTTOM_LIMIT; //領域判定用の下端 const int SCORE_DEST_X_PLAYER1; //プレイヤー1のスコア表示左座標 const int SCORE_DEST_Y_PLAYER1; //プレイヤー1のスコア表示上座標 const int SCORE_DEST_X_PLAYER2; //プレイヤー2のスコア表示左座標 const int SCORE_DEST_Y_PLAYER2; //プレイヤー2のスコア表示上座標 //カードクラス配列用ポインタ Card *m_pCard; int m_gameStatus; //ゲームステータス int m_savePos[2]; //座標保存用 enum { PLAYER1, PLAYER2, }; int m_playerTurn; //ターン管理用 }; |
「Memory.cpp」の「FaceUp関数」の下に関数本体を追加します。
bool Memory::IsFinish() const { const int CARD_MAX = Card::SUIT * Card::NUMBER; bool bFinish = true; for (int i = 0; i < CARD_MAX; i++) { if (m_pCard[i].IsShow()) { bFinish = false; break; } } return bFinish; } |
1枚でも表示しているカードがあれば、falseを返します。
これだけでシーンを移行してはいけません、まだ勝敗判定が済んでいません。
もう1度「Memory.h」を開いて、勝敗判定用の定数とメンバ関数を追加しましょう。
//前方参照 class Card; class Player; class Memory { public: enum { PLAYER1_WIN, PLAYER2_WIN, DRAW, }; Memory(); ~Memory(); void Initialize(); void Shuffle(); void FaceUp(const POINT &refPoint, Player &refPlayer1, Player &refPlayer2); bool IsFinish() const; int Result(Player &refPlayer1, Player &refPlayer2) const; void DrawCard(Engine *pEngine); void DrawScore(Engine *pEngine, Player &refPlayer1, Player &refPlayer2) const; private: const int ADJUST_X; //中央に転送するための調整用X座標 const int ADJUST_Y; //中央に転送するための調整用Y座標 const int SHUFFLE; //シャッフル回数 const int RIGHT_LIMIT; //領域判定用の右端 const int BOTTOM_LIMIT; //領域判定用の下端 const int SCORE_DEST_X_PLAYER1; //プレイヤー1のスコア表示左座標 const int SCORE_DEST_Y_PLAYER1; //プレイヤー1のスコア表示上座標 const int SCORE_DEST_X_PLAYER2; //プレイヤー2のスコア表示左座標 const int SCORE_DEST_Y_PLAYER2; //プレイヤー2のスコア表示上座標 //カードクラス配列用ポインタ Card *m_pCard; int m_gameStatus; //ゲームステータス int m_savePos[2]; //座標保存用 enum { PLAYER1, PLAYER2, }; int m_playerTurn; //ターン管理用 }; |
「Memory.cpp」を開き、「Result関数」を「IsFinish関数」の下に追加しましょう。
int Memory::Result(Player &refPlayer1, Player &refPlayer2) const { if (refPlayer1 > refPlayer2) { return PLAYER1_WIN; } else { if (refPlayer1 == refPlayer2) { return DRAW; } else { return PLAYER2_WIN; } } } |
すでにプレイヤークラスで勝敗判定用に得点を比較するため「>演算子」と「==演算子」のオーバーロードを作っています。
この結果を最初に作った共用データに入れます。
では「IsFinish関数」「Result関数」を踏まえて「SceneGame.cpp」の「Update関数」にコードを追加しましょう。
//============================================================================= // シーンの実行時に繰り返し呼び出される更新処理関数 //============================================================================= void SceneGame::Update() { if (m_pEngine->GetMouseButtonSync(DIK_LBUTTON)) { POINT point = m_pEngine->GetMousePosition(); m_memory.FaceUp(point, m_player1, m_player2); } if (m_memory.IsFinish()) { m_gameData.m_result = m_memory.Result(m_player1, m_player2); m_nowSceneData.Set(Common::SCENE_EXIT, false, NULL); } } |
結果シーンで使えるように、共用データに結果を代入しています。
ただし、今回は結果シーンは作りませんので、ゲームを終了させています。
実行して終了する事を確認してください。
※実行画像はありません。
これで完成!と行きたいところですが、「今どちらのターンなのか」が不明瞭です。
プレイヤー自身が管理しなければならないのは、コンピュータゲームとしては欠陥があります。
そこでターンが分かるように手番のプレイヤーに「☆」を付ける事にします。
「Memory.h」に必要な、メンバ関数や変数、定数を追加します。
//前方参照 class Card; class Player; class Memory { public: enum { PLAYER1_WIN, PLAYER2_WIN, DRAW, }; Memory(); ~Memory(); void Initialize(); void Shuffle(); void FaceUp(const POINT &refPoint, Player &refPlayer1, Player &refPlayer2); bool IsFinish() const; int Result(Player &refPlayer1, Player &refPlayer2) const; void DrawCard(Engine *pEngine); void DrawScore(Engine *pEngine, Player &refPlayer1, Player &refPlayer2) const; void DrawTurn(Engine *pEngine); private: const int ADJUST_X; //中央に転送するための調整用X座標 const int ADJUST_Y; //中央に転送するための調整用Y座標 const int SHUFFLE; //シャッフル回数 const int RIGHT_LIMIT; //領域判定用の右端 const int BOTTOM_LIMIT; //領域判定用の下端 const int SCORE_DEST_X_PLAYER1; //プレイヤー1のスコア表示左座標 const int SCORE_DEST_Y_PLAYER1; //プレイヤー1のスコア表示上座標 const int SCORE_DEST_X_PLAYER2; //プレイヤー2のスコア表示左座標 const int SCORE_DEST_Y_PLAYER2; //プレイヤー2のスコア表示上座標 const int STAR_SOUR_X; //手番用「☆」の転送元左座標 const int STAR_SOUR_Y; //転送元上座標 const int STAR_DEST_X1; //プレイヤー1側の転送先左座標 const int STAR_DEST_Y1; //転送先上座標 const int STAR_DEST_X2; //プレイヤー2側の転送先左座標 const int STAR_DEST_Y2; //転送先上座標 const int STAR_WIDTH; //「☆」の幅 const int STAR_HEIGHT; //高さ //カードクラス配列用ポインタ Card *m_pCard; int m_gameStatus; //ゲームステータス int m_savePos[2]; //座標保存用 enum { PLAYER1, PLAYER2, }; int m_playerTurn; //ターン管理用 RECT m_sour; RECT m_dest; }; |
「Memory.cpp」を開きましょう。
コンストラクタ関数で定数の初期値を設定します。
Memory::Memory()
: ADJUST_X(60)
, ADJUST_Y(120)
, SHUFFLE(2000)
, RIGHT_LIMIT(ADJUST_X + Card::NUMBER * Card::SMALL_CARD_WIDTH)
, BOTTOM_LIMIT(ADJUST_Y + Card::SUIT * Card::SMALL_CARD_HEIGHT)
, SCORE_DEST_X_PLAYER1(175)
, SCORE_DEST_Y_PLAYER1(395)
, SCORE_DEST_X_PLAYER2(495)
, SCORE_DEST_Y_PLAYER2(395)
, STAR_SOUR_X(0)
, STAR_SOUR_Y(1300)
, STAR_DEST_X1(64)
, STAR_DEST_Y1(374)
, STAR_DEST_X2(380)
, STAR_DEST_Y2(370)
, STAR_WIDTH(20)
, STAR_HEIGHT(20)
, m_pCard(NULL)
{
}
|
「DrawScore関数」の下に「DrawTurn関数」の本体を追加します。
void Memory::DrawTurn(Engine *pEngine) { SetRect(&m_sour, STAR_SOUR_X, STAR_SOUR_Y, STAR_SOUR_X + STAR_WIDTH, STAR_SOUR_Y + STAR_HEIGHT); if (m_playerTurn == PLAYER1) { SetRect(&m_dest, STAR_DEST_X1, STAR_DEST_Y1, STAR_DEST_X1 + STAR_WIDTH, STAR_DEST_Y1 + STAR_HEIGHT); } else { SetRect(&m_dest, STAR_DEST_X2, STAR_DEST_Y2, STAR_DEST_X2 + STAR_WIDTH, STAR_DEST_Y2 + STAR_HEIGHT); } pEngine->Blt(&m_dest, TEXTURE_TRUMP, &m_sour); } |
最後に「SceneGame.cpp」の「Draw関数」で「DrawTurn関数」を呼び出します。
//============================================================================= // シーンの実行時に繰り返し呼び出される描画処理関数 //============================================================================= void SceneGame::Draw() { m_back.Draw(m_pEngine); m_memory.DrawCard(m_pEngine); m_memory.DrawScore(m_pEngine, m_player1, m_player2); m_memory.DrawTurn(m_pEngine); } |
実行して確認しましょう。
<実行結果 クライアント領域のみ>
完成しました!
タイトルシーンや結果シーンは皆さんで追加してみてください。
今回はクラスオブジェクトを使ってゲームを作りましたので、ゲームシーンはすっきりしていると思います。
色々なゲームを通して、クラスを作る事にも慣れていきましょう。