[OGRE]看备注学编程(04):打地鼠03-实现地鼠动态效果

头文件ShrewMouse.h:

#ifndef __ShrewMouse_H__
#define __ShrewMouse_H__
#include <Ogre.h>

class ShrewMouse
{

public:
	//构造函数,参数为 地鼠实例的名称,场景管理器,地鼠在三维空间的位置。
	ShrewMouse(const std::string & name, Ogre::SceneManager * sm, Ogre::Vector3 & pos);
	~ShrewMouse(void);
	//更新函数,用于让地鼠做相应的动作。参数为两次调用的时间间隔。
	void update(float interval);
	//启动,换句话说让地鼠从洞里面钻出来
	void enable(void);
	//检查是否在第洞外面
	bool isEnable(void);

private:
	//地鼠是否在洞外面
	bool _isEnable;
	//地鼠的实体
	Ogre::Entity * _ent;
	//一个时间值,当这个时间为零的时候地鼠回洞里面。
	float _time;
	//添加一个地鼠的动画。AnimationState是动画状态的句柄
	Ogre::AnimationState* _animState;

};

#endif


头文件ShrewMouseApplication.h:

#ifndef __ShrewMouseApplication_H__
#define __ShrewMouseApplication_H__

#include "ExampleApplication.h"
class ShrewMouseManager;
class ShrewMouseApplication : public ExampleApplication
{

public:
	ShrewMouseApplication(void);
	~ShrewMouseApplication(void);

protected:
	//用于系统回调来创建场景
	void createScene(void);
	//用于提供框架所需要的FrameListener类型。
	virtual void createFrameListener(void);

private:
	//这里提供一个管理器,用于协调所有的地鼠。
	ShrewMouseManager * _miceManager;

};

#endif



头文件ShrewMouseFrameListener.h:

#ifndef __ShrewMouseFrameListener_H__
#define __ShrewMouseFrameListener_H__

#include "ExampleFrameListener.h"
#include "ShrewMouseManager.h"
#include <sstream>

class ShrewMouseFrameListener: public ExampleFrameListener
{
public:
	// 构造方法有个RenderWindow因为它用这个来决定输入的内容
	ShrewMouseFrameListener(ShrewMouseManager * miceManager, RenderWindow* win, Camera* cam, bool bufferedKeys = false, bool bufferedMouse = false,
		bool bufferedJoy = false );

	virtual bool processUnbufferedKeyInput(const FrameEvent& evt)
	{
		//按下ESC退出
		if( mKeyboard->isKeyDown(OIS::KC_ESCAPE))
			return false;

		// 否则继续运行
		return true;
	}

	virtual bool processUnbufferedMouseInput(const FrameEvent& evt)
	{
		return true;
	}

	//每一帧结束时刷新
	bool frameEnded(const FrameEvent& evt)
	{
		//父类的方法
		ExampleFrameListener::frameEnded(evt);
		//判断是否初始化了miceManager
		if(_miceManager)
			//执行miceManager的update方法,传参是两帧之间的间隔
			_miceManager->update(evt.timeSinceLastFrame);
		return true;
	}

private:
	ShrewMouseManager * _miceManager;
};
#endif


头文件ShrewMouseManager.h:

#ifndef __ShrewMouseManager_H__
#define __ShrewMouseManager_H__
#include <Ogre.h>

class ShrewMouse;
class ShrewMouseManager
{
public:
	ShrewMouseManager(Ogre::SceneManager *sm) ;
	~ShrewMouseManager(void);
	void update(float interval);
protected:
	Ogre::SceneManager * _sm;
	ShrewMouse* _mice[9];
	float _time;
};

#endif



源文件main.cpp:

#include "ShrewMouseApplication.h"

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
	INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
	int main(int argc, char **argv)
#endif
	{
		// Create application object
		ShrewMouseApplication app;

		try {
			app.go();
		} catch( Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
			MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
			std::cerr << "An exception has occured: " << e.getFullDescription();
#endif
		}


		return 0;
	}

#ifdef __cplusplus
}
#endif


源文件ShrewMouse.cpp:

#include "ShrewMouse.h"

//在构造函数中创建场景节点和模型
ShrewMouse::ShrewMouse(const std::string & name, Ogre::SceneManager * sm, Ogre::Vector3 & pos):_isEnable(false),_time(0.f)
{
	using namespace Ogre;
	//通过名称和模型作为参数,创建一个地鼠实体
	_ent = sm->createEntity(name, "ogrehead.mesh");

	//声明动画
	Ogre::Animation  * anim;
	Ogre::NodeAnimationTrack * track;

	//从场景的跟节点上创建一个子节点
	Ogre::SceneNode * sn = sm->getRootSceneNode()->createChildSceneNode(pos);
	//把地鼠实体挂接到这个节点上面
	sn->attachObject(_ent);
	//暂时让这个地鼠实体隐藏(在地洞里面)
	//_ent->setVisible(false);
	sn->setScale(Ogre::Vector3(0.5f, 0.5f, 0.5f));
	//Animation是一个完整的动画组,其中可以包含一系列动画来完成一组动作
	// 通过场景管理器创建,第1个参数代表动画名称,第2个参数代表总播放时间
	anim = sm->createAnimation(name.c_str(), 3.f);
	// 设置动画差值类型为样条插值
	anim->setInterpolationMode(Animation::IM_SPLINE);
	// 创建一个轨迹动画,第1个参数是id索引,第2个是代表其作用的场景节点
	track = anim->createNodeTrack(0, sn);
	// 设置动画关键帧
	TransformKeyFrame* key;
	//在第0秒,物体缩放为整个物体的1/2,为固定位置
	key = track->createNodeKeyFrame(0);
	key->setScale(Ogre::Vector3(0.5f, 0.5f, 0.5f));
	key->setTranslate(pos);
	//在1秒钟时,物体变为为原始大小
	key = track->createNodeKeyFrame(1.f);
	key->setScale(Ogre::Vector3(1.f, 1.f, 1.f));
	key->setTranslate(pos);
	//在2秒钟时,物体仍然为原始大小
	key = track->createNodeKeyFrame(2.f);
	key->setScale(Ogre::Vector3(1.f, 1.f, 1.f));
	key->setTranslate(pos);
	// 在第3秒动画结束时,物体缩小为1/2
	key = track->createNodeKeyFrame(3.f);
	key->setScale(Ogre::Vector3(0.5f, 0.5f, 0.5f));
	key->setTranslate(pos);
	// 最后我们通过上面定义的动画来创建动画状态实例	
	_animState = sm->createAnimationState(name.c_str());
	// 初期动画关闭
	_animState->setEnabled(false);
	// 设置为循环播放
	_animState->setLoop(true);
}

//更新函数,我们在这里倒计时,当倒计时为0的时候让实体隐藏
void ShrewMouse::update(float interval)
{
	//每次调用的时候
	_time-=interval;
	//每次刷新更新动画
	_animState->setTimePosition(3.f- _time);
	//当倒计时小于等于0的时候
	if(_time <=0.f)
	{
		//不再活跃
		_isEnable = false;
		//隐藏地鼠的头
		//_ent->setVisible(false);
	}
}

//析构函数
ShrewMouse::~ShrewMouse(void)
{

}

//让“地鼠”显示出来,并把地鼠在地面的倒计时设置为1秒
void ShrewMouse::enable(void)
{
	if(!isEnable())
	{
		_isEnable = true;
		//设置动画为开启
		_animState->setEnabled(true);
		//把动画时间设置为起点
		_animState->setTimePosition(0.f);
		//一共需要播放3秒钟
		_time = 3.f;

	}
}

bool ShrewMouse::isEnable(void)
{
	return _isEnable;
} 


源文件ShrewMouseApplication.cpp:

#include "ShrewMouseApplication.h"
#include "ShrewMouseFrameListener.h"
#include "ShrewMouseManager.h"
using namespace Ogre;

ShrewMouseApplication::ShrewMouseApplication(void):_miceManager(NULL)
{

}
ShrewMouseApplication::~ShrewMouseApplication(void)
{
	//最后释放地鼠管理器
	if(_miceManager)
		delete _miceManager;
}


void ShrewMouseApplication::createScene(void)
{
	//设置场景环境光
	mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
	//创建一个灯光
	Light* l = mSceneMgr->createLight("MainLight");
	//设置灯光位置
	l->setPosition(20,80,50);
	//设置摄像机位置
	mCamera->setPosition(100.0f, 200.0f, 400.0f);
	//设置摄像机角度
	mCamera->setOrientation(Ogre::Quaternion(Degree(-35),Vector3::UNIT_X));
	//创建一个地鼠管理器,并把Ogre3D引擎中场景管理器作为参数提供。
	_miceManager = new ShrewMouseManager(mSceneMgr);
}


void ShrewMouseApplication::createFrameListener(void)
{
	//把我们自己的FrameListener派生类型提供给Ogre3D图形引擎
	mFrameListener= new ShrewMouseFrameListener(_miceManager, mWindow, mCamera);
	mRoot->addFrameListener(mFrameListener);
}


源文件ShrewMouseFrameListener.cpp:

#include "ShrewMouseFrameListener.h"
#include "ShrewMouseManager.h"

ShrewMouseFrameListener::ShrewMouseFrameListener(ShrewMouseManager * miceManager, RenderWindow* win, Camera* cam, bool bufferedKeys, bool bufferedMouse,
	bool bufferedJoy):ExampleFrameListener(win, cam, bufferedKeys, bufferedMouse, bufferedJoy),_miceManager(miceManager)
{


}


源文件ShrewMouseManager.cpp:

#include "ShrewMouseManager.h"
#include "ShrewMouse.h"

ShrewMouseManager::ShrewMouseManager(Ogre::SceneManager * sm):_sm(sm), _time(0.f)
{
	using namespace Ogre;
	for(int i=0; i<3; ++i)
	{
		for(int j =0; j<3; ++j)
		{
			int n = i+j*3;
			//新建老鼠实例
			_mice[n] = new ShrewMouse("head"+Ogre::StringConverter::toString(i+j*3), _sm, Ogre::Vector3(100 *i, 0, 100 *j));
		}
	}

}

//析构函数
ShrewMouseManager::~ShrewMouseManager(void)
{ 
	for(int i=0; i<9; ++i)
	{
		if(_mice[i])
		{
			delete _mice[i];
			_mice[i] = NULL;
		}
	}
}

//每间隔一秒钟,一个地鼠随机从洞里钻出,参数是两帧之间的间隔,一直刷新
void ShrewMouseManager::update(float interval)
{
	//累计时间值,_time的值为剩余的累计时间
	_time+=interval;
	//检验累计时间有多少个1秒
	while(_time >= 1.f)
	{
		//从累计时间中减去1秒
		_time -= 1.f;
		//每秒随机启动一个地鼠类型
		_mice[rand()%9]->enable();
	}

	//在这里更新九个地鼠的动作
	for(int i=0; i<9; ++i)
	{
		//如果老鼠现在是活的
		if(_mice[i]->isEnable())
		{
			//那么给它传参,等它累积到了1秒自动消失
			_mice[i]->update(interval);
		}
	}
}

运行截图:

[OGRE]看备注学编程(04):打地鼠03-实现地鼠动态效果_第1张图片


你可能感兴趣的:(OGRE)