一如往常,我包含那头文件,使用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。这个方法会在引擎有事件发生时调用。我们用W和S键来移动场景节点。
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’)。把节点放在坐标(0,0,30)的位置并附上纹理,使节点看起来更有趣。
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);
|
我们已经准备好一切,接着要绘制了。在窗口的标题栏加上程序名和FPS(frames 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; }
|
就这样,编译和演示一下这程序吧。
|