第14節(jié) 實例-事件響應之組合鍵

致謝

感謝網友提出這個問題。大家有問題也可以在評論區(qū)提出,有問必有答。

問題描述

經常的我們需要響應一些組合鍵,最常見的是左Shift+某鍵,以及鼠標左/右鍵按下去+鍵盤某鍵。OSG做這些操作非常簡便。

本節(jié)代碼在網盤中:

注意:務必使用瀏覽器打開:
鏈接:https://pan.baidu.com/s/13gwJLwo_LbRnN3Bl2NXXXw
提取碼:xrf5

功能描述

1.當我們按下左shift+a的時候,會出打?。喊聪铝俗骃HIFT+A
2.當我們按下鼠標左鍵+a的時候,會出打?。喊聪铝耸髽俗箧I+A
有了這兩功能,其它依資類推。
注意:
1.正常的表況下,也受通用鍵盤的功能限制,鍵盤上一般只會檢測同時兩個鍵按下。需要檢測三個鍵按下的情況較少。檢測三鍵如果有需求可以使用::GetAsyncKeyState全局函數進行嘗試。
2.其它正常字母的組合鍵,比如as同時按下,正常判斷即可。

image.png

關鍵實現

OSG的事件處理中有個掩碼getModKeyMask,可以用來判斷當前某個鍵是否按下,如下就是本節(jié)實現的關鍵代碼:

        if (ea.getEventType() == ea.KEYDOWN)
        {
            if ((ea.getKey() == 'A') || (ea.getKey() == 'a'))
            {
                if (ea.getModKeyMask() == ea.MODKEY_LEFT_SHIFT)
                {
                    std::cout << "按下了左SHIFT+A" << std::endl;
                }

                if (ea.getButtonMask() == ea.LEFT_MOUSE_BUTTON)
                {
                    std::cout << "按下了鼠標左鍵+A" << std::endl;
                }     

                _aDown = true;
            }

            if ((ea.getKey() == 's') || (ea.getKey() == 'S'))
            {
                if(_aDown)
                std::cout << "as一起按下" << std::endl;
            }
        }

OSG中當前支持的鍵盤掩碼如下:

        enum ModKeyMask
        {
            MODKEY_LEFT_SHIFT  = 0x0001,
            MODKEY_RIGHT_SHIFT = 0x0002,
            MODKEY_LEFT_CTRL   = 0x0004,
            MODKEY_RIGHT_CTRL  = 0x0008,
            MODKEY_LEFT_ALT    = 0x0010,
            MODKEY_RIGHT_ALT   = 0x0020,
            MODKEY_LEFT_META   = 0x0040,
            MODKEY_RIGHT_META  = 0x0080,
            MODKEY_LEFT_SUPER  = 0x0100,
            MODKEY_RIGHT_SUPER = 0x0200,
            MODKEY_LEFT_HYPER  = 0x0400,
            MODKEY_RIGHT_HYPER = 0x0800,
            MODKEY_NUM_LOCK    = 0x1000,
            MODKEY_CAPS_LOCK   = 0x2000,
            MODKEY_CTRL        = (MODKEY_LEFT_CTRL|MODKEY_RIGHT_CTRL),
            MODKEY_SHIFT       = (MODKEY_LEFT_SHIFT|MODKEY_RIGHT_SHIFT),
            MODKEY_ALT         = (MODKEY_LEFT_ALT|MODKEY_RIGHT_ALT),
            MODKEY_META        = (MODKEY_LEFT_META|MODKEY_RIGHT_META),
            MODKEY_SUPER       = (MODKEY_LEFT_SUPER|MODKEY_RIGHT_SUPER),
            MODKEY_HYPER       = (MODKEY_LEFT_HYPER|MODKEY_RIGHT_HYPER)
        };

支持的鼠標掩碼如下:

        enum MouseButtonMask {
            LEFT_MOUSE_BUTTON    = 1<<0,
            MIDDLE_MOUSE_BUTTON  = 1<<1,
            RIGHT_MOUSE_BUTTON   = 1<<2
        };

以下是全部代碼實現

//#include <windows.h>
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgGA/EventHandler>



osg::Node* _base = nullptr;
osg::Group* _root = new osg::Group;

class MyEventHandler : public osgGA::GUIEventHandler
{
public:
    MyEventHandler()
    {}

    virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
    {
        if (ea.getEventType() == ea.KEYDOWN)
        {
            if ((ea.getKey() == 'A') || (ea.getKey() == 'a'))
            {
                if (ea.getModKeyMask() == ea.MODKEY_LEFT_SHIFT)
                {
                    std::cout << "按下了左SHIFT+A" << std::endl;
                }

                if (ea.getButtonMask() == ea.LEFT_MOUSE_BUTTON)
                {
                    std::cout << "按下了鼠標左鍵+A" << std::endl;
                }     

                _aDown = true;
            }

            if ((ea.getKey() == 's') || (ea.getKey() == 'S'))
            {
                if(_aDown)
                std::cout << "as一起按下" << std::endl;
            }
        }

        if (ea.getEventType() == ea.KEYUP)
        {
            if ((ea.getKey() == 'A') || (ea.getKey() == 'a'))
            {
                _aDown = false;
            }
        }

        ////判斷三鍵ASD
        //if ((::GetAsyncKeyState(0x41) & 0x8000) && (::GetAsyncKeyState(0x53) & 0x8000) && (::GetAsyncKeyState(0x44) & 0x8000))
        //{
        //    std::cout << "同時按下了asd" << std::endl;
        //}

        return false;
    }

    bool _aDown;
};


int main()
{
    osgViewer::Viewer viewer;
    viewer.setSceneData(osgDB::readNodeFile("glider.osg"));
    viewer.addEventHandler(new MyEventHandler());
    return viewer.run();
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容