Урок 4. Передвижение.
Автор: Иван Аракчеев
Этот урок научит вас как двигать SceneNodes и включать у них анимацию. Показаны как основы SceneNodeAnimators, так и ручное передвижение объектов при помощи клавиатуры.
Вот как будет выглядеть нижеописанная программа:
Поехали!
Как всегда в самом начале прописываем заголовочные файлы, объявляем пространство имён 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)