C/C++: 2008年6月アーカイブ
enumの列挙数って取得できないのかな。
/**
* ジョイスティック用キーコード
*/
enum E_JOY_CODE
{
JOY_UP = 0, ///< ボタン上 ※0始まりを明示
JOY_DOWN, ///< ボタン下
JOY_LEFT, ///< ボタン左
JOY_RIGHT, ///< ボタン右
JOY_BTN1, ///< ボタン1
JOY_BTN2, ///< ボタン2
JOY_BTN3, ///< ボタン3
JOY_BTN4, ///< ボタン4
JOY_BTN5, ///< ボタン5
JOY_BTN6, ///< ボタン6
JOY_CODE_END, ///< 最終メンバ(メンバ数取得用)
};
しょうがなく、最初の値を0って明示して、さらに最終列挙値を用意。これでJOY_CODE_ENDを見れば列挙数がわかるって細工したんだけど、他に上手いやり方ないか。
こんな構造体より、
/**
* ジョイスティックの入力状態
*/
struct ST_JOY_STATE
{
unsigned char ucJoyUp; ///< 上キー
unsigned char ucJoyDown; ///< 下キー
unsigned char ucJoyLeft; ///< 左キー
unsigned char ucJoyRight; ///< 右キー
unsigned char aryucJoyBtn[6]; ///< 数字キー
};
ST_JOY_STATE _stJoyState; ///< ジョイスティックの入力状態
こんな列挙型と配列使ったほうが、
/**
* ジョイスティック用キーコード
*/
enum E_JOY_CODE
{
JOY_UP, ///< ボタン上
JOY_DOWN, ///< ボタン下
JOY_LEFT, ///< ボタン左
JOY_RIGHT, ///< ボタン右
JOY_BTN1, ///< ボタン1
JOY_BTN2, ///< ボタン2
JOY_BTN3, ///< ボタン3
JOY_BTN4, ///< ボタン4
JOY_BTN5, ///< ボタン5
JOY_BTN6, ///< ボタン6
JOY_CODE_END, ///< 最終メンバ(メンバ数取得用)
};
unsigned char _aryucJoyState[JOY_CODE_END]; ///< ジョイスティックの入力状態
管理しやすいような気がした。
上のE_JOY_CODE列挙型があれば、ボタンの情報を関連付けやすいし、そんで構造体より配列の方がコードがシンプルになる。
※「///<」はDoxygen用のコメント
Part3 JavaScriptに学ぶ「言語の拡張性」 - ITpro
関数はローワーキャメルケース(先頭が小文字のキャメルケース)になっています。これは,クラス・ベースのオブジェクト指向言語では関数(メソッド)の命名規則がローワーキャメルケースであることに準じています。
オブジェクト指向言語だと、関数名はローワーキャメルケースにするのが一般的なのか。アッパーキャメルケースにしてたわ。直さなきゃ。ひたすら一括置換だ。
if文、for文とかにつける"{"についての話。
C、C++のコーディングだと、改行してから"{"を付ける。スクリプト言語とかWeb系の言語だと、右に"{"を付ける。もちろん規約があればそれに従う。無ければ、一般的な方に合わせる。
右"{"のとき、分岐処理のコメント前に改行するかしないかですごく悩む。
改行"{"だと、
// Aのとき
if (a == x)
{
FuncA();
FuncB();
}
// Bのとき
else if (b == x)
{
FuncC();
FuncD();
}
// その他
else
{
}
特に問題なし。
これが右"{"になると、
// Aのとき
if (a == x) {
FuncA();
FuncB();
// Bのとき ←この行の密集してる感が嫌だ
} else if (b == x) {
FuncC();
FuncD();
// その他
} else {
}
こんな風にごちゃごちゃする。じゃあ、コメント前に改行入れようと。
// Aのとき
if (a == x) {
FuncA();
FuncB();// Bのとき
} else if (b == x) {
FuncC();
FuncD();// その他
} else {
}
でも、コメント前改行ってことにすると、こんなときに↓
ってことになる。だから、密集してる感が漂ってたら、改行しましょうってことにした。// Aのとき
if (x == a) {
if (y == i) {
FuncA();
} else if (y == j) {
FuncB();
}
←この不自然な改行が気持ち悪い
// その他
} else {
}
でも、どういう基準で改行入れてるんだってことになって、、、あー、めんどくせ。。。
自分めんどくせ。
ゲーム処理クラスがDirectX処理クラスを直接使ってるけど、ゲーム処理も、描画エンジンとかに依存せずに独立したプログラムにしたい。ということで、一つクラスをラップすることにした。[]はクラス。
[DirectX Graphics処理]←――[描画] ←┐
[DirectX Audio処理] ←――[サウンド再生] ←+―[ゲーム処理]
[DirectInput処理] ←┬―[入力制御] ←┘
[Keyboard入力] ←┘
ゲーム処理クラスはDirectXなんて知らない。だから、描画クラスだけいじれば、ゲームプログラムを一切変更せずに描画エンジンが切り替えられる。
共通処理クラスCCommonっていうクラスを作ってて、その中でエラーログ出力関数みたいなどこでも使うような関数を用意して、いろんなとこで使ってたんだけど、DirectX処理クラスでこの共通処理クラスを使うのは、ちょっと変な気がしてきた。
というのも、DirectX処理クラスは、完全にゲームとは別に独立したものっていう考えで、本来はDLLとして存在するべきものにしてある(DLLにすると逆にめんどいことがあるんで、今は敢えてDLLにしてない)。だから、今作ってるゲームに限らず、このDirectX処理クラスは汎用的に使えるようにしてある。
本来独立して存在するものが、ゲーム処理クラスと同じ共通処理クラスを使用してるのは変。だから、DirectX処理クラスは、共通処理クラスを使わない方がいいな。
そもそも共通処理クラスっていうのが抽象的すぎた。ゲーム処理用の共通クラスとでもしておくか。
共通処理クラスに、デバッグトレースの関数を作った。
/**
* デバッグトレース
*
* @param[in] a_pszFormat 書式
*/
void CCommon::Trace(const char* a_pszFormat, ...)
{
#ifdef _DEBUG
va_list pcParam; // 引数リスト
char szTrace[512]; // 出力文字列// 可変引数の取得開始
va_start(pcParam, a_pszFormat);
// 出力文字列の作成
_vsnprintf(szTrace, sizeof(szTrace),
a_pszFormat, pcParam);
// 可変引数の取得終了
va_end(pcParam);// デバッグトレース
OutputDebugString(szTrace);
#endif
}
この関数はエラー発生時とかに使う。
// エラー発生時
if (! bRet)
{
CCommon::Trace("Errror: %s %s\n",
__FUNCTION__, pszErrorMessage);
}
上のフォーマットだと、例えば、
「Errror: CDI::Init DirectInput8オブジェクトの作成に失敗」
って文字列が出力されるんだけど、いろんなとこでこのトレースは使われるわけなんで、出力フォーマットは必ず統一されるようにした方がいい。
それで、直接トレース関数を使うわけじゃなくて、エラー発生用に使うトレース関数を別に作っといた。
/**
* エラー用デバッグトレース
*
* @param[in] a_pszFunction 関数名
* @param[in] a_pszError エラーメッセージ
*/
void CCommon::TraceOfError(char* a_pszFunction, char* a_pszError)
{
CCommon::Trace("Errror: %s %s\n",
__FUNCTION__, pszErrorMessage);
}
とりあえず、エラー発生した関数名とエラーメッセージだけ出力すればいいかな。ということで、エラー発生時に書く処理はこれ↓。
// エラー発生時
if (! bRet)
{
CCommon::TraceOfError(__FUNCTION__, pszErrorMessage);
}






