ogre3D学习基础10 -- 键盘控制与鼠标控制(缓冲控制)

带缓冲的鼠标、键盘操作,这里的鼠标、按键事件会被各自的监听器捕获。其中OIS中定义的两个类MouseListener,KeyListener负责对事件的处理。我们需要使用这两个类的接口。 

   当一个键被按下时,会触发一个 KeyListener::keyPressed 事件,而当这个键被释放(不再按下)时,KeyListener::keyReleased 事件被触发给所有已注册的KeyListener 类。

   鼠标键被按下/释放的函数: MouseListener::mousePressed 和MouseListener::mouseReleased. 它还包含一个 mouseMoved 函数,当鼠标移动时调用它。

  第一,和上一节不一样的就是,TutorialFrameListener的父类又增加了两个,如下

class TutorialFrameListener:public ExampleFrameListener,public OIS::MouseListener ,public OIS::KeyListener
{
public:
    TutorialFrameListener(RenderWindow *win,Camera *cam,SceneManager *sceneMgr)
        :ExampleFrameListener(win,cam,true,true)//第三个参数指明是否使用带缓冲的键盘输入,第四个参数指明是否使用带缓冲的鼠标输入
    {
        mCamNode = cam->getParentSceneNode();
        mSceneMgr = sceneMgr;
        mRotate = 0.13;//滚动常量
        mMove = 250;//移动常量
        mContinue = true;//继续渲染
        mMouse->setEventCallback(this);//注册鼠标监听
mKeyboard
->setEventCallback(this);//注册键盘监听
mDirection
= Vector3::ZERO;//初始化为零
}
//其他代码 }

   而且我们增加了两个成员变量,用于获取指代鼠标和键盘。

  第二,同样需要在每一帧渲染前捕获鼠标和键盘

 1 bool frameStarted(const FrameEvent& evt)
 2     {
 3         if (mMouse)
 4         {
 5             mMouse->capture();
 6         }
 7         if (mKeyboard)
 8         {
 9             mKeyboard->capture();
10         }
11     //实现更光滑的移动
12         mCamNode->translate(mDirection*evt.timeSinceLastFrame,Node::TS_LOCAL);//根据从上一帧到现在的时间,对平移大小进行缩放
13         return mContinue;
14     }

  第三,处理鼠标监听事件,首先实现鼠标左键开关灯,右键旋转摄像机

  鼠标左键按下:

 1 bool mousePressed(const OIS::MouseEvent &e,OIS::MouseButtonID id)
 2     {
 3         Light *light = mSceneMgr->getLight("light1");
 4         switch(id)
 5         {
 6         case OIS::MB_Left:
 7             light->setVisible(!light->isVisible());
 8                 break;
 9         }        
10         return true;
11     }

  鼠标右键拖拽:

 1 bool mouseMoved(const OIS::MouseEvent &e)
 2     {
 3         if (e.state.buttonDown(OIS::MB_Right))
 4         {
 5             //拖动实体
 6             mCamNode->yaw(Degree(-mRotate * e.state.X.rel),Node::TS_WORLD);//
 7             mCamNode->pitch(Degree(-mRotate * e.state.Y.rel),Node::TS_LOCAL);//
 8         }
 9         return true;
10     }

  看过上一章,这里就不解释了。

  键盘处理:

 1 bool keyPressed(const OIS::KeyEvent &e)
 2     {
 3         switch (e.key)
 4         {
 5         case OIS::KC_ESCAPE://按下esc时推出
 6             mContinue = false;
 7             break;
 8         case OIS::KC_1://数字键1
 9             mCamera->getParentSceneNode()->detachObject(mCamera);
10             mCamNode = mSceneMgr->getSceneNode("CamNode1");
11             mCamNode->attachObject(mCamera);
12             break;
13         case OIS::KC_2://数字键2
14             mCamera->getParentSceneNode()->detachObject(mCamera);
15             mCamNode = mSceneMgr->getSceneNode("CamNode2");
16             mCamNode->attachObject(mCamera);
17             break;
18         case OIS::KC_UP://
19         case OIS::KC_W:
20             mDirection.z -= mMove;
21             break;
22         case OIS::KC_DOWN://
23         case OIS::KC_S:
24             mDirection.z += mMove;
25             break;
26         case OIS::KC_LEFT://
27         case OIS::KC_A:
28             mDirection.x -= mMove;
29             break;
30         case OIS::KC_RIGHT://
31         case OIS::KC_D:
32             mDirection.x += mMove;
33             break;
34         case OIS::KC_PGDOWN://
35         case OIS::KC_E:
36             mDirection.y -= mMove;
37             break;
38         case OIS::KC_PGUP://
39         case OIS::KC_Q:
40             mDirection.y += mMove;
41             break;
42         }
43         return true;
44     }
代码

  这样写起来看着很明了,比上一章的if()好多了。同样可以在bool keyReleased(const OIS::KeyEvent &e);里做相应处理。

  其他的没有改动。代码参考上一章的。

 

 

posted @ 2013-09-05 16:50  struggle_time  阅读(1540)  评论(0编辑  收藏  举报