ゲームを作るならやはりジョイパッドを使いたいものです。そこで、今回はジョイパッドの入力状態取得についてお話します。
PCにつなげるジョイパッドをもし持っていなければ、PS2などのコントローラーをPCのUSBに接続出来るようにするコンバータなどお勧めします。
数百円で売っているので安く入手出来ます。
しかし、それすら面倒で、PS3のコントローラーをお持ちの方はこの辺の対応をしてPCでPS3のコントローラーを使用可能にしてもいいでしょう。
本章で紹介するプログラム自体はキーボードしか無くても動作可能です。
さて、DXライブラリでジョイパッドの入力状態を取得するにはGetJoypadInputState関数を使用します。リファレンスで仕様を確認してみましょう。
宣言 | int GetJoypadInputState( int InputType ) ; |
概略 | ジョイパッドの入力状態を得る |
引数 | InputType : 入力状態を取得するパッドの識別子 DX_INPUT_KEY_PAD1 : キー入力とパッド1 DX_INPUT_PAD1 : パッド1 DX_INPUT_PAD2 : パッド2 DX_INPUT_PAD3 : パッド3 DX_INPUT_PAD4 : パッド4 DX_INPUT_KEY : キー入力 |
戻り値 | パッドの入力状態 |
ジョイパッドの状態は4つまで取得でき、キーボードの入力と同時に取得したい人のために、DX_INPUT_KEY_PAD1の引数も指定出来るようになっています。
例えば、ジョイパッド1の入力状態を取得するには
int Pad1;
Pad1 = GetJoypadInputState( DX_INPUT_PAD1 );
と書くだけです。
Pad1には28種類のボタンの入力状態が格納されています。この状態で、ボタン1が押されているかどうかチェックしたい時は
if( Pad1 & PAD_INPUT_1){
// 押されている
}
のようにします。「&」は論理積です。後で詳しく説明します。ここでは
if( パッドの入力状態 & ボタンの定義 )
と書けば、マスクをかけ、そのボタンの入力状態がチェックできると覚えておいてください。
ボタンの定義は以下のようになっています。
PAD_INPUT_DOWN | // ↓チェックマスク(下キー or テンキーの2キー) |
PAD_INPUT_LEFT | // ←チェックマスク(左キー or テンキーの4キー) |
PAD_INPUT_RIGHT | // →チェックマスク(右キー or テンキーの6キー) |
PAD_INPUT_UP | // ↑チェックマスク(上キー or テンキーの8キー) |
PAD_INPUT_1 | // 1ボタンチェックマスク(Zキー) |
PAD_INPUT_2 | // 2ボタンチェックマスク(Xキー) |
PAD_INPUT_3 | // 3ボタンチェックマスク(Cキー) |
PAD_INPUT_4 | // 4ボタンチェックマスク(Aキー) |
PAD_INPUT_5 | // 5ボタンチェックマスク(Sキー) |
PAD_INPUT_6 | // 6ボタンチェックマスク(Dキー) |
PAD_INPUT_7 | // 7ボタンチェックマスク(Qキー) |
PAD_INPUT_8 | // 8ボタンチェックマスク(Wキー) |
PAD_INPUT_9 | // 9ボタンチェックマスク(ESCキー) |
PAD_INPUT_10 | // 10ボタンチェックマスク(スペースキー) |
. . . |
. . . |
PAD_INPUT_28 | // 28ボタンチェックマスク(初期状態では11番以降はキーボードキーとの対応はありません) |
キーボードの入力状態は、ゲームで主に使用される最小限のものしか取得出来ません。
全キーボードの入力状態を取得するには2.9章のプログラムを用います。
これらの定義を使って上記if文のようにマスクをかけることで入力状態を取得することが出来ます。
サンプルプログラムを確認して下さい。
ジョイパッドのAボタン定義にあたるボタンを押すか、キーボードのZキーを押すと「入力中です」と表示されます。
#include "DxLib.h" int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){ ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更,初期化,裏画面設定 int Pad; //ジョイパッドの入力状態格納用変数 // while( 裏画面を表画面に反映, メッセージ処理, 画面クリア ) while( !ScreenFlip() && !ProcessMessage() && !ClearDrawScreen() ){ Pad = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ; //入力状態をPadに格納 if( Pad & PAD_INPUT_A ){ //ボタン1またはZキーの入力フラグが立っていたら DrawFormatString( 0, 0, GetColor(255,255,255), "入力中です" ); } } DxLib_End(); return 0; }
実行結果
*** 以下、少し発展的な内容です。 ***
28個のボタン全てをチェックする為に、
if( Pad1 & PAD_INPUT_1)
if( Pad1 & PAD_INPUT_2)
if( Pad1 & PAD_INPUT_3)
・・・・
のように28個のif文を書くのは面倒です。ここで、変数Pad1に入っている入力状態の仕組みを理解します。
int型は本環境では4バイトつまり32bitです。
すなわち、32個の0と1を格納する入れ物が並んでいるわけです。
_ | _ | _ | _ | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
こんな感じですね。そして、下位のビットから順にボタンの入力状態が
0なら未入力、1なら入力、という状態で格納されています。
_ | _ | _ | _ | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 |
↑ ボ タ ン 28 の 入 力 状 態 |
↑ ボ タ ン 27 の 入 力 状 態 |
... | ↑ ボ タ ン 5 の 入 力 状 態 |
↑ ボ タ ン 4 の 入 力 状 態 |
↑ ボ タ ン 3 の 入 力 状 態 |
↑ ボ タ ン 2 の 入 力 状 態 |
↑ ボ タ ン 1 の 入 力 状 態 |
論理積について知らない人は、調べてみましょう。
& は論理積を計算する演算子です。簡単に論理積を説明すると
0 & 0 は 偽
0 & 1 は 偽
1 & 0 は 偽
1 & 1 は 真
という規則を持った計算です。
ここで、32bitでは数が多いので、8bitに減らして説明します。
今、パッドの入力状態が全ボタン入力中であったとしましょう。
11111111 …①
このようになっています。
この時、例えばボタン3が入力中かどうか確認したい時は
00000100 …②
と論理積を計算します。論理積は掛け算に似ていて、0に何をかけても0です。
すなわち3桁目以外は入力状態にかかわらず必ず0になります。
ですから①と②の論理積の計算結果は3bit目のみマスクされて
00000100 …③
となります。③を10進数で表現すると4ですね。マスクした結果、0でなければそのボタンが入力中であることが分かります。
0000100をC言語で表現には「1<<2」と書きます。1を2bit左にずらすという意味です。
このように、ビットを0から27までずらしてマスクをかけることで、28種類のボタンの入力状態が識別出来ます。
このことをfor文で一括処理出来るようにしました。サンプルプログラムをご覧ください。
#include "DxLib.h" int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){ ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更,初期化,裏画面設定 int Pad; //ジョイパッドの入力状態格納用変数 // while( 裏画面を表画面に反映, メッセージ処理, 画面クリア ) while( !ScreenFlip() && !ProcessMessage() && !ClearDrawScreen() ){ Pad = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ; //入力状態をPadに格納 for( int i=0; i<28; i++ ){ //ボタン28個分ループ if( Pad & (1<<i) ){ //ボタンiの入力フラグが立っていたら DrawFormatString( 0, i*15, GetColor(255,255,255), "%dのキーが押されています", i ); } } } DxLib_End(); return 0; }
実行結果
適当にボタンをあれこれ押してみたところです。
キーボードならZ、X、Cキーや十字キー等を押してみて下さい。
このようにすれば一括処理出来ますね。
- Remical Soft -