マウスの状態を取得する

マウスデバイスの設定

マウスの情報を取得するには、まずマウスデバイスを設定する必要がある。これは、DirectInputの初期化(WinMain.cpp内)のあとに、次のように指定する。

//-------------------------------------------------------------------------------------------------
//      メイン関数(エントリーポイント)プログラムはここから始まる
//-------------------------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode)
{
    ・
    ・
    ・
    // DirectInputオブジェクトの初期化
    if (FAILED(InitDInput(hThisInst))) return (FALSE);

    // Keyboard Object の初期化
    if (FAILED(InitKeyboard())) return (FALSE);

    // Joypad Object の初期化
    if (FAILED(InitJoypad())) OutputDebugString("Joypad Not Found\n");

    // Mouse Object の初期化
    if ( FAILED(InitMouse()) ) return (FALSE);
    ・
    ・
    ・
}

前準備

マウスの状態を取得するのは簡単だが、その情報をどう使うかが問題である。なぜならマウスポインタの位置は座標では取得できないからである。また、ゲームの場面によっては、画面いっぱいにマウスカーソルを動かしたり、動く位置を限定したりする必要もあるだろう。マウスカーソルの移動速度も場合によっては変えたいかもしれない。また、マウスカーソルの画像も用意する必要がある。
そういったことを考慮し、マウスの絶対座標や移動速度などを格納する構造体を場面ごとに作成し、DirectInputから取得したマウスの情報を元に、構造体の情報を書き換えるという方法をとることにした。

1.構造体の宣言

場面ごとのマウス情報を格納するための構造体の型は、NKC_DInput.hに作成してある。

/* マウスポインタの情報 */
typedef struct _MSTATE {
    RECT    moveRect;     // 画面上で動ける範囲
    int     x;            // X座標
    int     y;            // Y座標
    bool    lButton;      // 左ボタン
    bool    rButton;      // 右ボタン
    bool    cButton;      // 真ん中ボタン
    int     moveAdd;      // 移動量
    RECT    imgRect;      // マウス用画像矩形
    int     imgWidth;     // マウス画像幅
    int     imgHeight;    // マウス画像高さ
} MSTATE;

この構造体を使った構造体変数を場面ごとに用意し、使用する。

2.マウス情報を格納する構造体変数の宣言

次に、マウスの情報を格納する変数を作成する。たとえばスタート画面でメニューを選ぶ際にマウスを使用したい場合、Start.cpp内のグローバル変数宣言でマウス情報を格納する構造体変数を宣言する。

static MSTATE MState;	// マウス情報

3.マウス情報構造体変数の初期化

次に、初期化処理(StartInit関数内)で、マウスポインタ情報の初期化を行う。

//------------------------------------------------------- マウスポインタ情報の初期化
SetRect(&MState.moveRect, 10, 10, 630, 470);	// マウスカーソルの動く範囲
MState.x = MState.moveRect.left;	// マウスカーソルのX座標を初期化
MState.y = MState.moveRect.top;	// マウスカーソルのY座標を初期化
MState.lButton = false;	// 左ボタンの情報を初期化
MState.rButton = false;	// 右ボタンの情報を初期化
MState.cButton = false;	// 中央ボタンの情報を初期化
MState.moveAdd = 2;	// マウスカーソルの移動量を設定
SetRect(&MState.imgRect, 400, 0, 420, 20);	// マウスカーソル画像の矩形を設定
MState.imgWidth = MState.imgRect.right - MState.imgRect.left;	// 画像の幅を計算
MState.imgHeight = MState.imgRect.bottom - MState.imgRect.top;	// 画像の高さを計算

マウス情報の取得

マウスの情報(カーソルがどのように動いたか、ボタンは押されているか押されていないか)を格納する変数はmyInput.cppですでに用意してある。取得したいところでGetMouseState()という関数を実行すると、状態を取得し、変数に情報を格納する。

//-----------------------------------------------------------------------------
// 関数名 : UpdateFrame()
// 機能概要: ゲームメイン処理
//-----------------------------------------------------------------------------
void UpdateFrame(void)
{
    /* 現在の時間を取得 */
    gl_nowTime = timeGetTime();

    /* キーボードの状態を取得 */
    GetKeyboardState();

    // ジョイパッドの状態を取得
    GetJoypadState();

    // マウスの状態を取得
    GetMouseState();
    ・
    ・
    ・
}

取得した情報を元に、マウス情報を更新する。更新するプログラムは次のとおり。

// 取得した情報を元にマウスの情報を更新
MState.x += (g_diMouseState.lX * MState.moveAdd);
MState.y += (g_diMouseState.lY * MState.moveAdd);
if ( MState.x < MState.moveRect.left ) MState.x = MState.moveRect.left;
if ( MState.x > MState.moveRect.right - MState.imgWidth ) MState.x = MState.moveRect.right - MState.imgWidth;
if ( MState.y < MState.moveRect.top ) MState.y = MState.moveRect.top;
if ( MState.y > MState.moveRect.bottom - MState.imgHeight ) MState.y = MState.moveRect.bottom - MState.imgHeight;
(g_diMouseState.rgbButtons[0] & 0x80) ? MState.lButton = true : MState.lButton = false;
(g_diMouseState.rgbButtons[1] & 0x80) ? MState.rButton = true : MState.rButton = false;
(g_diMouseState.rgbButtons[2] & 0x80) ? MState.cButton = true : MState.cButton = false;

これにより、MStateという構造体変数に、カーソルの位置や、ボタンの状態が格納される。

マウス情報より、マウスの状態を調べる

MState構造体変数に、カーソルの位置や、ボタンの状態が格納されている。カーソルの位置(X,Y座標)は、MState.xとMState.yである。また、ボタンが押されているかどうかは、MState.lButton、MState.rButton、MState.cButtonがそれぞれtrueかfalseかを調べればよい。

マウス座標を元に、自作のマウスカーソル画像を表示する

マウスの座標が分かれば、その位置に画像を描画すればよい。ウィンドウズ標準のマウスカーソルを表示させないようにしておけば、自分で用意した画像をマウスカーソルとして描画できる。


BACK(ジョイパッドの状態を取得する) BACK(複数のジョイパッドを制御するには?)