第3章 画像の表示・動作

3-5 画面からはみ出さないようにするには?(当たり判定・1)

3のプログラムでは、キャラクタの矩形を画面(バック・サーフェイス)からはみ出した部分に描画を行うとBltFast関数がエラーになり、描画が失敗する。また、画面内の決められた範囲内しか移動できないようにしたい場合もある。では、はみ出さないようにするにはどうしたら良いのだろうか。

(a) 画面の端まで来たら、それ以上動かないようにする

《サンプルプログラム》

#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
・
・

// グローバル変数の宣言
RECT winRect = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};  // 画面の矩形(絶対に変わらないのでここで初期化)
RECT charRect;  // キャラクタ画像矩形
int x, y;  // キャラクタ表示座標
int charWidth, charHeight;  // キャラクタの幅、高さ
int move_x, move_y;  // キャラクタの移動量
・
・

// 初期化
void GameInit(void)
{
    // キャラクタ用変数
    SetRect(&charRect, 0, 50, 48, 98);  // キャラクタ画像矩形
    charWidth = charRect.right - charRect.left;  // キャラクタの幅
    charHeight = charRect.bottom - charRect.top;  // キャラクタの高さ
    move_x = 3;  // 移動量の初期値
    move_y = 3;  // 移動量の初期値
    ・
    ・
}

// メイン処理
void GameFrame(void)
{
    // 背景描画
    ・
    ・

    // キャラクタ描画
    hRet = g_pDDSBack->BltFast((DWORD)x, (DWORD)y, g_pDDSGame, &AngelRect, DDBLTFAST_SRCCOLORKEY);
    if (hRet != DD_OK)  // 描画に失敗したら関数を抜ける(これ以降の処理は行わない)
        return;
    ・
    ・

    // 移動処理
    if (KeyTbl[VK_LEFT] & 0x80)
    {
        x -= move_x;
        if (x < winRect.left) x = winRect.left;
    }
    if (KeyTbl[VK_RIGHT] & 0x80)
        x += move_x;
        if (winRect.right < (x + charWidth)) x = winRect.right - charWidth;
    }
    if (KeyTbl[VK_UP] & 0x80)
        y -= move_y;
        if (y < winRect.top) y = winRect.top;
    }
    if (KeyTbl[VK_DOWN] & 0x80)
        y += move_y;
        if (winRect.bottom < (y + charHeight)) y = winRect.bottom - charHeight;
    }
    ・
    ・

(b) 画面の端まで来たら、反対側に移動する

《サンプルプログラム》

    // 移動処理
    if (KeyTbl[VK_LEFT] & 0x80)
    {
        x -= move_x;
        if (x < winRect.left) x = winRect.right - charWidth;
    }
    if (KeyTbl[VK_RIGHT] & 0x80)
    {
        x += move_x;
        if (winRect.right < (x + charWidth)) x = winRect.left;
    }
    if (KeyTbl[VK_UP] & 0x80)
    {
        y -= move_y;
        if (y < winRect.top) y = winRect.bottom - charHeight;
    }
    if (KeyTbl[VK_DOWN] & 0x80)
    {
        y += move_y;
        if (winRect.bottom < (y - charHeight)) y = winRect.top;
    }
    ・
    ・

(c) 応用

画面全体を基準にして判定ができるなら、画面内の指定した範囲内でしか動けないようにするのも簡単である。

《サンプルプログラム》

#define SCREEN_WITDH 640
#define SCREEN_HEIGHT 480
・
・

// グローバル変数の宣言
RECT winRect = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};  // 画面の矩形(絶対に変わらないのでここで初期化)
RECT gameRect = {50, 15, 630, 465};  // キャラクタ描画領域の矩形(絶対に変わらないのでここで初期化)
・
・

// メイン処理
void GameFrame(void)
{
    ・
    ・

    // 移動処理
    if (KeyTbl[VK_LEFT] & 0x80)
    {
        x -= move_x;
        if (x < gameRect.left) x = gameRect.left;
    }
    if (KeyTbl[VK_RIGHT] & 0x80)
    {
        x += move_x;
        if (gameRect.right < (x + charWidth)) x = winRect.right - charWidth;
    }
    if (KeyTbl[VK_UP] & 0x80)
    {
        y -= move_y;
        if (y < gameRect.top) y = gameRect.top;
    }
    if (KeyTbl[VK_DOWN] & 0x80)
    {
        y += move_y;
        if (gameRect.bottom < (y + charHeight)) y = gameRect.bottom - charHeight;
    }
    ・
    ・

[ TOP ] [ Next ]