第10章 背景表示の様々なテクニック

シューティングゲームや単純アクションゲームなどでは、背景がスクロールするものが多い。この章では、様々な背景スクロールのプログラム例を紹介する。

10-1 星を降らせてスクロールしているように見せる

真っ黒な背景に星を降らせば、スクロールしているように見える。背景は黒く塗りつぶせばいいので、この処理で必要な画像は「降ってくる星」だけで済むため、ビデオメモリを節約できる。

プログラム例(Game.cpp)

【マクロ定義】

#define STAR_MAX    50
#define STAR_WIDTH  2
#define STAR_TIMING 15
#define STAR_SPEED  4

【背景処理用グローバル変数の定義】

/* 背景用変数 */
static struct {
    int x, y, flg;
} Star[STAR_MAX];
static int StarTiming;

【初期化処理】

//-----------------------------------------------------------------------------
// 関数名 : GameInit()
// 機能概要: スタート処理初期化
//-----------------------------------------------------------------------------
void GameInit(HWND hWnd)
{
    int i;

    //------------------------------------------------------- 各変数の初期化
    /* 背景処理 */
    for (i=0 ; i<STAR_MAX ; i++)
        Star[i].flg = 0;
    StarTiming = 0;
    /* 自キャラ(カーソルキーで移動) */
    StatusInit(&MyChara, 0, 0, 40, 40, 310, 230, 4, 4);
    /* ゴキブリ(動かない) */
    StatusInit(&Goki, 64, 394, 96, 426, 400, 300, 0, 0);

    //------------------------------------------------------- フレームナンバーセット
    g_FrameNo = GAME_FRAME;

}

【背景描画処理】

//-----------------------------------------------------------------------------
// 関数名 : BackDraw()
// 機能概要: 背景描画処理
//-----------------------------------------------------------------------------
static void BackDraw(void)
{
    HRESULT      hRet;
	DDBLTFX      ddBltFx;
	RECT         rcDest;
	int          i;

    ZeroMemory(&ddBltFx, sizeof(ddBltFx));
    ddBltFx.dwSize = sizeof(ddBltFx);

    // 背景を黒く塗りつぶす
    ddBltFx.dwFillColor = 0;
    hRet = g_pDDSBack->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx); 
    if (hRet != DD_OK)
        return;

    // 星(白い四角)を表示する
    ddBltFx.dwFillColor = 255;
    for (i=0 ; i<STAR_MAX ; i++)
    {
        if (Star[i].flg > 0)
        {
            // 表示
            SetRect(&rcDest, Star[i].x, Star[i].y, Star[i].x + STAR_WIDTH, Star[i].y + STAR_WIDTH);
            hRet = g_pDDSBack->Blt(&rcDest, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx);
            if (hRet != DD_OK)
                return;
            // 移動
            Star[i].x -= STAR_SPEED;
            if (Star[i].x <= 0)
                Star[i].flg = 0;
        }
    }

    // 一定間隔ごとに星を増やす
    StarTiming++;
    if (StarTiming >= STAR_TIMING)
    {
        StarTiming = 0;
        for (i=0 ; i<STAR_MAX ; i++)
        {
            if (Star[i].flg == 0)
            {
                Star[i].flg = 1;
                Star[i].x = 640 - STAR_WIDTH;
                Star[i].y = (int)((480.0 - STAR_WIDTH) * ((double)rand() / (double)RAND_MAX));
                break;
            }
        }
    }

}

【解説】

  1. 一定時間ごとに星を増やす(最大STAR_MAX個)
  2. 一定時間が経過したら、出現させる星のy座標をランダムにセットする
  3. 星の描画はBltメソッドで、小さな矩形を白く塗りつぶすことにより行っている
    (用意した星の画像を転送してもよい)
  4. 星が消えたらflgを0にセットすることにより、次に出現するときは違うy座標から表示させる

10章1練習問題1(必須)

第10章用プログラムをダウンロードしてプロジェクト作成後、上記修正を行い、ゲーム画面で星が右から左に流れることを確認しなさい。

[ 実行結果サンプル ]

10章1練習問題2(自由)

練習問題1のプログラムを修正する。50個の星のうち、任意の個数の星だけを他の星よりも早く流れるように改造しなさい。

[ 実行結果サンプル ]

10章1練習問題3(自由)

星の画像を用意し、用意した画像を表示するようプログラムを修正しなさい。また、横スクロールではなく、縦にスクロールさせなさい。


[ TOP ] [ NEXT ]