IrrlichtСтатьи

Урок 4. Передвижение.

Автор:

Этот урок научит вас как двигать SceneNodes и включать у них анимацию. Показаны как основы SceneNodeAnimators, так и ручное передвижение объектов при помощи клавиатуры.

Вот как будет выглядеть нижеописанная программа:
Иллюстрация к уроку #4 по Irrlicht Engine | Урок 4. Передвижение.

Поехали!

Как всегда в самом начале прописываем заголовочные файлы, объявляем пространство имён irr и указываем линкеру на .lib файл.

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

using namespace irr;
#pragma comment(lib, "Irrlicht.lib")

В этом уроке одной из наших задач является заставить двигаться объект с помощью клавиатуры. Указатель на SceneNode объекта и указатель на 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 координату.

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;
  }
}

Всё, перехватчик событий создан, теперь необходимо создать IrrlichtDevice и указать на наш перехватчик ему. Также мы создадим ещё несколько SceneNodes, чтобы продемонстрировать дополнительные возможности перемещения и анимации.

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();

Создами объект, который будем двигать. Это будет "test node" - просто затекстурированный куб. Мы поместим его в позицию (0,0,30) и прилепим текстуру.

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

Теперь мы создадим другой движущийся SceneNode, мы заставим его двигаться с помощью "аниматора". Аниматоры это такие SceneNodes которые могут быть прилеплены к любому другому объекту и которые изменяют свойства объекта ( позицию, размер, текстуры и пр. ), параллельно с игровым процессом. Сейчас мы создадим аниматор, который позволит кубу летать по окружности.

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 ). Также мы прикрутим к объекту аниматор, который заставит объект двигаться по прямой между двумя точками.

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 градусов, определим скорость анимации и прилепим текстуру. Вместо команды setFrameLoop мы можем поставить команду anms->setMD2Animation(scene::EMAT_RUN)", которая автоматически проставит нужную скорость и кадры анимации, но её использование не рекомендуется, т.к. эта команда работает только со специально подготовленными 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"));
}

Чтобы иметь возможность созерцать всё нами сделанное, добавим FPS камеру и сделаем мышиный курсор невидимым.

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

Мы произвели все необходимые действия, осталось всё это нарисовать.

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;

}

Всё. Запускайте и радуйтесь.

Оригинал: http://irrlicht.sourceforge.net/tut004.html
Перевод: http://irrlicht.kytron.com/

2 мая 2006 (Обновление: 17 ноя 2006)