第2章 Windowsプログラムをゲーム用に改造する

この章では、第1章の知識を元に、スケルトンプログラムをゲーム用に改造する手順を学ぶ。

2-1 前準備

改造する元となるプロジェクトを、以下の手順で作成しておく。

(a) プロジェクト「ddrawsamp01」を作成

任意の場所(Cドライブのルートなど)に、プロジェクト「DDrawSamp01」を新規に作成する。

(b) Windowsスケルトンプログラムを用意する

作成したプロジェクトに、ソースファイル「WinMain.cpp」を新規作成する。
(「プロジェクト」→「プロジェクトへ追加」→「新規作成」を選び、ファイルを「C++ソースファイル」、ファイル名を「WinMain.cpp」、位置をプロジェクトを作成したフォルダに設定し、OKボタンをクリック)

以下のプログラムは、Windowsスケルトンプログラムをゲーム開発用にアレンジしたものである。変更部分は赤色で表示した。このプログラムを、作成したWinMain.cppに入力する。

//=============================================================================
//      Windowsプログラミング スケルトンプログラム
//=============================================================================

#include <windows.h>
#include <windowsx.h>

// プロトタイプ宣言
LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
BOOL InitApp(HINSTANCE, int);

// グローバル変数
HWND hWnd;
char szWinName[] = "Skeleton";

int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode)
{
    MSG msg;

    /* 表示するウィンドウの定義、登録、表示 */
    if (!InitApp(hThisInst, nWinMode))
        return (FALSE);

    /* メッセージループ */
    while (GetMessage(&msg, NULL, 0, 0)) // Windowsは「WM_QUIT」メッセージを受けると偽(0)を戻す
    {
        TranslateMessage(&msg); // キーボード利用を可能にする
        DispatchMessage(&msg);  // 制御をWindowsに戻す
    }

    return msg.wParam;

}

//=============================================================================
//      ウィンドウプロシジャ関数(WindowProcedure)
//=============================================================================
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_KEYDOWN: // キーを押したとき
            switch (wParam)
            {
                case VK_ESCAPE:
                    PostMessage(hWnd, WM_CLOSE, 0, 0);
                    break;
            }
            break;
        case WM_DESTROY:        // 閉じるボタンをクリックした時
            PostQuitMessage(0); // WM_QUITメッセージを発行
            break;
        default:                // 上記以外のメッセージはWindowsへ処理を任せる
            return DefWindowProc(hWnd, message, wParam, lParam);
    }

    return 0;

}

//=============================================================================
//  関数名 :InitApp
//  機能概要:表示するウィンドウの定義、登録、表示
//  戻り値 :正常終了のとき1、以上終了のとき0
//=============================================================================
BOOL InitApp(HINSTANCE hThisInst, int nWinMode)
{
    WNDCLASSEX wc;

    /* ウィンドウクラスを定義する */
    wc.hInstance = hThisInst;                        // このインスタンスへのハンドル
    wc.lpszClassName = szWinName;                    // ウィンドウクラス名
    wc.lpfnWndProc = WinProc;                        // ウィンドウ関数
    wc.style = 0;                                    // ウィンドウスタイル(デフォルト)
    wc.cbSize = sizeof(WNDCLASSEX);                  // WNDCLASSEX構造体のサイズを設定
    wc.hIcon = LoadIcon(hThisInst, IDI_APPLICATION); // ラージアイコン
    wc.hIconSm = LoadIcon(hThisInst, IDI_WINLOGO);   // スモールアイコン
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);        // カーソルスタイル
    wc.lpszMenuName = NULL;                          // メニュー(なしに設定)
    wc.cbClsExtra = 0;                               // エキストラ(なしに設定)
    wc.cbWndExtra = 0;                               // 必要な情報(なしに設定)
    wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); // ウィンドウの背景(黒に設定)

    /* ウィンドウクラスを登録する */
    if (!RegisterClassEx(&wc))
        return (FALSE);

    /* ウィンドウクラスの登録ができたので、ウィンドウを生成する */
    hWnd = CreateWindowEx(
        WS_EX_TOPMOST,          // 拡張ウィンドウスタイル
        szWinName,                // ウィンドウクラスの名前
        "Skeleton 背景を黒に",    // ウィンドウタイトル
        WS_VISIBLE | WS_POPUP, // ウィンドウスタイル
        0,                        // ウィンドウの左角X座標
        0,                        // ウィンドウの左角Y座標
        640,                      // ウィンドウの幅
        480,                      // ウィンドウの高さ
        NULL,                     // 親ウィンドウ(なし)
        NULL,                     // メニュー(なし)
        hThisInst,                // このプログラムのインスタンスのハンドル
        NULL                      // 追加引数(なし)
    );

    ShowWindow(hWnd, nWinMode);   // ウィンドウを表示する
    UpdateWindow(hWnd);

    return (TRUE);

}

Windowsスケルトンプログラムとの変更点は次のとおり。

  1. フルスクリーンのゲームの場合、ウィンドウの枠は表示させないので、枠のないスタイルに変更する。
  2. 枠がなくなると、ウィンドウを閉じるボタンがなくなり、ウィンドウを閉じることができなくなるため、ESCキーを押したらウィンドウが閉じるようにした。

(c) 動作確認

修正したらビルド、実行を行い、エラーが出ることなくウィンドウが表示されるかどうかを確認する。
枠がない真っ黒なウィンドウが表示される!!

(d) DirectXをビルドするためには (重要!!)

DirectXをビルドするためにはDirectDraw関係のライブラリを使用できるよう、プロジェクトの設定を変更しなければならないので、次のように設定する。

  1. 「プロジェクト」→「設定」を選択
  2. 「リンク」タブをクリックし、「オブジェクト/ライブラリ モジュール」に以下のライブラリを追加
    • ddraw.lib
    • dxguid.lib
    • winmm.lib

  3. 追加したら「OK」ボタンをクリック
  4. 「ツール」→「オプション」を選択
  5. 「ディレクトリ」のタブをクリックし「インクルードファイル」を選択し「C:\mssdk\include」をで一番上に持ってくる。
  6. 「ライブラリファイル」を選択し「C:\mssdk\lib」をで一番上に持ってくる。
  7. 「OK」ボタンをクリック




補足

1.拡張ウィンドウスタイルの「WS_EX_TOPMOST」について
このスタイルを使って作成されたウィンドウは、すべてのトップレベルでないウィンドウの上におかれ、そのウィンドウがアクティブでなくなっても、そのままトップレベルに残る。
2.ウィンドウスタイルの「WS_VISIBLE」について
初期状態で可視のウィンドウを生成する。
3.ウィンドウスタイルの「WS_POPUP」について
ポップアップウィンドウを作成する。

詳しくはMSSDKを参照すること。


[ TOP ] [ Next ]