致謝
感謝網友提出這個問題。大家有問題也可以在評論區(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();
}