DXライブラリとC言語でゲーム作成日記2コード目。1つのファイルが肥大化する前に分割する方法について。DXライブラリというよりはVisual Studioでファイルを分割する方法になります。
ファイルを分割する意味
キー入力ができるようになったので次は画像や3Dモデルを表示させて動かして…といきたいところだがその前に意識しておきたいのがファイルの分割。
現在キー入力のみだけ書いているのでコードは短く済んでいるが、これからシーン管理やプレイヤー、敵、マップ、エフェクト、BGMなどいろんな処理を書いていくことになる。これらの処理を1つのファイルに全部書き込んでしまうとどこに何の機能があったかわかりにくくなってしまう。グローバル変数関連で思わぬバグを生み出してしまうことも。
ということでとある単位でファイルを分割することを意識しておきたい。今回は試しに前回書いたキー入力の部分をメイン関数のあるファイルから分離してみる。以降はVisual Studioを使っていることを前提で書きます。
Visual Studioでファイルを分割する
上のメニューバーから「プロジェクト」→「新しい項目の追加」を選択する。
C++ファイル(.cpp)を選択し、名前を入力して「追加」をクリックする。
追加されたファイルに関数を追加する。今回はメインファイルからコードを切り取って移動させる。なお別ファイルの移動に伴い関数名などを変更している。
<追加したcppファイルのコード>
#include "DxLib.h" static int m_key[256]; // キーが押されているフレーム数を格納する // キーの入力状態を更新する void Keyboard_Update() { char tmpKey[256]; // 現在のキーの入力状態を格納する // 全てのキーの入力状態を得る GetHitKeyStateAll(tmpKey); for (int i = 0; i < 256; i++) { if (tmpKey[i] != 0) { // i番のキーコードに対応するキーが押されていたら m_key[i]++; // 加算 } else { // 押されていなければ m_key[i] = 0; // 0にする } } } int Keyboard_Get(int KeyCode) { return m_key[KeyCode]; // KeyCodeの入力状態を返す }
もう一度新しい項目の追加のウィンドウを開いて今度は「ヘッダファイル(.h)」を選択し、先ほど追加したcppファイルと同じ名前を入力して「追加」をクリックする。
追加されたヘッダファイルに#pragma onceが記述されているがこれを以下のコードに書き換える。
#ifndef DEF_(大文字のヘッダファイル名)_H #define DEF_(大文字のヘッダファイル名)_H #endif
どちらも二重インクルードを防止するもの。ファイルの数が増えてくるとうっかり同じヘッダファイルをインクルードしてしまうことが多々あるのでこれを入れておくと事故を防げる。
別に#pragma onceのままでもいいが他の環境で使えなくなる可能性があるのでこちらを推奨(特にチームで開発する場合)。
次に追加したcppファイルに書いた関数のプロトタイプ宣言をする。上の二重インクルード防止を含めるとヘッダファイルのコードは以下のようになる。
<追加したヘッダファイルのコード>
#ifndef DEF_KEY_H #define DEF_KEY_H //キーの入力状態を更新する void Keyboard_Update(); //引数のキーコードのキー入力状態を返す int Keyboard_Get(int KeyCode); #endif
これでファイルの分割自体は完了だが、このままでは他のファイルから参照できないので次のことをする。
メインファイルに先ほど追加したヘッダファイルをインクルードし、関数を呼び出す。コードとしては以下のようになる。
<メインファイルのコード>
#include "DxLib.h" #include "Key.h" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // ウィンドウモードに設定 ChangeWindowMode(TRUE); // DXライブラリ初期化処理 if (DxLib_Init() < 0) { //エラーなら終了する return -1; } //描画先を裏画面にする SetDrawScreen(DX_SCREEN_BACK); // 画面モードの変更 SetGraphMode(800, 600, 32); // while(裏画面を表画面に反映, メッセージ処理, 画面クリア) while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) { Keyboard_Update(); DrawFormatString(0, 0, GetColor(255, 255, 255), "ESCキーで終了します"); if (Keyboard_Get(KEY_INPUT_ESCAPE) > 0) { break; } } DxLib_End(); // DXライブラリ終了処理 return 0; }
あとは実行して前回と同じ結果になれば成功。
まとめ
簡単にまとめると以下のようになる。
- cppファイルとヘッダファイルを追加する
- cppファイルに関数を書く
- ヘッダファイルに2で書いた関数のプロトタイプ宣言を書く(二重インクルード防止も忘れずに)
- 他のファイルに追加したヘッダファイルをインクルードする
- 関数を呼ぶ
ちなみに「ファイルを分ける単位」はキー入力やシーン管理、プレイヤー、敵、マップ、エフェクト、BGMといった具合に分けておくといいらしい。特にプレイヤーや敵、エフェクトなどゲーム中同時に複数存在するものは一括で処理できるようにしておくと便利。
参考にさせてもらったサイト:新ゲームプログラミングの館 複数のファイルに分けてコンパイルにする
コメント