http://irrlicht.sourceforge.net/

Çeviri : Yunus Kara (www.darkscythe.net)

Örnek 4.Hareket

Bu örnekte SceneNode'ları klavye girdisi ile nasıl hareket ettireceğimizi ve önceden belirlenmiş dahili hareketleri (dairesel hareket gibi...) nasıl uygulayacağımızı göreceğiz.

Örneğimiz bitince şuna benzeyecek:



Şimdi Başlayalım!

Her zamanki gibi başlık dosyalarımızı ekliyor,ad uzayımızı belirtiyor ve kütüphane dosyamızı bağlıyoruz.

#include <stdio.h>
#include <wchar.h>
#include <irrlicht.h>
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")

Bu örnekteki hedeflerimizden biri SceneNode'lardan birini klavye girdisi ile hareket ettirmek. Burada hareket ettirmek istediğimiz SceneNode'a bir gösterici tanımlıyoruz.
Diğer gösterici ise "Device" nesnemizi gösteriyor.Device nesnesini aktif kamerayı bulmak ve olay kotarıcısı(EventReceiver)'nın girdilerimizi işleyebilmesini sağlamak için kullanacağız.

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

Klavye,fare olayları ve görsel arabirim olaylarını işleyebilmek için "IEventReceiver" nesnesinden kalıtlayan bir nesneye ihtiyacımız var. Bu nesnede yineleme(override) yapılacak tek metod var oda "OnEvent". Bu metod motor tarafından herhangi bir olay olduğunda çağırılacak ve olaya göre belirlediğimiz işlemler yapılacaktır. Bu örnekte W ve S tuşlarını kullanarak SceneNode'lardan birini aşağı-yukarı hareket ettireceğiz.

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

Eğer W yada S tuşlarından birine basılırsa, SceneNode'un konumunu alıyor ve 'Y' koordinatını değiştiriyoruz.Böylece W'ya basınca nesne yukarı, S'ye basınca aşağı doğru hareket edecek.

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

Olay kotarıcımız hazır olduğunua göre "Device" nesnemizi ve hareket ettirmek istediğimiz SceneNode'u yaratıyoruz. Burada ayrıca diğer hareket ettirme yöntemlerinide göstermek için birkaç SceneNode daha ekleyeceğiz.

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

Klavye ile hareket ettireceğimiz Node'u yaratıyoruz. Burada motor içinde dahili bulunan bir küp(TestNode) ekliyoruz. Bu Node'u (0,0,30) konumuna yerleştirip daha düzgün gözükmesi için bir doku atıyoruz.

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

Şimdi bir "SceneNodeAnimator" tarafından hareket ettirilecek başka bir node yaratıyoruz. SceneNodeAnimator nesneleri herhangi bir Node'a iliştirilebilinir(mesh,billboard,light,camera). SceneNodeAnimator nesneleri bir nesnenin sadece pozisyonunu değil dokusunuda değiştirerek animasyon sağlayabilir. Yarattığımız yeni nesneye bir dairesel hareket('fly circle') animatörü ekliyoruz. Dikkat edeceğiniz gibi dairesel hareketin merkezi, klavye ile hareket ettireceğimiz nesne ile aynı ve hareketin çapıda 20 birim olarak verilmiş. Yani bu nesne klavye ile hareket ettireceğimiz nesnenin çevresinde dönecek.

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

SceneNodeAnimator'ların birbaşka hareketini göstermek için son SceneNode'umuzu ekliyoruz. Bu ilk örnekte eklediğimiz quake2 modeli ve ileri doğru uçuş('fly straight') animatörü ile iliştiriliyor.

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

Modelin düzgün gözükmesi(hiç ışık tanımlamadığımız için nesne siyah gözükecek) için ışığı iptal ediyoruz. Daha sonra modelin animasyon döngüsünü belirliyoruz. Modeli 180 derece çevirip, animasyon hızınıda ayarladıktan sonra dokusunu atıyoruz.
Animasyonu elle ayarlamak yerine, modelde dahili bulunan animasyonları "anms->setMD2Animation(scene::EMAT_RUN)" şeklinde çağırabiliriz. Tabi bu q2 modellerine özgü bir kullanım.

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

Bu yarattığımız nesnelere bakabilmek ve ortamda gezinebilmek için bir FPS kamerası yaratıp, fare imlecini gizliyoruz.

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

Her şeyi ayarladık artık çizdirebiliriz. Ayrıca pencere başlığına saniyede çizilen kare sayısınıda yazdıracağız.

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

Hepsi bu. Derleyin ve izleyin. :)