★領域判定★


次はこれまでのプログラムにマウスも組み合わせてみましょう。

プログラムは前回のものを使って作ります。


マウス座標の取得と表示


前にやったプログラムですが、再度書きます。

「SceneGame.h」を開いてprivateにPOINT構造体を追加しましょう。

private:

    int m_x;
    int m_y;
    int m_number;
    int m_suit;

    POINT m_point;
};

「SceneGame.cpp」を開き「Start関数」でm_pointの初期値を入れます。

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

    m_x = 270;
    m_y = 165;

    m_number = rand() % 13 + 1;
    m_suit = rand() % 4;

    m_point.x = 0;
    m_point.y = 0;
}

続いて「Update関数」にコードを追加します。

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

次に文字描画の準備をします。

「GameBase.h」を開きフォントを定数化しましょう。

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

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

「SceneGame.cpp」を開き、「Start関数」でフォントを追加します。

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

    m_x = 270;
    m_y = 165;

    m_number = rand() % 13 + 1;
    m_suit = rand() % 4;

    m_point.x = 0;
    m_point.y = 0;
}

「Exit関数」にフォントの解放コードを追加します。

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

準備が出来たので「Draw関数」にDrawPrintf関数を追加します。

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

    //カードの転送
    SetRect(&m_sour, (m_number - 1) * 100, m_suit * 150, (m_number - 1) * 100 + 100, m_suit * 150 + 150);
    SetRect(&m_dest, m_x, m_y, m_x + 100, m_y + 150);
    m_pEngine->Blt(&m_dest, TEXTURE_TRUMP, &m_sour);

    //マウス座標の表示
    m_pEngine->DrawPrintf(0, 0, FONT_GOTHIC, D3DCOLOR_XRGB(255, 255, 255), "X = %d : Y = %d", m_point.x, m_point.y);
}

とりあえず、ここまでで実行してみましょう。

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


領域の判定


今回やりたいことは、カードの上にマウスポインタがあるかどうか調べる事です。

マウスは座標を取得出来ていますので、カードが表示されいている範囲を考えてみましょう。

「Start関数」を見れば分かりますが、カードの左座標は270、上座標は165です。

右座標は左座標に幅を加えたものですから370になります。

下座標は上座標に高さを加えたものですので315になります。

図で見ると、

このようなイメージです。

マウスポインタがこの範囲に入った時を調べて何か起こるように作りたいと思います。

変化を付けるために1つフラグを追加しましょう。

「SceneGame.h」を開き、privateに↓のフラグを追加してください。

private:

    int m_x;
    int m_y;
    int m_number;
    int m_suit;

    POINT m_point;

    bool m_bInside;
};

「SceneGame.cpp」を開き「Start関数」で初期値を入れます。

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

    m_x = 270;
    m_y = 165;

    m_number = rand() % 13 + 1;
    m_suit = rand() % 4;

    m_point.x = 0;
    m_point.y = 0;

    m_bInside = false;
}

マウスポインタがカードの描画領域に入った時にこのフラグがtrueになるようにしたいです。

このフラグがtrueになった時に「マウスの座標を表示する」事にしましょう。

先に「Draw関数」を変更します。

//=============================================================================
// シーンの実行時に繰り返し呼び出される描画処理関数
//=============================================================================
void SceneGame::Draw()
{
    //背景の転送
    SetRect(&m_sour, 0, 1568, 640, 2048);
    SetRect(&m_dest, 0, 0, 640, 480);
    m_pEngine->Blt(&dest, TEXTURE_TRUMP, &sour);

    //カードの転送
    SetRect(&m_sour, (m_number - 1) * 100, m_suit * 150, (m_number - 1) * 100 + 100, m_suit * 150 + 150);
    SetRect(&m_dest, m_x, m_y, m_x + 100, m_y + 150);
    m_pEngine->Blt(&m_dest, TEXTURE_TRUMP, &m_sour);

    //マウス座標の表示
    if (m_bInside) {
        m_pEngine->DrawPrintf(0, 0, FONT_GOTHIC, D3DCOLOR_XRGB(255, 255, 255), "X = %d : Y = %d", m_point.x, m_point.y);
    }
}

一度実行してみます。

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

座標が消えました。


では、本題の「領域の判定」に入ります。

マウスの座標が次の時に描画領域に入ったと判断出来ます。

マウスのX座標 270以上、370未満

マウスのY座標 165以上、315未満

なぜ「未満」なのかは別の機会に説明します。

この4つの条件が成立した時が「領域に入った時」です。

「Update関数」を変更してみましょう。

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

    if (m_point.x >= 270 && m_point.x < 370 && m_point.y >= 165 && m_point.y < 315) {
        m_bInside = true;
    }
}

実行してみましょう。

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

最初は座標が表示されていませんが、カードの描画領域に入った時から座標が描画されるようになりました。


しかし、領域から出た後も座標は描画され続けています。

フラグがtrueになった後、falseになるタイミングが無いのが原因です。

領域から出たらフラグをfalseにするプログラムが必要です。

「Update関数」をさらに変更しましょう。

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

    if (m_point.x >= 270 && m_point.x < 370 && m_point.y >= 165 && m_point.y < 315) {
        m_bInside = true;
    }
    else {
        m_bInside = false;
    }
}

実行画像からは分からないので、画像は載せませんがきちんと動いている事を確認してください。


次へ

戻る

目次へ