ホームへ戻る

 sp.8章 マウスのクリックを検出する

 4.7章「マウスの入力状態を取得する」ではマウスの押下状態や、座標はとれるようになりましたが、今クリックされた瞬間だということが検出できませんでした。
これはsp.2章のように、押しているフレーム数を計算してやり、押し始めて1フレーム目の時にクリックされたと認識すればOKです。
内容は4.7章を参照するとして、


int Mouse = GetMouseInput();
if( Mouse & MOUSE_INPUT_LEFT ){
  //左クリック
}

このようにすることで、マウスのボタンが押されていることを検出しました。
このときMouseに入るint型の値は「bitアサイン」です。
0bit目が0ならボタン0は押されていない。0bit目が1ならボタン0は押されている。
1bit目が0ならボタン1は押されていない。1bit目が1ならボタン1は押されている。
2bit目が0ならボタン2は押されていない。2bit目が1ならボタン2は押されている。
・・・この要領でDXライブラリでは8個までマウスのボタンを識別できます。
一般的に0bit目は左クリック、1bit目は右クリック、2bit目は真ん中のスクロールボタン押下です。
3bit目以降はメーカー依存になるようです。
それぞれのbitアサインを取り出すには1と論理積を取ります。
論理積(&)とは
0と0で0
0と1で0
1と0で0
1と1で1
という計算方法です。つまり計算される方も計算する方も1で初めて結果が1になるのです。よって

mouse & 0x01

の結果はbit0が0か1かを意味します。

mouse & (0x01>>1)

の結果はbit0が0か1かを意味します。

mouse & (0x01>>2)

の結果はbit1が0か1かを意味します。この要領で8bit目まで取り出せばいいのです。

ではマウスの入力状態をsp.2章と同じ構成になるようにシングルトンを使って設計してみましょう。本章はC++の設計手法で紹介します。


/* Singleton.h */


#pragma once

template <typename _T>
class Singleton {

protected:
    Singleton() {}
    virtual ~Singleton() {}
    Singleton(const Singleton& r) {}
    Singleton& operator=(const Singleton& r) {}

public:
    static _T* getInstance() {
        static _T inst;
        return &inst;
    };

};

/* Mouse.h */


#pragma once

#include "Singleton.h"

class Mouse : public Singleton<Mouse> {

    Mouse();
    friend Singleton< Mouse >;

public:
    static constexpr int LEFT_CLICK = 0;
    static constexpr int RIGHT_CLICK = 1;

    bool update();	//更新
    int getPressingCount(int keyCode);//keyCodeのキーが押されているフレーム数を取得
    int getReleasingCount(int keyCode);//keyCodeのキーが離されているフレーム数を取得
    int getX() { return _x; }
    int getY() { return _y; }

private:
    static constexpr int KEY_NUM = 8;	//キー総数
    int _x, _y;
    int _buttonPressingCount[KEY_NUM];//押されカウンタ
    int _buttonReleasingCount[KEY_NUM];//離されカウンタ

    bool isAvailableCode(int keyCode);//keyCodeが有効なキー番号か問う

};

/* Mouse.cpp */


#include <DxLib.h>
#include "Mouse.h"

Mouse::Mouse() : _buttonPressingCount(), _buttonReleasingCount(), _x(), _y() {
}

//更新
bool Mouse::update() {
    int nowButtonState = GetMouseInput();
    GetMousePoint(&_x, &_y);
    for (int i = 0; i<KEY_NUM; i++) {
        if ((nowButtonState>>i) & 1) {            //i番のボタンが押されていたら
            if (_buttonReleasingCount[i] > 0) {//離されカウンタが0より大きければ
                _buttonReleasingCount[i] = 0;   //0に戻す
            }
            _buttonPressingCount[i]++;          //押されカウンタを増やす
        }
        else {                             //i番のキーが離されていたら
            if (_buttonPressingCount[i] > 0) { //押されカウンタが0より大きければ
                _buttonPressingCount[i] = 0;    //0に戻す
            }
            _buttonReleasingCount[i]++;         //離されカウンタを増やす
        }
    }
    return true;
}

//keyCodeのキーが押されているフレーム数を返す
int Mouse::getPressingCount(int keyCode) {
    if (!isAvailableCode(keyCode)) {
        return -1;
    }
    return _buttonPressingCount[keyCode];
}

//keyCodeのキーが離されているフレーム数を返す
int Mouse::getReleasingCount(int keyCode) {
    if (!isAvailableCode(keyCode)) {
        return -1;
    }
    return _buttonReleasingCount[keyCode];
}

//keyCodeが有効な値かチェックする
bool Mouse::isAvailableCode(int keyCode) {
    if (!(0 <= keyCode && keyCode<KEY_NUM)) {
        return false;
    }
    return true;
}

/* main.cpp */


#include "DxLib.h"
#include "Mouse.h"

using namespace std;

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
    
    ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK);
    
    while(!ScreenFlip()&&!ProcessMessage()&&!ClearDrawScreen()) {
        Mouse::getInstance()->update();
        DrawFormatString(0, 0, GetColor(255, 255, 255), "%d,%d",
            Mouse::getInstance()->getX(),
            Mouse::getInstance()->getY()
        );
        DrawFormatString(0, 20, GetColor(255, 255, 255), "%d %d",
            Mouse::getInstance()->getPressingCount(Mouse::LEFT_CLICK),
            Mouse::getInstance()->getPressingCount(Mouse::RIGHT_CLICK)
        );
    }
    DxLib_End();
    return 0;
}

実行結果


MouseクラスのgetPressingCountを取得することで押しているボタンのフレーム数が取得できます。
実行結果ではマウスの座標をリアルタイムに表示し、左クリックが押されているフレーム数と右クリックが押されているフレーム数を表示しています。

従いまして

if(Mouse::getInstance()->getPressingCount(Mouse::LEFT_CLOCK)==1){
  //左クリックされた瞬間
}

このようにすることでクリックされた瞬間を検出することができます。

→分からないことがあれば掲示板で質問して下さい


- Remical Soft -