ゲーム内のデータ(数値)は刻々と変化する物。デバッグ中にそれらを画面に映し確認できると
作業がしやすくなります。
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);
こんな感じになります。型を気にせず放り込めるので、楽に表示が出来るようになりました。
今回は数値だけですが、型を増やすなどするともっと良くなりますね。