irrwowview

Tutorial 4: Movement

Tutorial 4: Movement
本教程演示如何使场景节点移动和活动。既表明SceneNodeAnimators基本概念又用键盘移动节点。

程序的效果如下图所示:

 

Lets start!

一如往常,我包含那头文件,使用irr命名空间,和告诉链接器要链接的*.lib文件。

#include <stdio.h>
#include <wchar.h>
#include <irrlicht.h>

using namespace irr;

#pragma comment(lib, "Irrlicht.lib")

这个教程中,我们的目标之一是使用键盘的一些键来移动场景节点。使用ISceneNode指针保存要移动的场景节点。
另一个指针是指向IrrlichtDevice,我们需要加入事件接收器来操作场景节点和获得摄像机。

scene::ISceneNode* node = 0;
IrrlichtDevice* device = 0;

要获得鼠标和键盘的输入事件,或者类似按钮点击的GUI事件,则需要一个继承自IEventReceiver的对象。只需重载一个方法:OnEvent。这个方法会在引擎有事件发生时调用。我们用WS键来移动场景节点。

class MyEventReceiver : public IEventReceiver
{
public:
          virtual bool OnEvent(SEvent event)
          {

如果‘W’或‘S’键被放开,程序就获取场景节点的坐标,并修改Y坐标值。因此如果按下‘W’,那节点会上移,按下‘S’,那节点会下移。

          if (node != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT &&
                                         !event.KeyInput.PressedDown)
          {
                               switch(event.KeyInput.Key)
                               {
                               case KEY_KEY_W:
                               case KEY_KEY_S:
                                         {
                                                   core::vector3df v = node->getPosition();
                                                   v.Y += event.KeyInput.Key == KEY_KEY_W ? 2.0f : -2.0f;
                                                   node->setPosition(v);
                                         }
                                         return true;
                               }
          }

 

          return false;
          }
};

事件接收器用于移动场景节点。因此我们只创建一个IrrLicht设备和想移动的场景节点。也可以创建其它额外的场景节点来演示场景节点的移动和动画。

int main()
{
   MyEventReceiver receiver;

 

  

 

  device = createDevice(video::EDT_OPENGL, core::dimension2d<s32>(640, 480),

 

       16, false, false, false, &receiver);

   video::IVideoDriver* driver = device->getVideoDriver();

 

   scene::ISceneManager* smgr = device->getSceneManager();

创建一个用‘W’和‘S’控制移动的节点。我们在引擎中创建一个用于测试的测试节点(‘test node’)。把节点放在坐标(0030)的位置并附上纹理,使节点看起来更有趣。

node = smgr->addTestSceneNode();
node->setPosition(core::vector3df(0,0,30));
node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));

现在我们创建另一个使用场景节点动画(ISceneNodeAnimator)移动的节点。场景节点动画(ISceneNodeAnimator)修改场景节点和可以依附上任何的场景节点(例如网格场景节点,公告板,灯光和摄像机场景节点)。场景节点动画不但可以修改场景节点的坐标,还可以活动一个对象的纹理。我们创建一个依附上‘fly circle’动画的测试节点,使新的节点围绕上一个节点旋转。

scene::ISceneNode* n = smgr->addTestSceneNode();
n->setMaterialTexture(0, driver->getTexture("../../media/t351sml.jpg"));

scene::ISceneNodeAnimator* anim =

 

     smgr->createFlyCircleAnimator(core::vector3df(0,0,30), 20.0f);

 

n->addAnimator(anim);

 

anim->drop();

最后我们添加一个md2模型作为场景节点动画,并用‘fly straight’使模型在两点之间跑。

scene::IAnimatedMeshSceneNode* anms = smgr->addAnimatedMeshSceneNode(
                    smgr->getMesh("../../media/sydney.md2"));

 

 

 

if (n)
          {
                    anim = smgr->createFlyStraightAnimator(core::vector3df(100,0,60),
                               core::vector3df(-100,0,60), 10000, true);
                    anms->addAnimator(anim);
                    anim->drop();

为了使效果更好,我们关闭了灯光(因为我们没有灯光,模型会是黑色的),设置动画循环的帧,把模型旋转180度并设置好动画速度
和纹理。
我们可以只用"anms->setMD2Animation(scene::EMAT_RUN)"代替"setFrameLoop""setAnimationSpeed"语句设置动画(包含循环帧和循环速度),但这个函数只支持MD2动画,而其它动画你应该知道如何做。

   anms->setMaterialFlag(video::EMF_LIGHTING, false);
   anms->setFrameLoop(320, 360);

 

   anms->setAnimationSpeed(30);
   anms->setRotation(core::vector3df(0,180.0f,0));
   anms->setMaterialTexture(0, driver->getTexture("../../media/sydney.BMP"));
}

为了可以在场景周围观看和移动,我们创建一个第一人称射击类型(first person shooter style)的摄像机并隐藏了鼠标光标。

smgr->addCameraSceneNodeFPS(0, 100.0f, 100.0f);
device->getCursorControl()->setVisible(false);

我们已经准备好一切,接着要绘制了。在窗口的标题栏加上程序名和FPSframes per second.

int lastFPS = -1;

while(device->run())

 

{

 

     driver->beginScene(true, true, video::SColor(255,90,90,156));

 

     smgr->drawAll();

 

     driver->endScene();

     int fps = driver->getFPS();

     if (lastFPS != fps)

 

     {

 

        wchar_t tmp[1024];

 

        swprintf(tmp, 1024, L"Movement Example - Irrlicht Engine (%s)(fps:%d)",
        driver->getName(), fps);

       device->setWindowCaption(tmp);

 

       lastFPS = fps;

 

     }

 

}

 

 

 

device->drop();
return 0;
}

就这样,编译和演示一下这程序吧。

 

posted on 2008-07-04 11:03 shjy 阅读(245) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理