Windowsゲームプログラミング

Windowsゲームプログラミング
【ご購入はこちらへ】

本書は C 言語の習得者が Windows 上で動作するグラフィカルなゲームアプリケーションを開発できるようになるまでを導く、ゲーム開発と Windows API のための学習書です。 複雑な C++ 言語は使わずに、C 言語だけで Windows 上で動作するウィンドウアプリケーションの開発方法をシンプルに、サンプルコードを交えながら解説します。

Windows 上で動作するグラフィカルなゲームプログラムを作成するには、Windows API (Windows が提供しているウィンドウなどを制御するための関数群)を理解しなければなりません。 本書では、ゲーム開発に必要な API や、応用可能と思われる API を中心にウィンドウアプリケーションの開発方法を解説するため、Windows プログラミング入門者がスマートにゲーム開発にまでたどり着くことができます。 通常の Windows API 入門書籍では扱われないような、部分透明や半透明などのビットマップ処理方法なども、サンプルコード付きで解説しています。

B5変形 400ページ CD-ROM x 1

定価:2,800円(本体)

ISBN:4-7973-2545-3

Staff

著者: 赤坂 玲音

カバーデザイン: 原てるみ+宮田法子(plum)

発行者: 稲葉 俊夫

発行所: ソフトバンク パブリッシング株式会社

製作: 編集マッハ

印刷: 株式会社 厚徳社


第1版 サポート

ソフトバンクパブリッシングのサポートページ

現在見つかっている本書の技術的な誤り、誤植の修正を以下に公開します。

正誤表
原文訂正
16 表1.3UNICODE が定義されていれば PSTR、そうでなければ PWSTRUNICODE が定義されていれば PWSTR、そうでなければ PSTR
17 表1.3UNICODE が定義されていれば PCSTR、そうでなければ PCWSTRUNICODE が定義されていれば PCWSTR、そうでなければ PCSTR
17 表1.3LCPTSTRLPCTSTR
32 表1.7ウィンドウが再描画されたときに発生ウィンドウの描画が必要になったときに発生
79ペンのスタイルとしては実践、破線、点線などがペンのスタイルとしては実線、破線、点線などが
268100回程度しかWN_TIMERメッセージを発行できないのです100回程度しかWM_TIMERメッセージを発行できないのです
297NULL , TEXT("m1.bmp") , IMAGE_BITMAP ,NULL , TEXT("fore1.bmp") , IMAGE_BITMAP ,
297NULL , TEXT("m2.bmp") , IMAGE_BITMAP ,NULL , TEXT("fore2.bmp") , IMAGE_BITMAP ,
332TruenPiece()TurnPiece()
332MovePiece(PIEVE_DOWN)MovePiece(PIECE_DOWN)
333 表9.1TruenPiece()TurnPiece()

-ソースの修正-

04_01_01.c
修正前 1行目〜
#include <windows.h>

#define APP_NAME TEXT("Sample_MainWindow")
修正後 1行目〜
#define _WIN32_WINNT 0x0400
#include <windows.h>

#define APP_NAME TEXT("Sample_MainWindow")
修正理由
一部の開発環境を除いて、識別子 WM_MOUSEWHEEL が宣言されていないという問題が発生します。WM_MOUSEWHEEL は winuser.h ヘッダで宣言されていますが、#define _WIN32_WINNT 0x0400 が宣言されていないと認識されません。

05_03_00.c
修正前 25行目〜
case WM_LBUTTONUP:
	SetWindowLong(hWnd , GWL_STYLE , WS_POPUP);
	ShowWindow(hWnd , SW_SHOW);
	return 0;
case WM_RBUTTONUP:
	SetWindowLong(hWnd , GWL_STYLE , WS_OVERLAPPEDWINDOW);
	ShowWindow(hWnd , SW_SHOW);
	return 0;
修正後 25行目〜
case WM_LBUTTONUP:
	SetWindowLong(hWnd , GWL_STYLE , WS_POPUP);
	SetWindowPos(
		hWnd , HWND_TOP , 0 , 0 , 0 , 0 ,
		SWP_FRAMECHANGED | SWP_NOMOVE |
		SWP_NOSIZE | SWP_DRAWFRAME | 
		SWP_SHOWWINDOW
	);
	return 0;
case WM_RBUTTONUP:
	SetWindowLong(hWnd , GWL_STYLE , WS_OVERLAPPEDWINDOW);
	SetWindowPos(
		hWnd , HWND_TOP , 0 , 0 , 0 , 0 ,
		SWP_FRAMECHANGED | SWP_NOMOVE |
		SWP_NOSIZE | SWP_DRAWFRAME | 
		SWP_SHOWWINDOW
	);
	return 0;
修正理由
Windows XP より以前の Windows (98/Me/2000 など) で発生した不具合を解消しました。 ウィンドウデータの中には、キャッシュされており、SetWindowLong 関数を使って変更しても SetWindowPos 関数を呼び出すまでは有効にならないものもあります。 特に、フレームスタイルを変更した場合は、SWP_FRAMECHANGED フラグをセットして SetWindowPos 関数を呼び出すさなければ、キャッシュが正しく更新されません。

06_03_00.c
修正前 24行目〜
hBitmap = LoadImage(
	(HINSTANCE)GetWindowLong(hWnd , GWL_HINSTANCE) ,
	BMPFILE , IMAGE_BITMAP ,
	0 , 0 , LR_LOADFROMFILE
);
修正後 24行目〜
hBitmap = LoadImage(
	NULL , BMPFILE , IMAGE_BITMAP , 0 , 0 , LR_LOADFROMFILE
);
修正理由
ファイルイメージを読み込む場合は LoadImage() の最初の引数は NULL を指定します。

07_03_00.c
修正前 38行目
LRESULT CALLBACK WindowProc (
	HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
) {
	ThreadParam param;
	DWORD dwID;
修正後 38行目
LRESULT CALLBACK WindowProc (
	HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
) {
	static ThreadParam param;
	DWORD dwID;
修正理由
スレッド起動時に WindowProc 関数のローカル変数のポインタを引数に渡しますが、スレッド実行時に WindowProc のローカル変数が破棄されてしまった場合正常に動作しないことがあります。そのため、ローカル変数が破棄されないように static を宣言に追加します。

07_04_00.c
修正前 43行目
case WM_LBUTTONUP:
	if (ResumeThread(hThread) == 0) SuspendThread(hThread);
	return 0;
修正後 43行目
case WM_LBUTTONUP:
	if (((LONG)ResumeThread(hThread)) <= 0) SuspendThread(hThread);
	return 0;
修正理由
システムによっては ResumeThread() 関数はサスペンドされていない hThread を渡すと失敗する可能性があります。そのため、ResumeThread() が失敗した場合もサスペンドするように記述した方が安全です。

sample1.c
修正前 24行目〜
/*フィールドのマスのテキスト表現*/
#define PIECE_FALSE 	TEXT("□")
define PIECE_TRUE 		TEXT("■")
修正後 24行目〜
/*フィールドのマスのテキスト表現*/
#define PIECE_FALSE 	TEXT("□")
#define PIECE_TRUE 	TEXT("■")
修正理由
#define プロセッサディレクティブの # がありませんでした。このソースコードを修正しないままコンパイルした場合、コンパイルエラーが報告されます。付属の実行ファイルに問題はありません。

sample2.c
修正前 126行目〜
if (hBackBmp) {
	HDC hBackDC = CreateCompatibleDC(hdc);
	SelectObject(hBackDC , hBackBmp);
	BitBlt(hdc , 0 , 0 , WND_WIDTH , WND_HEIGHT , hBackDC , 0 , 0 , SRCCOPY);
	DeleteDC(hBackDC);
	DeleteObject(hBackDC);
}
修正後 126行目〜
if (hBackBmp) {
	HDC hBackDC = CreateCompatibleDC(hdc);
	SelectObject(hBackDC , hBackBmp);
	BitBlt(hdc , 0 , 0 , WND_WIDTH , WND_HEIGHT , hBackDC , 0 , 0 , SRCCOPY);
	DeleteDC(hBackDC);
}
修正理由
DeleteObject(hBackDC); は不要です。hBackDC は DeleteDC() 関数で削除されています。

-よくある質問-

「'HGDIOBJ' から 'HBRUSH' に変換できません」という警告、またはエラーが発生します。
型変換に関連するエラーが報告される場合、ソースコードが C++ 言語としてコンパイルされていないかどうかを確認してください。本書のサンプルはすべて C 言語としてコンパイルを対象としているため、C++ 言語としてのコンパイルは保障されません。 HGDIOBJ から HBRUSH への暗黙変換に対する警告が出るかどうかは、コンパイラ、またはコンパイラの設定に依存します。 警告やエラーを解決するにはキャスト演算子を使って明示的に方変換を行ってください。
リンカのエラー「未解決の外部シンボル」が発生します。
一部の開発環境を除いて、AlphaBlend 関数、timeGetTime 関数、PlaySound 関数などを利用するプログラムでは、インポートライブラリをリンカに認識させる必要があります。 Winmm.lib や msimg32.lib など、必要なインポートライブラリをリンカに設定してください。

本書の技術的な誤り、誤字脱字などが見つかれば third@fine.ocn.ne.jp までご連絡ください。

乱丁本、落丁本など、本の物理的な欠陥については WisdomSoft 及び赤坂玲音はサポートしておりません。


戻る