前章の続きです。
本章では、main.cppと「プレイヤー」の他に「キーボード」というモジュールを作り
キーボードモジュールで計算したキーの入力状態をプレイヤーモジュールから参照して操作出来るようにしてみましょう。
今回は、「Keyboard」モジュールを追加しますので、前章の手順で「Keyboard.cpp」と「Keyboard.h」をソリューションに追加しておいて下さい。
さて、キーボードモジュールにはこちらの章の gUpdateKey関数 を使います。
状態を計算した後、どうやって他のモジュールからキーの入力状態を知ることができるのか。
それには関数の返り値を使います。
int Keyboard_Get( int KeyCode );
という関数を作り、キーの入力状態を確認したいキーコードを関数に渡します。
するとその関数は渡されたキーコードの入力状態を返り値で返すというわけです。
プログラムコードで見てみましょう。
/* Keyboard.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にする } } } // KeyCodeのキーの入力状態を取得する int Keyboard_Get( int KeyCode ){ return m_Key[ KeyCode ]; // KeyCodeの入力状態を返す }
Keyboard_Update関数は、前述の2.9章のように、main.cppから毎フレーム呼び出されます。
状態が更新された後、Keyboard_Get関数 を通して他の関数からキーの入力状態が参照出来ます。
引数である KeyCode にはDXライブラリで定められている定義を渡します。キーコードについては2.9章をご覧下さい。
ヘッダファイルには関数のプロトタイプ宣言を書いておきます。
/* Keyboard.h */
#ifndef DEF_KEYBOARD_H //二重include防止 #define DEF_KEYBOARD_H // キーの入力状態を更新する void Keyboard_Update(); // 引数のキーコードのキーの入力状態を返す int Keyboard_Get( int KeyCode ); #endif
プレイヤーモジュールは、Player_Update関数 の中身のみ変更して、上下キー入力によってキャラを上下出来るようにします。
実装は簡単です。例えば下キーなら Keyboard_Get( KEY_INPUT_DOWN ) で入力状態が取得できるわけですから
void Player_Update(){
if( Keyboard_Get( KEY_INPUT_UP ) > 0 ){
m_y--;
}
if( Keyboard_Get( KEY_INPUT_DOWN ) > 0 ){
m_y++;
}
}
このように書くことで、Keyboardモジュールで計算したキーの入力状態を参照出来ます。
では Playerモジュール のプログラムを見てみましょう。
/* Player.cpp */
#include "DxLib.h" #include "Keyboard.h" static int m_Image; static int m_y; // 初期化をする void Player_Initialize(){ m_Image = LoadGraph("画像/キャラクタ01.png"); m_y = 0; } // 動きを計算する void Player_Update(){ if( Keyboard_Get( KEY_INPUT_UP ) > 0 ){ m_y--; } if( Keyboard_Get( KEY_INPUT_DOWN ) > 0 ){ m_y++; } } // 描画する void Player_Draw(){ DrawGraph( 0, m_y, m_Image, TRUE ); } // 終了処理をする void Player_Finalize(){ DeleteGraph( m_Image ); }
/* Player.h */
変更なし
このように関数を通して変数の値を参照することで、変数の値を書きかえる心配無く参照することが出来ます。
最期に main.cpp の変更部分を見てみましょう。
/* main.cpp */
#include "DxLib.h" #include "Player.h" #include "Keyboard.h" int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){ ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen( DX_SCREEN_BACK ); Player_Initialize();// 初期化 while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){ Keyboard_Update(); Player_Update(); // 計算 Player_Draw(); // 描画 } Player_Finalize(); // 終了処理 DxLib_End(); return 0; }
Keyboard_Update関数 を毎フレーム呼び出しているだけです。呼び出せるように、Keyboardモジュールのヘッダファイルをincludeしています。
実行結果
本章で紹介したプロジェクトファイルはこちらです。
プロジェクトファイルはこちら
これまでに紹介したように、モジュール単位でファイルを分割し、グローバル変数はファイル内のみで閉じるようにすることで、
安全にそして管理しやすい設計が出来るようになります。
しかしこれでは、対戦プレイなどでプレイヤーが2人になった時、困ります。
グローバル変数は一つなので、二つの状態を持つことが出来ません。
そこで、変数の実体は、main.cpp で持ち、純粋に処理のみをモジュールにやらせてはどうかという考えになります。
次の章で、多重化出来るモジュール設計についてお話します。
- Remical Soft -