做为Ogre学习的一个小总结,最后把打地鼠这个小游戏实现一下。要看懂代码的话必须先把wiki上的初级教程都搞定。代码的实现主要参考了打工仔的那本书,但在其上做了一些修改,使用的是wiki上的框架,环境是Ubuntu11.10.下面是代码:
主游戏类:
TutorialApplication.h
/*
-----------------------------------------------------------------------------
Filename: TutorialApplication.h
-----------------------------------------------------------------------------
//主游戏类
-----------------------------------------------------------------------------
*/
#ifndef __TutorialApplication_h_
#define __TutorialApplication_h_
#include "BaseApplication.h"
#include "ShrewMouseManager.h"
#include "ShrewMouseFrameListener.h"
#include "ShrewMouse.h"
class TutorialApplication : public BaseApplication
{
public:
TutorialApplication(void);
virtual ~TutorialApplication(void);
protected:
virtual void createScene(void);
void createFrameListener();
bool frameStarted(const FrameEvent &evt);
bool keyPressed( const OIS::KeyEvent &arg );
void updateScore(void);
private:
ShrewMouseManager* _miceManager;
bool _exit;
int _score;
OgreBites::Label* mScoreLabel;
};
#endif // #ifndef __TutorialApplication_h_
TutorialApplication.cpp
/*
-----------------------------------------------------------------------------
Filename: TutorialApplication.cpp
-----------------------------------------------------------------------------
//打地鼠的实现文件
-----------------------------------------------------------------------------
*/
#include "TutorialApplication.h"
using namespace Ogre;
//-------------------------------------------------------------------------------------
TutorialApplication::TutorialApplication(void)
{
_exit=false;
_score=0;
}
//-------------------------------------------------------------------------------------
TutorialApplication::~TutorialApplication(void)
{
if(_miceManager)
delete _miceManager;
}
//-------------------------------------------------------------------------------------
void TutorialApplication::createScene(void)
{
mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));
Light* l=mSceneMgr->createLight("MainLight");
l->setPosition(20,80,50);
mCamera->setPosition(94.8f,194.0f,373.9f);
mCamera->setOrientation(Ogre::Quaternion(0.9f,-0.3f,0.0f,0.0f));
_miceManager=new ShrewMouseManager(mSceneMgr);
}
void TutorialApplication::createFrameListener()
{
BaseApplication::createFrameListener();
//初始化记分牌
mScoreLabel = mTrayMgr->createLabel(OgreBites::TL_TOP, "ShrewMouseScore", "", 350);
}
//每一帧渲染前调用
bool TutorialApplication::frameStarted(const FrameEvent &evt)
{
if(_miceManager)
{
_miceManager->update(evt.timeSinceLastFrame);
}
return !_exit;
}
//监听键盘
bool TutorialApplication::keyPressed( const OIS::KeyEvent &arg )
{
int who = -1;
switch(arg.key)
{
case OIS::KC_Q:
who = 0;
break;
case OIS::KC_W:
who = 1;
break;
case OIS::KC_E:
who = 2;
break;
case OIS::KC_A:
who = 3;
break;
case OIS::KC_S:
who = 4;
break;
case OIS::KC_D:
who = 5;
break;
case OIS::KC_Z:
who = 6;
break;
case OIS::KC_X:
who = 7;
break;
case OIS::KC_C:
who = 8;
break;
}
if(who != -1)
{
bool ret = _miceManager->hit(who);
if(ret)
{
_score+=10;
updateScore();
}
}
//退出程序
if (arg.key == OIS::KC_ESCAPE)
{
_exit = true;
}
//游戏截图
else if (arg.key == OIS::KC_SYSRQ) // take a screenshot
{
mWindow->writeContentsToTimestampedFile("screenshot", ".jpg");
}
return false;
}
//修改分数
void TutorialApplication::updateScore(void)
{
mScoreLabel->setCaption(Ogre::String("Score: =") + Ogre::StringConverter::toString(_score));
}
#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
TutorialApplication app;
try {
app.go();
} catch( Ogre::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().c_str() << std::endl;
#endif
}
return 0;
}
#ifdef __cplusplus
}
#endif
//地鼠类
ShrewMouse.h
#ifndef __ShrewMouse_H__
#define __ShrewMouse_H__
#include <Ogre.h>
class ShrewMouse
{
public:
enum State
{
Alive,
Dead,
Sleep
};
public:
ShrewMouse(const std::string & name, Ogre::SceneManager * sm, Ogre::Vector3 lpos);
~ShrewMouse(void);
void update(float interval);
void enable(void);
State getState(void);
bool hit(void);
private:
//bool _isEnable;
Ogre::Entity * _ent;
float _time;
Ogre::AnimationState* _animState;
State _state;
};
#endif
ShrewMouse.cpp
#include "ShrewMouse.h"
ShrewMouse::ShrewMouse(const std::string & name, Ogre::SceneManager * sm, Ogre::Vector3 pos):_time(0.f),_state(Sleep)
{
using namespace Ogre;
_ent = sm->createEntity(name, "ogrehead.mesh");
Ogre::Animation * anim;
Ogre::NodeAnimationTrack * track;
Ogre::SceneNode * sn = sm->getRootSceneNode()->createChildSceneNode(pos);
// Add entity to the root scene node
sn->attachObject(_ent);
//_ent->setVisible(false);
sn->setScale(Ogre::Vector3(0.5f, 0.5f, 0.5f));
anim = sm->createAnimation(name.c_str(), 3.f);
// Spline it for nice curves
anim->setInterpolationMode(Animation::IM_SPLINE);
// Create a track to animate the camera's node
track = anim->createNodeTrack(0, sn);
// Setup keyframes
TransformKeyFrame* key = track->createNodeKeyFrame(0); // startposition
key->setScale(Ogre::Vector3(0.5f, 0.5f, 0.5f));
key->setTranslate(pos);
key = track->createNodeKeyFrame(1.f);
key->setScale(Ogre::Vector3(1.f, 1.f, 1.f));
key->setTranslate(pos);
key = track->createNodeKeyFrame(2.f);
key->setScale(Ogre::Vector3(1.f, 1.f, 1.f));
key->setTranslate(pos);
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);
}
void ShrewMouse::update(float interval)
{
_time -= interval;
_animState->setTimePosition(3.f- _time);
if(_time <=0.f)
{
_ent->getSubEntity(0)->setMaterialName("Ogre/Eyes");
_ent->getSubEntity(1)->setMaterialName("Ogre/Skin");
_ent->getSubEntity(2)->setMaterialName("Ogre/Earring");
_ent->getSubEntity(3)->setMaterialName("Ogre/Tusks");
_state = Sleep;
//_ent->setVisible(false);
}
}
ShrewMouse::~ShrewMouse(void)
{
// _sm->destroyAnimation(_name.c_str());
}
void ShrewMouse::enable(void)
{
if(_state == Sleep)
{
_animState->setEnabled(true);
_animState->setTimePosition(0.f);
_state = Alive;
//_ent->setVisible(true);
_time = 3.f;
}
}
ShrewMouse::State ShrewMouse::getState(void)
{
return _state;
}
bool ShrewMouse::hit(void)
{
std::cout<<"hit me"<<std::endl;
if(_state == Alive)
{
_ent->setMaterialName("Examples/RustySteel");
_state = Dead;
return true;
}
return false;
}
地鼠管理类
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);
bool hit(int num);
protected:
Ogre::SceneManager * _sm;
ShrewMouse* _mice[9];
float _time;
};
#endif
ShrewMouseManager.cpp
#include "ShrewMouseManager.h"
#include "ShrewMouse.h"
bool ShrewMouseManager::hit(int num)
{
return _mice[num]->hit();
}
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+=interval;
while(_time >= 1.0f)
{
_time -= 1.f;
_mice[rand()%9]->enable();
}
for(int i=0; i<9; ++i)
{
if(_mice[i]->getState() != ShrewMouse::Sleep)
{
_mice[i]->update(interval);
}
}
}
CMakeLists.txt
#/*
#-----------------------------------------------------------------------------
#Filename: CMakeLists.txt
#-----------------------------------------------------------------------------
#
#打地鼠的CMakeLists.txt
#-----------------------------------------------------------------------------
#*/
cmake_minimum_required(VERSION 2.6)
project(OgreApp)
set(CMAKE_MODULE_PATH "/usr/local/lib/OGRE/cmake/;${CMAKE_MODULE_PATH}")
set(OGRE_SAMPLES_INCLUDEPATH "/home/tao/workspace/ogre_src_v1-8-0/Samples/Common/include/")
if (CMAKE_BUILD_TYPE STREQUAL "")
# CMake defaults to leaving CMAKE_BUILD_TYPE empty. This screws up
# differentiation between debug and release builds.
set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: None (CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE)
endif ()
set(CMAKE_DEBUG_POSTFIX "_d")
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/dist")
find_package(OGRE REQUIRED)
#if(NOT "${OGRE_VERSION_NAME}" STREQUAL "Cthugha")
# message(SEND_ERROR "You need Ogre 1.7 Cthugha to build this.")
#endif()
find_package(OIS REQUIRED)
if(NOT OIS_FOUND)
message(SEND_ERROR "Failed to find OIS.")
endif()
# Find Boost
if (NOT OGRE_BUILD_PLATFORM_IPHONE)
if (WIN32 OR APPLE)
set(Boost_USE_STATIC_LIBS TRUE)
else ()
# Statically linking boost to a dynamic Ogre build doesn't work on Linux 64bit
set(Boost_USE_STATIC_LIBS ${OGRE_STATIC})
endif ()
if (MINGW)
# this is probably a bug in CMake: the boost find module tries to look for
# boost libraries with name libboost_*, but CMake already prefixes library
# search names with "lib". This is the workaround.
set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES} "")
endif ()
set(Boost_ADDITIONAL_VERSIONS "1.44" "1.44.0" "1.42" "1.42.0" "1.41.0" "1.41" "1.40.0" "1.40" "1.39.0" "1.39" "1.38.0" "1.38" "1.37.0" "1.37" )
# Components that need linking (NB does not include header-only components like bind)
set(OGRE_BOOST_COMPONENTS thread date_time)
find_package(Boost COMPONENTS ${OGRE_BOOST_COMPONENTS} QUIET)
if (NOT Boost_FOUND)
# Try again with the other type of libs
set(Boost_USE_STATIC_LIBS NOT ${Boost_USE_STATIC_LIBS})
find_package(Boost COMPONENTS ${OGRE_BOOST_COMPONENTS} QUIET)
endif()
find_package(Boost QUIET)
# Set up referencing of Boost
include_directories(${Boost_INCLUDE_DIR})
add_definitions(-DBOOST_ALL_NO_LIB)
set(OGRE_LIBRARIES ${OGRE_LIBRARIES} ${Boost_LIBRARIES})
endif()
set(HDRS
./BaseApplication.h
./TutorialApplication.h
./ShrewMouseManager.h
./ShrewMouse.h
./ShrewMouseFrameListener.h
)
set(SRCS
./BaseApplication.cpp
./TutorialApplication.cpp
./ShrewMouseManager.cpp
./ShrewMouse.cpp
./ShrewMouseFrameListener.cpp
)
include_directories( ${OIS_INCLUDE_DIRS}
${OGRE_INCLUDE_DIRS}
${OGRE_SAMPLES_INCLUDEPATH}
)
add_executable(OgreApp WIN32 ${HDRS} ${SRCS})
set_target_properties(OgreApp PROPERTIES DEBUG_POSTFIX _d)
target_link_libraries(OgreApp ${OGRE_LIBRARIES} ${OIS_LIBRARIES})
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/dist/bin)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/dist/media)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/dist/bin)
install(TARGETS OgreApp
RUNTIME DESTINATION bin
CONFIGURATIONS All)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/dist/media
DESTINATION ./
CONFIGURATIONS Release RelWithDebInfo Debug
)
install(FILES ${CMAKE_SOURCE_DIR}/dist/bin/plugins.cfg
${CMAKE_SOURCE_DIR}/dist/bin/resources.cfg
DESTINATION bin
CONFIGURATIONS Release RelWithDebInfo Debug
)
最后的的效果是9个地鼠轮番出现,qweasdzxc对应9个地鼠,打中的话地鼠就会变色,同时获得10分。