DirectInputにもコントローラーの入力を取得する機能があるのだが、
より新しい「XInput」という規格の方が使いやすいので、そちらで実装していく。
なお、使用するコントローラーは「Xbox360」のものを想定している。
また、XInputの使い方のみを書くので、自分でInputクラスに機能を追加していくこと。
XInputを使うには、次の2行が必要。
#include "XInput.h"
#pragma comment(lib,"Xinput.lib")
コントローラーの状態を入れる変数を用意する。
XINPUT_STATE controllerState_;
この変数ひとつで、ボタンやスティックの状態を扱うことができる。
複数のコントローラーに対応したい場合は、この変数を配列にする。
今のコントローラーの状態を変数に入れる。
XInputGetState(0, &controllerState_);
第一引数はコントローラーの番号。(PCに繋いだ順に0→1→2・・・)
ボタンが押されているかどうかは、次の記述で取得できる。
if (controllerState_.Gamepad.wButtons & ●●●●●)
{
return TRUE; //押してる
}
return FALSE; //押してない
●●●●●の部分は
・XINPUT_GAMEPAD_A ・・・ Aボタン
・XINPUT_GAMEPAD_DPAD_RIGHT・・・ 十字キーの右
・XINPUT_GAMEPAD_START ・・・ スタートボタン
・XINPUT_GAMEPAD_LEFT_THUMB・・・ 左スティック押し込み
・XINPUT_GAMEPAD_LEFT_SHOULDER・・Lボタン(左ショルダー) など
詳細は、いつも通り「右クリック」⇒「宣言へ移動」で。
名前が長くて使いづらいのであれば、好きな名前でdefineしてやるのもいいだろう。
アナログ情報は次の記述で取得できる。
float value = controllerState_.Gamepad.●●●;
●●●の部分は
・sThumbLX・・・ 左スティックの横方向の傾き具合
・sThumbLY・・・ 左スティックの縦方向の傾き具合
・sThumbRX・・・ 右スティックの横方向の傾き具合
・sThumbRY・・・ 右スティックの縦方向の傾き具合
・bLeftTrigger・・・ 左トリガーの押し込み具合
・bRightTrigger・・・右トリガーの押し込み具合
スティックの傾きは-32768~32767の間の値になる。
そのままだと使いづらいので、32767で割って、約-1~1にしてやると使いやすいかと。
トリガーは0~255の値になる。
なおスティックやトリガーは、まったく触ってない状態でも微妙に傾いてしまい、0ではなく小さな値が返ってきてしまう。
そこで、約±20%の値は無視する(0にしてやる必要がある)
この範囲をデッドゾーンという。
正確なデッドゾーンは
XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE
XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE
XINPUT_GAMEPAD_TRIGGER_THRESHOLD
という名前で定義されているので、これを使うのもよい。
次の記述でコントローラーを振動させることができる。
XINPUT_VIBRATION vibration;
ZeroMemory(&vibration, sizeof(XINPUT_VIBRATION));
vibration.wLeftMotorSpeed = ●●●; // 左モーターの強さ
vibration.wRightMotorSpeed = ●●●;// 右モーターの強さ
XInputSetState(0, &vibration);
一つのコントローラーにはモーターが2つ付いていて、それぞれ違った振動をする。
2つのモーターの強さを調整することで多彩な演出が出来る。
各モーターの強さは0~65535の範囲で指定する。
65535という値が覚えにくいのであれば、0~1で指定指定して65535倍してやるという手もある。
振動を止めたいときは、両モーターの強さを0にすればよい。
なお、XInputSetState関数の第一引数は、振動させたいコントローラーの番号。