Понедельник
29.04.2024, 18:32
Приветствую Вас Гость | RSS
Главная Каталог статей Регистрация Вход
Меню сайта

Категории раздела
Уроки програмирования игр на IrrLicht [7]
Уроки програмирования на игровом движке IrrLicht
Обработка цифровых изображений [0]
Различные способы реализации графических фильтровов,работа с цветовыми пространствами
Програмирование игр с использованием DirectX [3]
Програмирование трёхмерной графики на DirectX под Windows

Наш опрос
На каком языке вы програмируете?
Всего ответов: 209

Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0

Форма входа

Главная » Статьи » Програмирование » Уроки програмирования игр на IrrLicht

Урок 6.Столкновения.

Вспомните урок 2 как мы загружали карту из Quake 3.Мы будем использовать его, для того чтобы научиться управлять столкновениями. Кроме того мы немного усложним наш уровень, поместив на него 3 новые модели. Следующий код запускает Irrlicht и загружает quake 3 уровень. Я не буду рассказывать как мы это делаем так как уже рассказал вам об этом во 2-ом уроке.



#include <irrlicht.h>

#include <iostream>
using namespace irr;

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

int main()

{
  video::E_DRIVER_TYPE driverType;

printf("Please select the driver you want for this example:\n"\
    " (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
    " (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
    " (f) NullDevice\n (otherKey) exit\n\n");

  char i;
  std::cin >> i;

  switch(i)
  {
  case 'a': driverType = video::EDT_DIRECT3D9;break;
  case 'b': driverType = video::EDT_DIRECT3D8;break;
  case 'c': driverType = video::EDT_OPENGL;  break;
  case 'd': driverType = video::EDT_SOFTWARE; break;
  case 'e': driverType = video::EDT_SOFTWARE2;break; 
  case 'f': driverType = video::EDT_NULL;    break;
  default: return 0;
  }
  IrrlichtDevice *device = createDevice(driverType,

    core::dimension2d<s32>(640, 480), 16, false);
  if (device == 0)
    return 1; // could not create selected driver.

  video::IVideoDriver* driver = device->getVideoDriver();
  scene::ISceneManager* smgr = device->getSceneManager();

  device->getFileSystem()->addZipFileArchive
      ("../../media/map-20kdm2.pk3");

  scene::IAnimatedMesh* q3levelmesh = smgr->getMesh("20kdm2.bsp");

  scene::ISceneNode* q3node = 0;

  if (q3levelmesh)

    q3node = smgr->addOctTreeSceneNode(q3levelmesh->getMesh(0));


Всё,мы загрузили карту и Quake 3. Но теперь всё будет несколько иначе. Мы создаём triangle selector.
Triangle selector - это класс, который может содержать треугольники от узлов сцены для того, чтобы делать различные вещи с ними, например как в нашем случае обнаружения столкновений. Есть различные виды triangle selector, и все могут быть созданы с ISceneManager. В этом примере мы создаём OctTreeTriangleSelector.
Это очень полезно при использоании огромных mesh'ей как в quake3 уровне.

scene::ITriangleSelector* selector = 0;

  if (q3node)

  {   

    q3node->setPosition(core::vector3df(-1370,-130,-1400));

    selector = smgr->createOctTreeTriangleSelector(

            q3levelmesh->getMesh(0), q3node, 128);

    q3node->setTriangleSelector(selector);

    selector->drop();

  }

Мы добавили камеру от первого лица в сцену для того, чтобы было возможно перемещение по нашему загруженному quke3 уровню как это было в уроке №2, но на этот раз мы добавили специальную камеру проверки на столкновение : Collision Response animator.
После того, как  Collision Response animator связон с камерой, мы можем больше ничего не делать для проверки на столкновение, потому  что движок сделает это за нас.  Таким образом, выполнять проверку на столкновение в Irrlicht'e достаточно легко.


Теперь мы рассмотрим все параметры функции createCollisionResponseAnimator (). Первый параметр - TriangleSelector, определяет, столкновения в мире. Второй параметр - узел сцены, который присоединяется к объекту объектом занимается обнаружением столкновения, в нашем случае, это является камерой. Третье определяет, насколько большой объект, это - радиус эллипсоида. Испытайте это и измените радиус на меньшие значения, камера будет не в  в состоянии придвинуться поближе к стенам. Следующий параметр - направление и скорость серьезности. Вы могли оставить этот параметр в значении (0,0,0) . И последняее значение -  Без этого параметра , эллипсоид, с которым сделано обнаружение столкновения, был бы вокруг камеры, и камера будет в середине эллипсоида.


scene::ICameraSceneNode* camera = 
    camera = smgr->addCameraSceneNodeFPS(0,100.0f,300.0f);

  camera->setPosition(core::vector3df(-100,50,-150));

  scene::ISceneNodeAnimator* anim =
    smgr->createCollisionResponseAnimator(

    selector, camera, core::vector3df(30,50,30),

    core::vector3df(0,-3,0),

    core::vector3df(0,50,0));


  camera->addAnimator(anim);

  anim->drop();

Поскольку проверка на столкновения не является сложным в irrlicht, я опишу, как сделать два других способа проверки на столкновение. Но перед этим, я подготовлю сцену. Мне нужны 3 модели, которые я затем смогу осветить, и конечно надо избавиться от курсора :).


// disable mouse cursor

  device->getCursorControl()->setVisible(false);

  // add billboard

  scene::IBillboardSceneNode * bill = smgr->addBillboardSceneNode();

  bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );

  bill->setMaterialTexture(0, driver->getTexture(
        "../../media/particle.bmp"));

  bill->setMaterialFlag(video::EMF_LIGHTING, false);

  bill->setSize(core::dimension2d<f32>(20.0f, 20.0f));

  // add 3 animated faeries.

  video::SMaterial material;

  material.Texture1 = driver->getTexture(
        "../../media/faerie2.bmp");

  material.Lighting = true;

  scene::IAnimatedMeshSceneNode* node = 0;

  scene::IAnimatedMesh* faerie = smgr->getMesh(
        "../../media/faerie.md2");

  if (faerie)

  {

    node = smgr->addAnimatedMeshSceneNode(faerie);

    node->setPosition(core::vector3df(-70,0,-90));

    node->setMD2Animation(scene::EMAT_RUN);

    node->getMaterial(0) = material;

    node = smgr->addAnimatedMeshSceneNode(faerie);

    node->setPosition(core::vector3df(-70,0,-30));

    node->setMD2Animation(scene::EMAT_SALUTE);

    node->getMaterial(0) = material;

    node = smgr->addAnimatedMeshSceneNode(faerie);

    node->setPosition(core::vector3df(-70,0,-60));

    node->setMD2Animation(scene::EMAT_JUMP);

    node->getMaterial(0) = material;

  }

  material.Texture1 = 0;

  material.Lighting = false;

  smgr->addLightSceneNode(0, core::vector3df(-60,100,400),

    video::SColorf(1.0f,1.0f,1.0f,1.0f),

    600.0f);

scene::ISceneNode* selectedSceneNode = 0;

  scene::ISceneNode* lastSelectedSceneNode = 0;

 

  int lastFPS = -1;

  while(device->run())
  if (device->isWindowActive())

  {

    driver->beginScene(true, true, 0);

    smgr->drawAll();


После того, как мы нарисовали сцену :  smgr-> drawAll (), нам необходимо узнать, куда направленна камера. Кроме того, нам нужна точная точка quake3 уровня, на которую мы смотрим. Для этого, мы создаем 3-ью линию, начинающуюся в позиции камеры.

core::line3d<f32> line;

    line.start = camera->getPosition();

    line.end = line.start +

        (camera->getTarget() - line.start).normalize() * 1000.0f;

    core::vector3df intersection;

    core::triangle3df tri;

    if (smgr->getSceneCollisionManager()->getCollisionPoint(

      line, selector, intersection, tri))

    {

      bill->setPosition(intersection);

       

      driver->setTransform(video::ETS_WORLD, core::matrix4());

      driver->setMaterial(material);

      driver->draw3DTriangle(tri, video::SColor(0,255,0,0));

    }

Есть ещё один способ проверки на столкновения в движке Irrlicht.

selectedSceneNode = smgr->getSceneCollisionManager()->

          getSceneNodeFromCameraBB(camera);

    if (lastSelectedSceneNode)

      lastSelectedSceneNode->setMaterialFlag(

                video::EMF_LIGHTING, true);

    if (selectedSceneNode == q3node ||

          selectedSceneNode == bill)

      selectedSceneNode = 0;

    if (selectedSceneNode)

      selectedSceneNode->setMaterialFlag(

              video::EMF_LIGHTING, false);

    lastSelectedSceneNode = selectedSceneNode;

Вот и всё :-) Осталось выполнить последние штрихи.


driver->endScene();

    int fps = driver->getFPS();

    if (lastFPS != fps)

    {

      core::stringw str = L"Collision detection example - Irrlicht Engine [";
      str += driver->getName();
      str += "] FPS:";
      str += fps;

      device->setWindowCaption(str.c_str());
      lastFPS = fps;
    }

  }

  device->drop();

 

  return 0;

}
Готово!
Категория: Уроки програмирования игр на IrrLicht | Добавил: mannn (25.07.2010)
Просмотров: 1790 | Рейтинг: 4.0/3
Всего комментариев: 0
Имя *:
Email *:
Код *:
Поиск

Друзья сайта
  • Самый свежий NET.Framework
  • Програмирование игр на OpenGL
  • FAQ по системе
  • Инструкции для uCoz


  • Copyright by ZHABIN GRAD © 2024