• 用OGRE1.74搭建游戏框架(三)加入人物控制和场景


    有了前面的状态机,我们就可以很方便的扩展出自己的游戏场景状态的类。

    现在我们要写一个RunState的类,这个就是游戏的主场景所在的地方,从MenuState可以跳转过来。

    一、加入第三人称控制器

    对于人物的控制,新版的OGRE已经给出了一个示例,就是那个Sample_Charater。

    里边是对一个OGRE新模型的控制,操作起来感觉不错,就是向前跑动的时候没法看身后的东西,得停下来,Camera才会回到自由模式。

    这个地方主要用到两个类:

    SdkCameraMan:封装了OGRE的像机,可以比较自由的控制像机。

    SinbadCharacterController:对于Sinbad的角色的控制以及动画的播放。

    只要声明并定义好这两个类就能快速的实现第三人称的控制。

    CRunState.h

    class CRunState : public CGameState
    {
    public:
    CRunState();

    DECLARE_GAMESTATE_CLASS(CRunState)

    void Enter();
    void CreateScene();
    void Exit();
    bool Pause();
    void Resume();

    bool keyPressed(const OIS::KeyEvent &evt);
    bool keyReleased(const OIS::KeyEvent &evt);

    bool mouseMoved( const OIS::MouseEvent &evt);
    bool mousePressed( const OIS::MouseEvent &evt, OIS::MouseButtonID id );
    bool mouseReleased( const OIS::MouseEvent &evt, OIS::MouseButtonID id );


    void Update(double timeSinceLastFrame);


    protected:
    OgreBites::SdkCameraMan* m_pCameraMan;

    bool m_bIsQuit;

    SinbadCharacterController* m_pChara;
    };

    在Enter函数中初始化:

    void CRunState::Enter()
    {
    COgreFramework::getSingletonPtr()->m_pLog->logMessage("Entering RunState.h.");

    m_pSceneMgr = COgreFramework::getSingletonPtr()->m_pRoot->createSceneManager(ST_GENERIC, "RunSceneMgr");
    m_pSceneMgr->setAmbientLight(Ogre::ColourValue(0.3f, 0.3f, 0.3f));



    m_pCamera = m_pSceneMgr->createCamera("MainCam");
    m_pCamera->setNearClipDistance(5);

    m_pCamera->setAspectRatio(Real(COgreFramework::getSingletonPtr()->m_pViewport->getActualWidth())/
    Real(COgreFramework::getSingletonPtr()->m_pViewport->getActualHeight()));


    COgreFramework::getSingletonPtr()->m_pViewport->setCamera(m_pCamera);

    m_pCameraMan = new OgreBites::SdkCameraMan(m_pCamera);
    m_pCameraMan->setStyle(OgreBites::CS_MANUAL);

    m_pChara = new SinbadCharacterController(m_pCamera);

    COgreFramework::getSingletonPtr()->m_pTrayMgr->destroyAllWidgets();
    COgreFramework::getSingletonPtr()->m_pTrayMgr->hideCursor();


    CreateScene();


    }

    在那些键盘和鼠标消息中响应人物和摄像机的事件。最后要在Update中更新动画。

    void CRunState::Update(double timeSinceLastFrame)
    {
    if (m_bIsQuit)
    {
    Shutdown();
    return;
    }

    if (m_pChara)
    m_pChara->addTime(timeSinceLastFrame/1000); // from miliseconds to seconds

    }


    这边注意,因为我们前面用的是毫秒,这边动画更新需要的是秒为单位,所以要除,否则画面不会动。

    二、载入.Scene场景文件

    如果要用代码加入物体,不仅麻烦(得算坐标),而且不易修改(修改后得重新编译)。于是就有了场景文件的出现,而且也有了开源的场景编辑器(Ogitor)。

    Ogitor是一个基于QT的OGRE场景的编辑器,可以到官网上下载:

    http://www.ogitor.org/HomePage

    在我们的工程中要用到的就是三个文件(在Ogitor的安装目录的/SampleApp_Source/下):

    DotSceneLoader.h

    DotSceneLoader.cpp

    rapidxml.h

    把他们拷进我们的工程里,我们将要使用他们来载入场景。

    这时,会发现程序有错,DotSceneLoader.cpp里要引用到PagedGeometry的一些东西,这是一个用来植树造林的工具,我们也可以去下载。

    http://www.ogre3d.org/tikiwiki/PagedGeometry+Engine

    官方没有提供已经编译好的,所以需要自己编译,要配置OGRE的头文件和库的路径。

    新的OGRE中的material的一个方法改了,所以编译会有错误:

    需要将:

    bestTechnique = material->getBestTechnique(material->getLodIndexSquaredDepth(parent->minDistanceSquared));

    转换为:

    bestTechnique = getLodIndex(parent->minDistanceSquared)


    这样就可以编译出LIB库了。

    回到我们的工程:

    在CreateScene函数中载入场景:

    void CRunState::CreateScene()
    {
    DotSceneLoader* pDotSceneLoader = new DotSceneLoader();
    pDotSceneLoader->parseDotScene("CubeScene.xml", "General", m_pSceneMgr, m_pSceneMgr->getRootSceneNode());
    delete pDotSceneLoader;

    // add a bright light above the scene
    Light* light = m_pSceneMgr->createLight();
    light->setType(Light::LT_POINT);
    light->setPosition(-10, 40, 20);
    light->setSpecularColour(ColourValue::White);

    // create a floor mesh resource
    MeshManager::getSingleton().createPlane("floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
    Plane(Vector3::UNIT_Y, 0), 100, 100, 10, 10, true, 1, 10, 10, Vector3::UNIT_Z);

    // create a floor entity, give it a material, and place it at the origin
    Entity* floor = m_pSceneMgr->createEntity("Floor", "floor");
    floor->setMaterialName("Examples/Rockwall");
    floor->setCastShadows(false);
    m_pSceneMgr->getRootSceneNode()->attachObject(floor);
    }


    这边要注意在资源文件(resource.cfg)中加入CubeScene.xml和Cube模型的资源路径,否则OGRE不会载入他们,就找不到这些资源。

    最后就可以看到结果了:

    尝试着载入了Ogitor自带的Sample文件,SampleScene3.scene。注意要把资源路径配好。

    人缩小一倍还比房子大。。。有点像绿巨人,人物的位置要根据地形高低来设置好。

  • 相关阅读:
    异常处理(throw,throws,try,catch,finally)
    内部类、匿名内部类、静态内部类
    Object,equals,toString
    有关于多态和静态绑定与动态绑定的知识
    接口的基本知识
    关于继承的基本知识,方法重写,final和abstract的使用, 动态绑定和静态绑定的知识
    设计模式: 单列设计模式 、模块方法设计模式、装饰设计模式、工厂设计模式、适配器设计模式
    zabbix设置维护周期
    zabbix入门
    yum安装zabbix 5.0 LTS
  • 原文地址:https://www.cnblogs.com/gameprogram/p/2373622.html
Copyright © 2020-2023  润新知