9.user input and frame listener

这一次整整把一章看完了,那就一下子来一章的内容吧。

用户输入主要包括键盘和鼠标输入,要处理这两类信息,必须使用OIS和frame listener。这需要创建一个新类继承Ogre中基本的framelistener,然后在构造函数中创建OIS系统和需要监控的设备,对信息的处理可以在framestarted中进行,也可以在frameended或者framerenderingqueue中进行,对输入的处理貌似一般在started中进行。

这次还用到了一个定时器timer,用来确定两次按键间隔大于0.25s,好用易懂,reset就好了。

要注意OIS系统的初始化、使用和析构。

#include "Ogre\ExampleApplication.h"

class Example25FrameListener:public Ogre::FrameListener
{
public:
	Example25FrameListener(RenderWindow* win, Ogre::Camera* cam)
	{
		this ->_movementspeed = 3;

		size_t windowHnd = 0;                                   //从这里开始OIS系统的初始化,主要提供窗口句柄windowHnd
		std::stringstream windowHndStr;
		win ->getCustomAttribute("WINDOW", &windowHnd);
		windowHndStr << windowHnd;
		OIS::ParamList pl;
		pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));

		_man = OIS::InputManager::createInputSystem(pl);       //创建系统和设备
		_key = static_cast<OIS::Keyboard*>(_man ->createInputObject(OIS::OISKeyboard, false));
		_mouse = static_cast<OIS::Mouse*>(_man ->createInputObject(OIS::OISMouse, false));

		_Cam = cam;

		_PolyMode = Ogre::PolygonMode::PM_SOLID;

		_timer.reset();
	}

	~Example25FrameListener()
	{
		_man ->destroyInputObject(_key);
		_man ->destroyInputObject(_mouse);
		OIS::InputManager::destroyInputSystem(_man);
	}

	bool frameStarted(const Ogre::FrameEvent& evt)
	{
		Ogre::Vector3 translate(0, 0, 0);
		_key ->capture();
		_mouse ->capture();

		if(_key ->isKeyDown(OIS::KC_R) && _timer.getMilliseconds() > 250)//多边形模式的变化,这里用到了timer
		{
			if(_PolyMode == Ogre::PolygonMode::PM_SOLID)
			{
				_PolyMode = Ogre::PolygonMode::PM_WIREFRAME;
			}
			else if(_PolyMode == Ogre::PolygonMode::PM_WIREFRAME)
			{
				_PolyMode = Ogre::PolygonMode::PM_POINTS;
			}
			else if(_PolyMode == Ogre::PolygonMode::PM_POINTS)
			{
				_PolyMode = Ogre::PolygonMode::PM_SOLID;
			}
			_Cam ->setPolygonMode(_PolyMode);
			_timer.reset();
		}

		if(_key ->isKeyDown(OIS::KC_W))                //镜头的位移
		{
			translate += Ogre::Vector3(0, 0, -10);
		}
		if(_key ->isKeyDown(OIS::KC_S))
		{
			translate += Ogre::Vector3(0, 0, 10);
		}
		if(_key ->isKeyDown(OIS::KC_A))
		{
			translate += Ogre::Vector3(-10, 0, 0);
		}
		if(_key ->isKeyDown(OIS::KC_D))
		{
			translate += Ogre::Vector3(10, 0, 0);
		}
		
		float rotX = _mouse ->getMouseState().X.rel * evt.timeSinceLastFrame * (-0.5);  //镜头的旋转
		float rotY = _mouse ->getMouseState().Y.rel * evt.timeSinceLastFrame * (-0.5);

		_Cam ->yaw(Ogre::Radian(rotX));
		_Cam ->pitch(Ogre::Radian(rotY));
		_Cam ->moveRelative(translate * evt.timeSinceLastFrame * _movementspeed);

		if(_key ->isKeyDown(OIS::KC_ESCAPE))
		{
			return false;
		}

		return true;
	}

private:
	OIS::InputManager* _man;
	OIS::Keyboard* _key;
	Ogre::Camera* _Cam;
	OIS::Mouse* _mouse;
	size_t _movementspeed;
	Ogre::PolygonMode _PolyMode;
	Ogre::Timer _timer;
};

class Example25:public ExampleApplication
{
public:
	Ogre::FrameListener* FrameListener;

	Example25()
	{
		FrameListener = NULL;
	}

	~Example25()
	{
		if(FrameListener)
		{
			delete FrameListener;
		}
	}

	void createFrameListener()
	{
		FrameListener = new Example25FrameListener(mWindow, mCamera);
		mRoot ->addFrameListener(FrameListener);
	}

	void createScene()
	{
		Ogre::Plane plane(Vector3::UNIT_Y, -10);
		Ogre::MeshManager::getSingleton().createPlane("plane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
			plane, 1500, 1500, 200, 200, true, 1, 5, 5, Vector3::UNIT_Z);
		Ogre::Entity* ent = mSceneMgr ->createEntity("LightPlaneEntity", "plane");
		mSceneMgr ->getRootSceneNode() ->createChildSceneNode() ->attachObject(ent);
		ent ->setMaterialName("Examples/BeachStones");

		Ogre::Light* light = mSceneMgr ->createLight("Light1");
		light ->setType(Ogre::Light::LT_DIRECTIONAL);
		light ->setDirection(Ogre::Vector3(1, -1, 0));

		Ogre::SceneNode* node = mSceneMgr ->createSceneNode("Node1");
		mSceneMgr ->getRootSceneNode() ->addChild(node);

		Ogre::Entity* Sinbad = mSceneMgr ->createEntity("Sinbad", "Sinbad.mesh");
		_SinbadNode = node ->createChildSceneNode("SinbadNode");
		_SinbadNode ->setScale(3.0f, 3.0f, 3.0f);
		_SinbadNode ->setPosition(Ogre::Vector3(0.0f, 4.0f, 0.0f));
		_SinbadNode ->attachObject(Sinbad);

		mSceneMgr ->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
	}
	
	void createCamera()
	{
		mCamera = mSceneMgr ->createCamera("MyCamera1");
		mCamera ->setPosition(0, 100, 200);
		mCamera ->lookAt(0, 0, 0);
		mCamera ->setNearClipDistance(5);
	}
	
private:
	Ogre::SceneNode* _SinbadNode;
};

int main(void)
{
	Example25 app;
	app.go();
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值