ゲーム内のデータ(数値)は刻々と変化する物。デバッグ中にそれらを画面に映し確認できると
作業がしやすくなります。
LPD3DXFONT pFont; //フォント
HRESULT InitFont(LPD3DXDEVICE9 pDevice) { //文字列フォントの設定 if(FAILED(D3DXCreateFont(pDevice, 14, //文字高さ 7, //文字幅 FW_BOLD, //フォントスタイル NULL, //ミップマップモデルの数 FALSE, //斜体にするかどうか SHIFTJIS_CHARSET, //文字セット OUT_DEFAULT_PRECIS, PROOF_QUALITY, FIXED_PITCH | FF_MODERN, "tahoma", //フォントの種類 &pFont))) { return E_FAIL; } return TRUE; }
D3DXCreateFont関数でフォントを生成します。 フォントの種類はワードで使用されているものは使える様です。 また、参考書にはtahomaフォントが例にあげられているものが多いです。 なので、ここでもtahomaにしておきます。
//文字列レンダリング関数 VOID RenderString(LPD3DXFONT pFont, LPSTR szStr, //表示する文字列 INT iX, //表示X座標 INT iY) //表示Y座標 { RECT rect = {iX, iY, 0, 0}; //表示領域 //文字列サイズを計算 pFont->DrawText( NULL, szStr, -1, //表示サイズ(-1で全部) &rect, //表示範囲 DT_CALCRECT, //表示範囲に調整 NULL); //そのサイズでレンダリング pFont->DrawText( NULL, szStr, -1, //表示サイズ(-1で全部) &rect, //表示範囲 DT_LEFT | DT_BOTTOM, //左詰めで両端揃え 0xff00ff00); //色 }
■使い方
RenderString(pFont, "文字列", 10, 10);
これで文字列の表示が出来ました。 たかがデバッグ文字列、されどデバッグ文字列です。これが有ると無いとで バグの発見しやすさが大分変わります。
■扱いやすくしてみる
上記の方法では、文字列をRenderString関数に渡すため、例えば数値を表示する際に
char str[64]; sprintf(str, "%d", 何かの値); RenderString(pFont, str, 10, 10);
という感じに、毎回値を文字列に変換するという作業を入れなければなりません。 そこでオーバーロードを利用し扱いやすくしてみます。
#pragma once #include <d3dx9.h> #include <stdio.h> #include <string> #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p) = NULL; } } using namespace std; class CDebugFont { private: LPD3DXFONT m_pFont; TCHAR c[20]; string str; public: CDebugFont(LPDIRECT3DDEVICE9 pDevice) { m_pFont = NULL; //文字列レンダリングの初期化 if(FAILED(D3DXCreateFont(pDevice, 18, //高さ 9, //幅 FW_REGULAR, //普通(BOLD:太字) NULL, //下線 FALSE, //斜体 SHIFTJIS_CHARSET, //文字セット OUT_DEFAULT_PRECIS, //固定 PROOF_QUALITY, //固定 FIXED_PITCH | FF_MODERN, "tahoma", //フォント &m_pFont))) { MessageBox(NULL, "フォントを作成できません","Error", MB_OK); } }; ~CDebugFont() { SAFE_RELEASE(m_pFont); }; private: VOID Conversion(short value) { sprintf(c, "%d", value); str += c; } VOID Conversion(unsigned short value) { sprintf(c, "%d", value); str += c; } VOID Conversion(int value) { sprintf(c, "%d", value); str += c; } VOID Conversion(unsigned int value) { sprintf(c, "%d", value); str += c; } VOID Conversion(float value) { sprintf(c, "%.3lf", value); str += c; } VOID Conversion(double value) { sprintf(c, "%.3lf", value); str += c; } VOID Conversion(bool value) { if(value) { str += "true"; } else { str += "false"; } } public: template <typename TYPE> VOID Render(LPSTR szStr, TYPE type, int x, int y) { str += szStr; Conversion(type); //文字列に置き換える RECT rect = {x, y, 0, 0}; //表示領域 m_pFont->DrawText(NULL, str.c_str(), -1, &rect, DT_CALCRECT, NULL); m_pFont->DrawText(NULL, str.c_str(), -1, &rect, DT_LEFT | DT_BOTTOM, 0xffffffff); str = (""); //空文字でクリア } };
Conversion関数は名前の通り値の変換を行い、その後文字列をつなげています。 使い方は
CDebugFont DebugFont = new CDebugFont(pDevice); DebugFont->Render("文字列1", value1, 10, 10); DebugFont->Render("文字列2", value2, 10, 30); DebugFont->Render("文字列3", value3, 10, 50); DebugFont->Render("文字列4", value4, 10, 70);
こんな感じになります。型を気にせず放り込めるので、楽に表示が出来るようになりました。
今回は数値だけですが、型を増やすなどするともっと良くなりますね。