第5章 キャラクタ構造体を使う

5-2.キャラクタ用構造体変数の作り方と使い方

(a) キャラクタ用構造体変数の宣言

構造体を宣言したら、キャラクタ別に構造体変数をグローバル変数として宣言する。

[Game.cpp]
//-----------------------------------------------------------------------------
// グローバル変数
//-----------------------------------------------------------------------------
/* ゲーム処理用 */
static struct STATUS Angel;          // 天使
static RECT GokiRect;                      // ゴキブリの矩形
static int GokiWidth, GokiHeight;          // ゴキブリの幅・高さ
static int GokiX, GokiY;                   // ゴキブリの表示座標

[メリット]

  1. ステータス情報を追加する場合、構造体にメンバーを追加するだけでよい。
  2. VC6.0のオートコンプリート機能により、メンバー名を覚える必要が無い(例えば Angel. と入力すると、メンバー名一覧が表示される)
※構造体の宣言は次のようにすることもできる。
[common.h]
typedef struct tarSTATUS {
    int x, y;           // 表示座標
    RECT rect;          // 画像の矩形
    RECT hitrect;       // 当たり判定用の矩形
    int move_x, move_y; // 移動量
    int width, height;  // キャラクタの幅と高さ
} STATUS;
[Game.cpp]
//-----------------------------------------------------------------------------
// グローバル変数
//-----------------------------------------------------------------------------
/* ゲーム処理用 */
static STATUS Angel;                 // 天使
static RECT GokiRect;                      // ゴキブリの矩形
static int GokiWidth, GokiHeight;          // ゴキブリの幅・高さ
static int GokiX, GokiY;                   // ゴキブリの表示座標

(b) キャラクタ用構造体変数を初期化する

初期化処理で、通常の変数と同様に初期化を行う。

    /* 天使(カーソルキーで移動) */
    SetRect(&Angel.rect, 0, 608, 48, 656);             // キャラクタ矩形設定
    SetRect(&Angel.hitrect, 4, 4, 40, 40);             // 当たり矩形設定
    Angel.width = Angel.rect.right - Angel.rect.left;  // 幅
    Angel.height = Angel.rect.bottom - Angel.rect.top; // 高さ
    Angel.x = 310;                                     // X座標
    Angel.y = 230;                                     // Y座標
    Angel.move_x = 4;                                  // X方向移動量
    Angel.move_y = 4;                                  // Y方向移動量
    /* ゴキブリ(動かない) */
   ・
   ・
   ・

(c) キャラクタ情報の使い方

例えばキャラクタ画像を表示するには次のようなプログラムになる。

hRet = g_pDDSBack->BltFast(Angel.x, Angel.y, g_pDDSGame, &Angel.rect, DDBLTFAST_SRCCOLORKEY);

(d) まとめ

キャラクタのステータス情報を構造体で宣言して共通ヘッダ・ファイルに宣言し、キャラクタ用の構造体変数をグローバル変数として宣言すると、Game.cppは次のようになる。

[修正後のGame.cpp]

//=============================================================================
//	Game処理関係の自作関数群
//=============================================================================
#include "common.h"

//-----------------------------------------------------------------------------
// プロトタイプ宣言(ソース内でしか使わないもの)
//-----------------------------------------------------------------------------
static void ScreenOut(void);
static void CharMove(void);
static void ScreenHitCheck(void);
static void CharHitCheck(void);
static bool HitCheck(RECT, RECT);

//-----------------------------------------------------------------------------
// ゲーム処理用グローバル変数
//-----------------------------------------------------------------------------
static STATUS Angel;                 // 天使
static RECT GokiRect;                      // ゴキブリの矩形
static int GokiWidth, GokiHeight;          // ゴキブリの幅・高さ
static int GokiX, GokiY;                   // ゴキブリの表示座標

//-----------------------------------------------------------------------------
// 関数名 : GameInit()
// 機能概要: スタート処理初期化
//-----------------------------------------------------------------------------
void GameInit(HWND hWnd)
{
    //------------------------------------------------------- 各変数の初期化
    /* 天使(カーソルキーで移動) */
    SetRect(&Angel.rect, 0, 608, 48, 656);             // キャラクタ矩形設定
    SetRect(&Angel.hitrect, 4, 4, 40, 40);             // 当たり矩形設定
    Angel.width = Angel.rect.right - Angel.rect.left;  // 幅
    Angel.height = Angel.rect.bottom - Angel.rect.top; // 高さ
    Angel.x = 310;                                     // X座標
    Angel.y = 230;                                     // Y座標
    Angel.move_x = 4;                                  // X方向移動量
    Angel.move_y = 4;                                  // Y方向移動量
    /* ゴキブリ(動かない) */
    ・
    ・
    ・
//-----------------------------------------------------------------------------
// 関数名 : GameFrame()
// 機能概要: ゲーム画面更新処理
//-----------------------------------------------------------------------------
void GameFrame(HWND hWnd)
{
    ・
    ・
    ・
}
//-----------------------------------------------------------------------------
// 関数名 : ScreenOut()
// 機能概要: ゲーム画像描画処理
//-----------------------------------------------------------------------------
static void ScreenOut(void)
{
    HRESULT hRet;

    /* ゲーム画面用背景 */
    hRet = g_pDDSBack->BltFast(0, 0, g_pDDSGame, &ScreenRect, DDBLTFAST_NOCOLORKEY);
    if (hRet != DD_OK)
        return;

    /* 天使 */
    hRet = g_pDDSBack->BltFast(Angel.x, Angel.y, g_pDDSGame, &Angel.rect, DDBLTFAST_SRCCOLORKEY);
    if (hRet != DD_OK)
        return;

    /* ゴキブリ */
    hRet = g_pDDSBack->BltFast(GokiX, GokiY, g_pDDSGame, &GokiRect, DDBLTFAST_SRCCOLORKEY);
    if (hRet != DD_OK)
        return;

}
//-----------------------------------------------------------------------------
// 関数名 : CharMove()
// 機能概要: キャラクタ移動処理
//-----------------------------------------------------------------------------
static void CharMove(void)
{
    /* 天使の移動 */
    if (KeyTbl[VK_LEFT] & 0x80)
        Angel.x -= Angel.move_x;
    if (KeyTbl[VK_RIGHT] & 0x80)
        Angel.x += Angel.move_x;
    if (KeyTbl[VK_UP] & 0x80)
        Angel.y -= Angel.move_y;
    if (KeyTbl[VK_DOWN] & 0x80)
        Angel.y += Angel.move_y;
}
//-----------------------------------------------------------------------------
// 関数名 : ScreenCheck()
// 機能概要: キャラクタがゲーム画面をはみ出している時の処理
//-----------------------------------------------------------------------------
static void ScreenHitCheck(void)
{
    /* 天使とゲーム画面(画面全体)をチェック */
    if (Angel.x < ScreenRect.left)
        Angel.x = ScreenRect.left;
    else if (Angel.x > ScreenRect.right - Angel.width)
        Angel.x = ScreenRect.right - Angel.width;
    if (Angel.y < ScreenRect.top)
        Angel.y = ScreenRect.top;
    else if (Angel.y > ScreenRect.bottom - Angel.height)
        Angel.y = ScreenRect.bottom - Angel.height;
}

//-----------------------------------------------------------------------------
// 関数名 : HitCheck()
// 機能概要: あたり判定関数
//-----------------------------------------------------------------------------
static bool HitCheck(RECT Rect1, RECT Rect2)
{
    ・
    ・
    ・
}
//-----------------------------------------------------------------------------
// 関数名 : CharHitCheck()
// 機能概要: キャラクタ同士の当たり判定と処理
//-----------------------------------------------------------------------------
static void CharHitCheck(void)
{
    RECT r1, r2;

    /* 天使とゴキブリの衝突を調べ、当たっていたらスタート画面に戻る */
    SetRect(&r1, Angel.x + Angel.hitrect.left, Angel.y + Angel.hitrect.top,
                Angel.x + Angel.hitrect.right, Angel.y + Angel.hitrect.bottom);
    SetRect(&r2, GokiX, GokiY, GokiX + GokiWidth, GokiY + GokiHeight);
    if (HitCheck(r1, r2))
    {
        g_FrameNo = START_INIT;
        return;
    }
}

確認!!

共通ヘッダ・ファイル(common.h)にステータス情報構造体を宣言し、天使のステータス情報を全て構造体変数で管理するようプログラムを修正し、正常に動くかどうか確かめよう。


[ TOP ]