4. Movement

Posted 2007/09/15 19:20 by 수달

--------------------------------------------------------------------------

튜토리얼 4 : 이동

----------------

이번 튜토리얼은 씬 노드를 이동하고 매니메이션하는 법을 보인다. 씬 노드 애니메이터의 기본 컨셉은 키보드를 이용해 노드를 수동적으로 움직이는 것이다.

<예제 그림>


--------------------------------------------------------------------------

시작

----

항상 그렇듯이 헤더 파일, 네임 스페이스, 라이브러리를 연결하자.


#include <stdio.h>

#include <wchar.h>

#include <irrlicht.h>


using namespace irr;


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


이번 예제의 목표 중 하나는 정해진 키보드 키를 사용해 씬 노드를 움직이는 것이다. 이를 위해 움직여야 할 위치를 저장하는 포인터 하나를 설정하겠다. (역자 주 : node 변수가 그것임) 그리고 발생하는 이벤트를 받아 씬 노드를 다루고 활성된 카메라를 얻기 위한 IRRLICHT 장치(device) 포인터를 하나 설정하겠다.


scene::ISceneNode * node = 0;

IrrlichtDevice * device = 0;


마우스나 키보드, 혹은 "Ok 버튼이 눌렸다."와 같은 GUI 이벤트를 얻기 위해, IEventReciver 객체가 필요하다. 거기에는 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 fasle;

}

};


씬 노드를 움직일 이벤트 리시버를 준비했다. 이제 할 일은 움직여 볼 씬 노드와 IRRLICHT 엔진을 만드는 것이다. 추가적으로 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 키로 움직이는 노드를 만들자. 테스팅 목적의 직육면체 하나를 만들어 (0,0,30)에 위치시키고, 여기에 볼만한 텍스처까지 적용해 본다.


node = smgr->addTestSceneNode();

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

node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));


자, 이제 씬 노드 애니메이터를 사용할 또 다른 노드를 만들어보자. 씬 노드 애니메이터는 씬 노드를 다양하게 변경시킬 수 있고, 메시 씬 노드, 빌 보드, 광원, 카메라등 다른 씬 노드에 의해 부착 될 수 있다. (역자 주 : 씬 노드 애니메이터의 기능을 사용자가 다른 씬 노드에서도 사용가능하게 한다.) 씬 노드 애니메이터는 위치의 변경 뿐만 아니라, 예를 들어 한 개체의 텍스처를 애니메이션할 때도 사용된다. (역자 주 : 한 (폴리곤, 메시) 개체에 여러 텍스처를 바꿔 입혀 애니메이션을 할 수 있다.) 예제에서는 테스트용으로 처음 만든 씬 노드 주위를 둥글게 날아다니는 '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();


모델을 보기 좋게 하기 위해, 광원을 설정하고(안하면 모델이 검게 나온다), 애니메이션 관련 폭과 속도, 텍스처 등등을 정해 보자. 아래 코드에서 애니메이션과 관련해 setFrameLoop()와 setAnimationSpeed() 대신 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"));

}


배치한 씬을 보기 위해 1인칭 슈팅 게임 스타일의 카메라와 마우스를 정하겠다.


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;

}


컴파일한 후 프로그램을 실행해 보라.


+ Recent posts