는 DirectX 수업의 첫번째 과제!
이번학기에는 과제물이나 스터디한 것을 차곡차곡 잘 정리해서 포스팅하는게 목표!
* 소위 용책.. 이라 불리우는 DirectX 9을 이용? 사용? 한 3D 게임 프로그래밍 .. 의 예제를 기초로 함.
* 쓸데없는 잡설은 더보기.. 로 접어둠.
* 재미 음슴. 정리도 사실 잘 안된 거 같음ㅠㅠ
* 중요한? .. 요소는 굵은글씨.
구현 목적!
- 세 개의 구로 이루어진 목표물이 존재함.
- 총알 역할을 하는 구가 존재함.
- 스페이스 바를 누르면 총알이 발사!
- 발사된 총알이 세 목표물 중 하나와 충돌하면 다시 원위치로 소환됨
- 그 어떤것과도 충돌하지 않으면 계속 그상태로 나와 멀어짐
- 총알은 키조작으로 상하좌우(X,Y)로 움직일 수 있다.
? 이걸 좀만 더 예전에 알았더라면 지난학기 기말 과제가 좀 더 쉬웠을텐데...!
DIRECTX 9를 이용한 3D GAME 프로그래밍 입문
- 저자
- FRANK D. LUNA 지음
- 출판사
- 정보문화사 | 2004-02-16 출간
- 카테고리
- 컴퓨터/IT
- 책소개
- 「DIRECTX 9를 이용한 3D GAME 프로그래밍 입문」은 ...
요 책 'ㅅ'.. 게임프로그래밍2, 게임프로그래밍3 수업 모두 다 이 책이 교재 =_=
Directional Light 예제를 기초로 삼았다!
원래 예제에는 네가지 물체(구, 큐브, 티팟, torus?)가 존재하고 그에 Directional light를 위치시키는 내용인데
이 예제를 살짝 수정해서 세개의 구를 목표물로 지정하고 구 하나를 더 생성해서 총알 역할을 맡겼다.
예제를 보기 전에 일단 기본적으로 렌더링파이프라인에 대해 다시 공부했음.
렌더링 파이프라인에 대해서는 다른 블로그에 자세한, 좋은 설명도 많으니 검색찬스를 쓰시길.
1. 오브젝트 생성
1) 변수 선언,
전역변수로 아래 변수를 선언해준다.
ID3DXMesh* Objects[4] = {0, 0, 0, 0};
D3DMATERIAL9 Mtrls[4];
D3DXMATRIX Worlds[4];
사실 나도 mesh에 대해서는 아직 더 공부해야됨T_T.. 공부를 아직 다 못했으니 설명은 PASS.
일단 작업하면서 체감하기로는 오브젝트를 지정하는 그릇? 같은 느낌이다.
재질을 설정해 줄 변수 Mtrls를 선언하고... 각 오브젝트에 월드 좌표를 지정해줄 변수 Worlds 도 선언한다.
2) 물체 생성
bool 형의 Setup() 함수를 살펴보면... 기존의 예제에서는 teapot도 만들고 torus도 만들고 sphere 도 만들고 .. 하는데
나는 간단하게 D3DXCreateSphere() 함수를 사용하여 Sphere를 네개 만들어주었다.
D3DXCreateSphere(Device, 1.0f, 20, 20, &Objects[0], 0);
D3DXCreateSphere(Device, 1.0f, 20, 20, &Objects[1], 0);
D3DXCreateSphere(Device, 1.0f, 20, 20, &Objects[2], 0);
D3DXCreateSphere(Device, 0.5f, 20, 20, &Objects[3], 0);
각각의 매개변수를 살펴보면... 두번째 인자는 구의 반지름, 두번째와 세번째는 음.. 경도와 위도를 지정하는?.. =_= 네번째는 해당 구를 만들어서 지정해줄 매쉬. 다섯번째는 무슨 의미인지 모르겠다. 마지막 구는 총알 역할을 담당하기 때문에 반지름을 줄였다.
3) 물체의 월드 좌표 지정
로컬 스페이스에서 물체를 만들어주었으니, 이제 월드 스페이스에서 물체들의 위치를 지정한다.
D3DXMatrixTranslation(&Worlds[0], -3.0f, 0.0f, 0.0f);
D3DXMatrixTranslation(&Worlds[1], 0.0f, 3.0f, 0.0f);
D3DXMatrixTranslation(&Worlds[2], 3.0f, 0.0f, 0.0f);
D3DXMatrixTranslation(&Worlds[3], 0.0f, 0.0f, -6.0f);
각각 살펴보면, 각 구가 모두 z=0 평면에 위치하고 z-에서 z+ 방향으로 카메라를 두었을 때 삼각형 모양으로 보인다.
재질 설정은 예제에 있으니 넘어가고! 지금은 재질이 중요한게 아니다.
조명 설정도 나중에 공부하고 일단은 넘어간다.
4) 카메라 설정
카메라는 아래처럼 지정해준다.
D3DXVECTOR3 pos(0.0f, 3.0f, -10.0f);
D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMATRIX V;
D3DXMatrixLookAtLH(&V, &pos, &target, &up);
Device->SetTransform(D3DTS_VIEW, &V);
(0, 3, -10)에서 원점을 바라봄. 업벡터는 (0,1,0).
2. 물체 이동 및 조작
이제 본격적으로 Display() 함수를 건들여보자.
참, 그전에 일단 총알의 움직임을 제어해줄 변수 x, y, z를 전역으로 선언한다. 자료형은 float을 쓰는게 좋...다ㅠㅠ
그리고 스페이스바를 눌렀을 경우, 충돌할 때 까지 그 상태를 지속해줄 bool 형의 변수도 하나 선언해준다.
변수를 선언할 때 초기화는 필수!!! x,y,z 이 세 변수에는 각각 0, 0, -6 의 수로 초기화해준다.
1) 물체 발사
먼저 스페이스 바를 눌렀을 경우, 구가 발사되도록 구현해준다.
변수 b_moveSphere 는 bool 형의 전역변수이다.
if( ::GetAsyncKeyState(VK_SPACE))
{
b_moveSphere = true;
}
if(b_moveSphere)
{
D3DXMatrixTranslation(&Worlds[3], x, y, z);
z += timeDelta*3;
}
우리가 발사해야될 것은 인덱스 3의 오브젝트이므로 Worlds[3]의 위치를 수정한다.
D3DXMatrixTranslation() 함수는 해당 오브젝트의 행렬의 위치를 이동시키는 함수다.
행렬이고 뭐고 설명하려면 매우 복잡한데 @_@... 근데 사실 검색하면 잘 나오는 문제이므로 내 블로그에서는 일단 패스.
나도 이론 따로, 실습 따로... 가다가 이번 과제 하면서 이론을 체감하게 되어서 행렬까지 설명하기엔 무리데스.
총알의 초기 좌표는 (0, 0, -6). 이제 스페이스 바를 누르게 되면 z값이 시간에 따라 변화하게 된다. 현재 총알은 z=-6 에 위치하고 최소한 목표인 z=0 까지는 가야하므로 z값을 증가시키기로 한다.
timeDelta는 Display() 함수에서 받아오는 값으로, 대체로 1초 정도... ? 아마? 유니티에서는 그런데 여기는 잘 모르겠다.
2) 물체 조작
추가적으로 상하좌우로 움직일 수 있게 코드를 좀 더 추가하도록 한다.
자세한 설명은 생략한다. 그냥 x축, y축에 대한 이동이다.
else if( ::GetAsyncKeyState(VK_LEFT))
{
D3DXMatrixTranslation(&Worlds[3], x, y, z);
x -= timeDelta*2;
}
else if( ::GetAsyncKeyState(VK_RIGHT))
{
D3DXMatrixTranslation(&Worlds[3], x, y, z);
x += timeDelta*2;
}
else if( ::GetAsyncKeyState(VK_UP) )
{
D3DXMatrixTranslation(&Worlds[3], x, y, z);
y += timeDelta*2;
}
else if( ::GetAsyncKeyState(VK_DOWN) )
{
D3DXMatrixTranslation(&Worlds[3], x, y, z);
y -= timeDelta*2;
}
3) 충돌처리
이제 저 대로 실행하면 아마 .. 스페이스를 바를 누름과 동시에 공이 앞으로 나아가며 나아가며 나아가며 ... 나아갈 것이다.
공이 앞으로 나아가는 것에 대한 제한. 즉, 충돌처리를 해줄 때가 된 것이지!!!
나는 따로 bool 형의 Collsion 함수를 만들었다.
bool CheckingCollision()
{
return false;
}
자 이제 여기에 무슨 내용을 채워넣어야 하지? 충돌처리? 충돌처리를 어떻게 하지? 거리로? 거리를 어떻게 재? 이건 횡스크롤 게임도 아니고.. 종스크롤 게임도 아니고 3D!!!... 입체인데?
그래서 머리를 쥐어짜다가 공간상에서 두 점 사이의 거리를 구하는 공식이 문득 떠올랐다.
(학학.. 수식 입력 힘들다@_@)
두 점 사이의 거리가 일정 거리 이하가 되면 충돌된 것으로 간주! ..
그래서 머리를 쥐어짜내어 작성한 코드는 아래와 같다. 이과생인데 수학을 못해요...,
bool CheckingCollision()
{
float result = 0;
for(i=0; i<3; i++)
{
float x1=0.0f; float y1=0.0f; float z1=0.0f;
x1 = Worlds[3]._41 - Worlds[i]._41;
x1 *= x1;
y1 = Worlds[3]._42 - Worlds[i]._42;
y1 *= y1;
z1 = Worlds[3]._43 - Worlds[i]._43;
z1 *= z1;
result = sqrt(x1 + y1 + z1);
if(result <1.0f) // if collision
return true;
}
return false;
}
아무튼. 거리가 1 이하가 되면 true 를 리턴! .. 하는데 리턴해서 뭐하지 ?
다시 Display 함수에서 총알이 움직이고 있는 상태에 실행되는 지점을 보자.
if(b_moveSphere)
{
// translate Yellow Sphere
D3DXMatrixTranslation(&Worlds[3], x, y, z);
z += timeDelta*3;
// collision
if(CheckingCollision())
{
// ???????????
}
}
이제 저 안으로 채워줘야 한다. 충돌이 일어났을 시, 총알이 다시 원위치!
일단 총알의 움직임을 멈추고, 총알을 원래의 위치로 이동시킨다.
아래의 코드를 빈 곳에 추가하자.
b_moveSphere = false;
x=0; y=0; z=-6;
D3DXMatrixTranslation(&Worlds[3], x, y, z);
이렇게 하면 이제 아래와 같은 슈팅 게임을 빙자한 ... 과제의 결과물이 나타난다.
일단 좌우로 움직일 수 있다.
아래는 충돌 못했을때. 끝없이 날아간다...
ps. .. 내가썼지만 참 성의 없게 썼다-_-;;;;
걸린 시간은 꽤 걸렸는데 써놓고보니까 왜 이렇게 정리가 안되고 어수선하지...ㅠㅠ
modify_
과제 제출 완료★ 헤헤@''@
잘했다고 칭찬 들었다*_*!!! 사실 좀.. 첫 수업때 저 과제 받고 거의 5일동안 VS 켜놓기만 하고 롤 .. 을 하다가
막판 가서 이틀? 정도 쉬엄쉬엄 예제 참고하고 예전에 교양수학 강의 때 배웠던 행렬지식 끄집어내서 했는데
막상 저렇게 하고 보니까 뭔가 욕심!? 이 더 생김ㅋㅋ 재미있다!!!
그치만 일단 당장 눈앞에 닥친 Unity 졸업 프로젝트부터 .. ㅠㅠ 포스팅도 일단 이번주 분량 끝내고ㅠㅠ
'스터디' 카테고리의 다른 글
Unity3D :: Time.timeScale (0) | 2013.10.06 |
---|---|
안드로이드 (0) | 2013.09.23 |
OpenGL :: .....예전에 했던 stanford bunny 과제 (0) | 2013.08.16 |
중간고사 대비 관련해서 이것저것 남겨두는 포스팅. (0) | 2013.04.21 |
Direct3D :: 시야각 설정을 통한 카메라 Zoom In/Out (0) | 2013.03.23 |