★プレイヤーキャラクター 移動制限1★


今の状態では、プレイヤーキャラクターを移動していくと画面外に出てしまいます。

本来であれば画面外に描画すると「描画用メモリ」の外にデータを転送する事になるため「クリッピング」と言う処理が必要になります。

しかし、このシステムはDirectXを使っているため「クリッピング」は自動的に行ってくれます。

今回は「クリッピング」よりも、プレイヤーキャラクターが画面外に出る事自体を問題として考えていきます。


皆さんがゲームをプレイする時にプレイヤーキャラクターが画面外に出てしまう事があったでしょうか?

画面外で出てしまった場合、座標の表示が無ければ画面内に戻ってくる事も困難です。

普通のゲームはプレイヤーキャラクターが画面外に出ないようにプログラムで制御しています。

まずは「画面端でプレイヤーキャラクターを止める」処理を考えてみましょう。


「Player.cpp」の「Move関数」を開いてください。

void Player::Move(Engine *pEngine)
{
    if (pEngine->GetKeyState(DIK_UP)) {

        m_direction = UP;

        m_y -= m_speed;
    }

    if (pEngine->GetKeyState(DIK_RIGHT)) {

        m_direction = RIGHT;

        m_x += m_speed;
    }

    if (pEngine->GetKeyState(DIK_DOWN)) {

        m_direction = DOWN;

        m_y += m_speed;
    }

    if (pEngine->GetKeyState(DIK_LEFT)) {

        m_direction = LEFT;

        m_x -= m_speed;
    }
}

今は何の制限も無く座標を増減させていますので、画面外に出てしまいます。


最初は簡単な「左端」から対応を考えてみます。

画面の左端の座標は「0」です。

キャラクターの「転送先X座標」がマイナスになると画面外に出てしまいます。

座標を確認出来るように「Draw関数」に座標を表示するコードを追加します。


座標の表示


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

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

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

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

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

    m_pEngine->AddFont(FONT_GOTHIC, 20);

    m_player.Initialize();
}

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

void Player::Draw(Engine *pEngine)
{
    SetRect(&m_sour,
        m_animation * WIDTH,
        m_direction * HEIGHT,
        m_animation * WIDTH + WIDTH,
        m_direction * HEIGHT + HEIGHT);

    SetRect(&m_dest, 
        m_x, 
        m_y, 
        m_x + WIDTH,
        m_y + HEIGHT);
    
    pEngine->Blt(&m_dest, TEXTURE_CHARACTER, &m_sour);

    pEngine->DrawPrintf(0, 0, FONT_GOTHIC, D3DCOLOR_XRGB(255, 255, 255), "X = %d : Y = %d", m_x, m_y);
}

実行して確認しましょう。

移動すると座標も変わります。


移動制限


それでは改めて「左端」で止める処理を考えます。

考え方としては「左端からはみ出したら左端に戻す」と言う事をやります。

左に移動する箇所だけを抜き出すと、

if (pEngine->GetKeyState(DIK_LEFT)) {

    m_direction = LEFT;

    m_x -= m_speed;
}

こうなっています。

X座標を無条件で引いていますので、いつかマイナスになり画面外に出てしまいます。

そこで、if文を追加します。

if (pEngine->GetKeyState(DIK_LEFT)) {

    m_direction = LEFT;

    m_x -= m_speed;

    if (m_x < 0) {
        m_x = 0;
    }
}

座標がマイナスになったら「0」に戻します。

こうする事で、

「左端」で止まります。


「上端」も同じように作る事が出来ます。

if (pEngine->GetKeyState(DIK_UP)) {

    m_direction = UP;

    m_y -= m_speed;

    if (m_y < 0) {
        m_y = 0;
    }
}

「転送先Y座標」がマイナスになった場合、「0」に戻せば良いです。


残りは「右端」と「下端」です。

クライアント領域のサイズは「640×480ピクセル」ですから「右端」「下端」の座標は分かります。

極力定数値を使うようにしていますので、640や480と言った直値を使うのは避けたいです。

このシステムでは「WindowSetting名前空間」に「WINDOW_WIDTH」「WINDOW_HEIGHT」と言う定数を用意しています。

これを使って「右端」「下端」の処理を作りましょう。

if (pEngine->GetKeyState(DIK_RIGHT)) {

    m_direction = RIGHT;

    m_x += m_speed;

    if (m_x >= WindowSetting::WINDOW_WIDTH - WIDTH) {
        m_x = WindowSetting::WINDOW_WIDTH - WIDTH;
    }
}

if (pEngine->GetKeyState(DIK_DOWN)) {

    m_direction = DOWN;

    m_y += m_speed;

    if (m_y >= WindowSetting::WINDOW_HEIGHT - HEIGHT) {
        m_y = WindowSetting::WINDOW_HEIGHT - HEIGHT;
    }
}

クライアント領域の「右端」の座標は640ですが、キャラクターの幅を考慮しなければなりません。

キャラクターの幅は32ピクセルですから、608で止めなければ画面外に出てしまいます。

「下端」も同様にキャラクターの高さを考慮して作りました。


実行してみましょう。


右も下も画面外に出なくなりました。


次へ

戻る

目次へ