转载:OGRE一起学(十六)简化的 Common 头文件和简单角色控制

第十六章 简化的 Common 头文件和简单角色控制

OGRE 在 Common/include 目录下的两个头文件: ExampleApplication.h 和 ExampleFrameListener.h ,本身不是为了做游戏准备的,它是为了做演示 Demo 准备的。自从我们学习了键盘控制以后,做一个像模像样的小游戏的欲望肯定会越来越大,我们希望能够拥有自己的角色控制模块,像真正的游戏一样控制角色东奔西走、左顾右盼,这时候,上面两个头文件中的一些代码,包括鼠标控制、消息显示、功能切换等等的这些代码,都可能会变得很碍事,比方说,它们已经占用了方向键和 [W] [S] [A] [D] 来做镜头控制,我们想控制自己的角色就只能挑选其它键位了,上一节《键盘控制》里面我们就是挑选了 [I] [K] [J] [L] 来控制角色,很别扭是吧?

所以我们从这一节开始,使用自己的、经过最简化了的 MyApplication.h 和 MyFrameListener.h ,在这两个文件中,删除了鼠标控制、消息显示和功能切换等“多余”代码,键盘输入仅仅保留了对 [Esc] 退出的支持。 
这两个文件不需要放在 Common/include 目录下,因为我们可能随时会根据需要,向其中加入我们想要的功能,所以我们直接把它们放到每一个新项目的目录下。

头文件经过简化,条理比较清晰,加了注释,自己可以看看。

这个角色控制方式很笨很简单,就是上下方向键控制角色进退,左右方向键控制角色转身,并且镜头始终被固定在角色的背后,始终跟随角色运动。而角色本身永远在做行走动作,不会停下脚步,很简单了。

这种做法的几个要点:

(1) 首先要在 CharacterControlApplication::createScene() 方法中,把镜头绑定为角色节点的一个子节点:
// 绑定镜头节点到模型节点  mCamera->setPosition( Vector3( 0, 300, -400 ) );  mCamera->lookAt( objectNode->getPosition() + Vector3( 0, 100, 0 ) );  objectNode->attachObject( mCamera );  

注意上面 setPosition() 和 attachObject() 的顺序:先定位,再绑定。

(2) 然后每帧,在 CharacterControlFrameListener::frameStarted() 方法中处理键盘输入、控制角色移动和播放角色动画:
        // 获取角色对象的场景节点         mSceneNode = mSceneMgr->getSceneNode( "objectNode" );         // 获取键盘状态         if ( timeDelay <= 0 )         {             walkU = ( mInputDevice->isKeyDown( KC_UP ) )        ?  1 : 0;             walkD = ( mInputDevice->isKeyDown( KC_DOWN ) )      ? -1 : 0;             turnL = ( mInputDevice->isKeyDown( KC_LEFT ) )      ?  1 : 0;             turnR = ( mInputDevice->isKeyDown( KC_RIGHT ) )     ? -1 : 0;             timeDelay = 0.05;   // 0.05 秒内不再响应方向键输入事件         }         // 移动角色         mSceneNode->translate( Vector3( 0, 0, ( walkU + walkD )* walkSpeed ), Node::TransformSpace::TS_LOCAL );         // 旋转角色         mSceneNode->rotate( Vector3( 0, 1, 0 ), Angle( ( turnL + turnR )* turnSpeed ) );         // 更新动画状态         mAnimState->addTime( evt.timeSinceLastFrame* mAnimationSpeed ); 

这节讲讲场景节点的移动、旋转、缩放三个方法,它们各自都有若干重载,在头文件 OgreSceneNode.h 中定义:
virtual void translate (const Vector3 &d, TransformSpace relativeTo=TS_PARENT)  virtual void translate (Real x, Real y, Real z, TransformSpace relativeTo=TS_PARENT)  virtual void translate (const Matrix3 &axes, const Vector3 &move, TransformSpace relativeTo=TS_PARENT)  virtual void translate (const Matrix3 &axes, Real x, Real y, Real z, TransformSpace relativeTo=TS_PARENT)  virtual void rotate (const Vector3 &axis, const Radian &angle, TransformSpace relativeTo=TS_LOCAL)  virtual void rotate (const Quaternion &q, TransformSpace relativeTo=TS_LOCAL)  virtual void scale (const Vector3 &scale)  virtual void scale (Real x, Real y, Real z)  

你可以注意到 translate() 和 rotate() 方法的最后一个参数 TransformSpace relativeTo ,这个参数用来指定场景节点在移动和旋转时相对的参照系,也就是相对于谁来移动。 TransformSpace 是 Ogre::Node 类的一个枚举成员,在头文件 OgreNode.h 中定义:
        enum TransformSpace         {             TS_LOCAL,        // 相对于自身坐标系             TS_PARENT,      // 相对于父节点             TS_WORLD        // 相对于世界坐标系         }; 

灵活使用这个 TransformSpace 参数可以使我们直观快捷的进行场景节点的各种复杂控制,而不需要进行复杂的向量、矩阵、四元数等等的变换。

ZFGirl.zip 不用解压缩,直接放置到 Samples\Media\packs\ 目录下,然后在 resources.cfg 的路径中添加这个压缩文件,OGRE可以直接读取 Zip 资源包:

Zip=http://www.cnblogs.com/../Media/packs/ZFGirl.zip

这个角色动画文件中有很多动作,足够我们以后的若干章节中使用了,具体动作列表在压缩包里的 ZFGirlKey.txt 里面写着:

1,17,stand 
18,38,walk 
39,55,run 
56,76,attack1 
77,97,attack2 
98,118,attack3 
119,174,cool 
175,195,jump 
196,206,wound 
207,223,die 
224,244,happy

至于 3dsmax 源文件因为有公司的商业版权,不能放出了。

posted @ 2009-06-08 13:21  回忆1919  阅读(744)  评论(0编辑  收藏  举报