带缓冲的鼠标、键盘操作,这里的鼠标、按键事件会被各自的监听器捕获。其中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 = ;//移动常量
mContinue = true;//继续渲染
mMouse->setEventCallback(this);//注册鼠标监听
mKeyboard->setEventCallback(this);//注册键盘监听
mDirection = Vector3::ZERO;//初始化为零
}
//其他代码
}

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

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

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

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

  鼠标左键按下:

 bool mousePressed(const OIS::MouseEvent &e,OIS::MouseButtonID id)
{
Light *light = mSceneMgr->getLight("light1");
switch(id)
{
case OIS::MB_Left:
light->setVisible(!light->isVisible());
break;
}
return true;
}

  鼠标右键拖拽:

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

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

  键盘处理:

 bool keyPressed(const OIS::KeyEvent &e)
{
switch (e.key)
{
case OIS::KC_ESCAPE://按下esc时推出
mContinue = false;
break;
case OIS::KC_1://数字键1
mCamera->getParentSceneNode()->detachObject(mCamera);
mCamNode = mSceneMgr->getSceneNode("CamNode1");
mCamNode->attachObject(mCamera);
break;
case OIS::KC_2://数字键2
mCamera->getParentSceneNode()->detachObject(mCamera);
mCamNode = mSceneMgr->getSceneNode("CamNode2");
mCamNode->attachObject(mCamera);
break;
case OIS::KC_UP://前
case OIS::KC_W:
mDirection.z -= mMove;
break;
case OIS::KC_DOWN://后
case OIS::KC_S:
mDirection.z += mMove;
break;
case OIS::KC_LEFT://左
case OIS::KC_A:
mDirection.x -= mMove;
break;
case OIS::KC_RIGHT://右
case OIS::KC_D:
mDirection.x += mMove;
break;
case OIS::KC_PGDOWN://上
case OIS::KC_E:
mDirection.y -= mMove;
break;
case OIS::KC_PGUP://下
case OIS::KC_Q:
mDirection.y += mMove;
break;
}
return true;
}

代码

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

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

ogre3D学习基础10 -- 键盘控制与鼠标控制(缓冲控制)的更多相关文章

  1. ogre3D学习基础10 -- 键盘控制与鼠标控制(直接控制)

    要实现键盘,鼠标对场景的控制,首先要帧监听,就是在每一帧的渲染前后对它进行操作.这里的操作没有用到缓冲区,只是简单的直接获取. 1.这些步骤和前面的一样,直接上代码,操作还是在createScene函 ...

  2. ogre3D学习基础13 -- 键盘控制网格动画mesh

    以上一节为蓝本,这里增加一点难度,添加了四个节点,增加键盘控制移动速度,使用bool变量控制是否移动. 第一,要增加键盘控制,那就使用OIS::KeyListener,在监听器里添加一个父类KeyLi ...

  3. ogre3D学习基础1 -- 核心对象与脚本技术

    一.核心对象介绍1.命名空间 Ogre3d使用了C++的特性--命名空间,可以防止命名混淆.使用方法也简单,using namespace Ogre;或者直接在使用时加上“Ogre::”的前缀,如Og ...

  4. ogre3D学习基础5 -- 阴影与动画

    五.阴影 阴影是渲染一个真实场景的重要组成部分,它可以给场景中的物体提供更加真实的感觉,同时还可以帮助用户更好的了解对象间的空间关系. 启用阴影: 缺省情况下,阴影是关闭的,开启方式如下: 1.建立场 ...

  5. ogre3D学习基础19 --- 材质的继承,纹理的滚动与旋转

    以上一节为基础,废话不多说. 首先新增一个节点,用于比较显示 //新增一个节点 ent = mSceneMgr->createEntity("Quad"); ent-> ...

  6. ogre3D学习基础18 -- 材质的使用与脚本的简单书写

    这一节以基础16为基础,练习材质的使用. 第一,看看框架 //material #include "ExampleApplication.h" class TutorialAppl ...

  7. ogre3D学习基础17 --- 如何手动创建ogre程序

    建立自己的Ogre程序 一直以来都是使用ExampleApplication.h来写程序,现在来看看它到底有什么神奇的地方. 首先,我们新建一个win32空项目 然后配置环境 最后新建define.c ...

  8. ogre3D学习基础3 -- 粒子与表层脚本

    9.粒子脚本 粒子脚本允许你实例化地在你的脚本代码中定义粒子系统,而不必在源代码中进行设置,使得你做任何修改都能得到快速回应.脚本里定义的粒子系统被用作模板,并且多个实际的系统可以在运行时从这里被创建 ...

  9. ogre3D学习基础11 -- 交换两个场景管理器

    这一节,练习一下前几次学习的内容,功能很简单,就是建立两个不同的场景管理器,当按下键盘上某个键时切换镜头. 基本框架不变,这个监听器继承了两个父类,一个是我们的老朋友ExampleFrameListe ...

随机推荐

  1. iOS VIPER架构(二)

    第一篇文章对VIPER进行了简单的介绍,这篇文章将从VIPER的源头开始,比较现有的几种VIPER实现,对VIPER进行进一步的职责剖析,并对各种细节实现问题进行挖掘和探讨.最后给出两个完整的VIPE ...

  2. 【深度精讲】JFinal中的Ret和Kv工具类的区别,你用对了吗?

    在JFinal中有两个类Map的工具类,一个是有状态的Ret,一个是无状态的Kv,各种自己的应用场景,你用对了吗? 下面我们从多个方面来探究一下,JFinal针对这两个类的设计: 一.位置-com.j ...

  3. PHP判断两个矩形是否相交

    <?php $s = is_rect_intersect(1,2,1,2,4,5,0,3); var_dump($s); /* 如果两个矩形相交,那么矩形A B的中心点和矩形的边长是有一定关系的 ...

  4. GIT新手入门学习教程

    廖雪峰的GIT教程 链接地址:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

  5. WPF中,DataGrid最左边多出一行的解决方案

        这种情况下,请在DataGrid的属性里加上这个属性:   RowHeaderWidth="0" 必须赋值为0,不能不赋值,也不能赋其他值. 问题解决.

  6. UVA 11997 K Smallest Sums (多路归并)

    从包含k个整数的k个数组中各选一个求和,在所有的和中选最小的k个值. 思路是多路归并,对于两个长度为k的有序表按一定顺序选两个数字组成和,(B表已经有序)会形成n个有序表 A1+B1<=A1+B ...

  7. _variant_t的使用

    我们先看看COM所支持的一些类型的基本类: (微软提供,在comdef.h中定义) 在COM中使用的标准类Class如下所示: _bstr_t:对BSTR类型进行打包,并提供有用的操作和方法: _co ...

  8. 文件下载(NSURLConnection/NSURLSession)

    最基本的网络文件下载(使用原生的网络请求) #pragma mark - 小文件下载 // 方法一: NSData dataWithContentsOfURL - (void)downloadFile ...

  9. 利用SignalR实现实时聊天

    2018/10/10:博主第一次写原创博文而且还是关于C#的(博主是从前端转过来的),菜鸟一枚,如果有什么写的不对,理解错误,还望各位轻喷.,从SignalR开始! 首先先介绍一下关于SignalR的 ...

  10. jenkins 全局工具配置