포트폴리오 소개서

Download Report

Transcript 포트폴리오 소개서

포트폴리오 영상 링크
00 BLOG http://jjoreg.tistory.com/
01 WINAPI http://www.youtube.com/watch?v=48WA4mBJt6M
02 DIRECTX2D http://www.youtube.com/watch?v=PvBCWlV7Jj4
03 DIRECTX2D MFCTOOL http://www.youtube.com/watch?v=z7BMUlP0f-o
04 DIRECTX2.5D http://www.youtube.com/watch?v=48WA4mBJt6M
05 DIRECTX2.5D MFCTOOL http://www.youtube.com/watch?v=yB_k0chW_GA
06 DIRECTX3D http://www.youtube.com/watch?v=OuHRamHwniA
07 JAVA 2D
08 UNITY3D
구현기술 및 코드소개서
사용 프로그램 : Microsoft Visual Studio 2008
조해근
시기
시작하고 2개월
기한
15일
장르
전방위 슈팅 RPG
01 2D WINAPI SOLO
프로젝트 이슈
1. 무한맵
2. 스킬 상점 및 스킬 교체
3. 몬스터 & 오브젝트
4. 충돌
영상주소 http://www.youtube.com/watch?v=48WA4mBJt6M
1. 무한맵
-> 플레이어는 전 방향 어디로든 움직일 수 있다.
-> 어디로 가도 맵은 계속 되어야 한다.
-> 결론 = “타일들이 끝없이 이어지는 무한히 이어지는 무한맵을 만들자.”
새로운 타일 생성!
위치지정.
RENDERING 이미지 지정.
즉 Tile* pTile = new Tile()
왼쪽 이동
타일 삭제
delete pTile
무한맵 구현 1차 시도 -> 실패
1.
새로운 객체를 생성하는 NEW가 얼마나
부하를 일으키는지 여기에서 배움.
2.
TILEOBJECT 오브젝트를 담고 있는 STL은
타일의 개수가 9X9개로 제한되어 있으므
로 VECTOR을 사용했지만 무한맵을 구현
하기 위해서 기존 객체를 빼고 새로 추가
하는 방식은 삽입삭제가 느린VECTOR를
가장 잘못 이용하는 방법이었다.
3.
무한맵은 구현되었지만 프레임이 떨어지
는 문제를 겪게 되었다.
스크롤의 X 수치가 기준 위치 + 240
픽셀보다 큰 상황에서
타일들을 검색하여 중 위치가 오른쪽
끝에 위치한 상태라면
타일의 위치를 왼쪽으로 옮기고
반복되지 않도록 새로운 이미지번호
를 부여
기준 위치를 현재의 스크롤 X 위치로 이동시킨다.
그래야 계속 왼쪽으로 이동해도 새로운 기준에 의
해서 계속적으로 타일을 옮길 수 있다.
타일 자체가 이동한다.
왼쪽 이동
2차시도 결과 -> 성공
1.
타일객체의 데이터의 변경만으로 해결
2.
플레이어가 어느 방향으로 움직인다면 그 위
치를 기록하고 자신의 위치가 일정 리미트를
넘기면 플레이어가 진행하는 방향의 가장 앞
쪽으로 위치를 이동 시키고 새로운 이미지를
부여한다.
3.
위의 코드를 상하좌우에 맞춰서 4가지 경우로
분류하여 캐릭터가 어느 방향으로 움직이더라
도 맵이 계속되는 듯한 효과를 부여한다.
2. 스킬교체
-> 스킬을 구매하려면? 어떠한 상점이나 혹은 그에
준하는 UI나 디스플레이 요소가 존재해야 한다.
-> 필드에 상점을 만든다.
-> 상점 오브젝트가 나오고 그 오브젝트에 접근하면
상점 UI가 뜨도록 한다!
-> 상점에 가까이가면 상점화면이 열리고 상점 기능
과 관련 있는 객체를 제외한 다른 요소들은 RENDER
기능을 제외하고는 정지. 즉 업데이트 하지 않는다.
상점 근처로 이동시 이벤트를
발생하게 했다.
스킬들은 ACTION이라는 명
칭의 클래스들로 표현됩니다.
상점에 들어가면
ACTIONCREMGR 클래스에서
무작위로 스킬을 생성합니다.
보유한 스킬과 상점의 스킬을
기반으로 SHOPICON 클래스
를 생성합니다.
SHOP 클래스에서는
SHOPICON을 외부에 표시하
고 실행을 시키는 역할을 합
니다.
상점에 들어가면 4개의 스킬을
확인이 가능하고 그 스킬을 자
신의 스킬슬롯의 스킬과 교환하
므로서
3. 몬스터 & 오브젝트
-> 정확하게 캐릭터는 항상 화면 중앙에 존재한다고 할 수 있으며 fCreTime라는 전역변수를 하나 두고 거
기에 +를 시키는 방식으로 몬스터를 생성.
-> 외부의 보스의 위치를 설정하고 그 위치에 미리 보스를 생성해 놓는 방식으로 진행되며 보스와 대전이
시작되면 몬스터나 TERRAIN생성은 중지한다.
몬스터는 크게
근접 몬스터 AI와
원거리 몬스터 AI로
나누고 BRIDGE패턴
을 이용해서 인공지
능을 만들었습니다.
외부의 CREATEZONE에서 무작위로
MONSTER과 TERRAIN을 생성합니다.
외부의 CREATEZONE에서 무작위로
MONSTER과 TERRAIN을 생성합니다.
4. 충돌
-> 크게 보면 3가지 충돌이 존재하며 모두 원 충돌 방식을 통해서 서로간의 방향을 확인한 후 반사각 방향
으로 밀어내는 방식으로 충돌을 구현.
1. 서로 튕겨내는 충돌
1-1. MONSTER & PLAYER
1-2. MONSTER & TERRAIN
1-3. PLAYER & TERRAIN
-> 모든 기술이나 공격을 ACTION이라는 클래스로 묶는다.
그리고 몬스터와 플레이어가 존재하므로 ACTION은 2가지 종류로 나눈다.
PLAYERACTION & MONSTERACTION.
2. ACTION의 충돌.
2-1. PLAYERACTION & TERRAIN
2-2. PLAYERACTION & MONSTERACTION
2-3. MONSTERACTION & PLAYER
2-4. MONSTERACTION & TERRAIN
EXTRA. 아쉬운 점
1. 몬스터들의 패턴을 좀더 다양화 하지 못한 점.
플레이어를 향해서 돌진한 후 총알을 발사할 뿐. 그 이상의 행동을 집어넣지 못했다. 회피하
거나 2가지 종류의 공격을 상황에 맞춰 사용하거나.
2. 스코어 등의 UI를 제대로 구현하지 못한 점.
실제 글자 하나를 띄우는 것도 프로그래밍적으로는 많은 노력이 들어가야 한다는 것을 깨
달았다.
EXTRA. 얻은점
1. 최초로 게임이라는 것을 혼자의 힘으로만 하나 만들어 보았다.
2. 전 과정을 혼자서 처리한다는 것의 어려움, 즐거움을 알게 되었다.
3. 게임 속에서 내가 무언가를 하고 싶다면 그에 맞는 노력이 필요하
다는 것을 깨닫는다.
4. 게임 그 자체가 더 좋아졌다.
시기
프로그래밍 3개월 차
기한
3일 (인원수 : 4)
장르
포트리스 모작
02
2D WINAPI TEAM
프로젝트 이슈
1.
땅을 깎아야 한다.
2.
카메라 워크.
3.
턴 방식
* 맡은 주요 업무 : 픽셀단위 충돌 & 지형파괴
1. 땅을 깎자.
-> 나에게 맡겨진 임무는 말 그대로 땅을 깎아내는 것.
-> 시작 시 너무 막막한 기분.
-> 하지만 어렵게 생각하지 말고 모든 것은 결국 데이터라는 것에 착안.
-> 결국 이미지도 데이터이고 0과 1로 이루어진 녀석들이다. 색깔을 표시하는 것도 결국 0과 1로 이루어진
데이터가 그렇게 색깔을 모니터에 그리라고 해서 그릴뿐이다. 그럼 그 데이터만 고친다면 되는 것 아닌가?
깎이기 전의 이미지 데이터가 있다면 그 데이
터를 수정하면
실제 이미지를 깎을 수 있지 않을까?
2. 데이터를 구분하자.
-> 우리가 깎아야 할 땅은 배경과 분리된 땅 본면의 녀석이 필요하다.
-> WINAPI에서 투명 처리를 위해서 필요한 이미지들은 TransparentBlt을 사용하여 RENDER하고 있었다.
-> 즉 실제로는 분홍색으로 제외할 색상을 지정하고 그 색은 모니터에 그리지 않는 않는 함수를 사용하여
렌더링 하고 있다.
-> 즉 우리의 이미지는 투명색과 그 이외의 색으로 분리할 수 있다.
-> 결론 : 나는 이미지의 색상 값을 가져야와 한다.
배경과 하나인 이미지로는 알 수 없다.
이와 같이 실제 탱크가 올라가고 깎여야 할 땅
의 이미지를 색상 해볼 때 색상 값을 가져올 방
법을 찾아야 한다.
3. 색상 값을 어떻게?
-> 구글링!
-> WINAPI에서는 실제 이미지의 데이터를 저장해 놓는 DC객체를 사용하고 이 DC객체에서 GetPixel로 가
져올 수 있다는 것을 알았다.
//투명RGB 이미지는 다음의 색상입니다.
#define TRANSPARENTIMAGE RGB(255,0,174)
STAGE_BMP_PIXELMAP
포탄이 충돌할시 픽셀에 대한 체크를
해야 한다. 결국 일정 픽셀의 RGB값
을 가져와서 그 값을 비교하여 처리
해야만 한다.
각 BMP파일의 MemDC를 통해서
if( GetPixel(STAGE_BMP_PIXELMAP-> GetMemDC() , x,y)
!= TRANSPARENTIMAGE )
다음과 같이 색상 비교를 한다. 즉 포탄의 위치인 x, y
픽셀에 반환된 값이 TRANSPARENTIMAGE값이 아니
라면 땅이 존재한다는 것.
4. 탱크는 어떻게?
-> 값이 있다면 뭐든지 할 수 있다. 한점의 픽셀을 가져와서 그값을 기준으로 탱크가 땅위에 올라과 있는지
아닌지 판단할 수 있다.
-> 탱크가 땅 위에 올라가 있다면 더 이상 낙하하지 않게만 하면 해결.
탱크의 중심을 기준으로 아래로 내려
가며 땅이 있는지 없는지 색상 값을
기준으로 하여 만약 투명처리를 위한
투명 값이 아니라면 탱크는 땅 위에
올라서 있는 것이다.
5. 땅은 어떻게 깎을까?
-> 땅을 깎는 것은 체크가 아닌 수정의 문제 이미지 자체를 수정해야 한다.
-> SetPixel이라는 함수를 사용하여 실제 이미지의 DC의 값을 수정할 수 있다는 것을 깨달음.
-> 거기에 픽셀을 수정할 수 있다는 것을 보여준 이후 나는 카와이 하게 별 모양으로 땅을 깎아보겠다고 단
언했으나. 어떻게 별 모양으로 깎을지 생각해보지 못함.
땅 깎아내기 1차 시도 -> 실패
1.
For문을 사용해서 픽셀로 이루어진 원을
만들고 그것을 사용하여 땅을 깎아 내려
고 함.
2.
땅 이미지의 크기는 대략 4000 * 2000이
며 그 중 한 부분의 픽셀을 투명색으로 수
정하는 코드를 넣었다.
3.
For문이 문제가 아니고. 실제 원을 만들어
내는 코드 또한 for문이라는 것이 문제며
원모양을 만들어 내는 코드가 오히려 더
큰 부하를 만들어 낸다는 것을 깨달았음.
6. 진짜로 별 모양으로 깍으려면?
-> 내가 코드적으로 별을 만들어내는 것은 어리석은 생각이었다.
-> 별 모양으로 무언가를 하려면 별 모양 이미지를 준비하는 것이 더 간편하다.
-> GetPixel로 색상 값을 가져올 수 있다면 별 모양의 이미지의 색상 또한 가져올 수가 있지 않을까?
-> 즉 별 모양의 이미지와 땅의 이미지를 별 모양의 이미지가 땅에 겹쳐진다고 생각하고 겹쳐지는 부분의
색상을 변경하면 되는 것이 아닌가?
땅 깎아내기 2차 시도 -> 성공
1.
별 이미지를 준비한다.
2.
별 이미지를 땅에 겹치게 위치를 조정한다.
3.
별 이미지의 어느 한점의 색상이 투명색이
아니라면 그와 겹치는 곳의 땅 이미지의 색
상을 투명색으로 변경한다.
실제 작업 및 코드.
STAGE_BMP_BOOM의 X, Y 값이 투명 값이 아니라면
STAGE_BMP_PIXELMAP동일한 위치에 겹치는 X, Y
위치의 색상이 있는 값을 투명값으로 변경한다.
STAGE_BMP_BOOM
STAGE_BMP_PIXELMAP
충돌지점에 겹친다
땅을 예쁘게 별 모양으로 깎아보기 위해서 다음과
같은 폭발 이펙트를 추가한다.
결과물
EXTRA. 아쉬운 점
1. 포탄의 패턴을 포물선 하나밖에 못 만든점.
유도탄 분할탄 등등 포트리스에서 있었던 포탄들이 여러가지 있었다. 하지만 3일이라는 시
간 동안 만들어야 하는 압박이 너무 컸다.
2. 탱크의 기울기에 따른 회전.
WINAPI를 하면서 이미지의 다이렉트 기반이 아니기 때문에 이미지의 회전을 해보지 못했
던 점이 있었다. 즉 탱크는 언제나 수평방향만이 가능했고 그에 따른 각도 수정도 할 수 없었
다. 만약 비슷한 프로젝트를 한다면 다음에는 꼭 해보고 싶은 일이다.
EXTRA. 얻은점
1. 개발로서의 첫 팀작업.
2. 모든 것은 0과 1이다. 그리고 프로그래머는 그걸 조작할 수 있다.
3. 할 수 없을 수도 있다.
4. WINAPI만으로는 한계가 있다. 아니 WINAPI의 한계는 하드웨어 적
인 문제고 실제로는 시간의 한계가 있다.
시기
프로그래밍 4개월 차
기한
15일
장르
부루마블식 TCG게임
03
DIRECTX 2D SOLO
프로젝트 이슈
1.
카드게임 + 부르마블.
2.
다양한 스테이지.
3.
300종의 카드.
4.
턴 방식.
1. 카드게임 부르마블?
-> 4명의 플레이어가 다양한 맵에서 시작한다.
-> 카드의 종류는 마법, 소환, 장비카드가 존재한다.
-> 최초 플레이어는 45장의 카드를 가지고 시작한다.
-> 주사위를 굴려 이동하며 빈 땅에 도착했을 때 소환카드를 사용하면 땅을 점령할 수 있다.
-> 마법을 사용하면 자신이 원하는 칸으로 이동하거나 점령지역 몬스터에게 직접 데미지를 주는 행동이 가
능하다.
-> 다른 유저가 자신의 땅이 아닌 이미 점령된 땅에 도착하면 통행료를 내거나 자신의 몬스터를 투입하여
전투를 걸 수 있다. 이때 전투에서는 장비카드를 사용할 수 있으며 승리하면 땅을 빼앗을 수 있다.
2. 다양한 스테이지.
-> 다양한 스테이지를 구성하기 위해서는 예전과 같이 코드안에 데이터를 같이 때려넣는 작업으로는 너무
비효율 적이었다.
-> 그것을 위해서는 맵을 제작하기 위한 툴을 만들 필요가 있었고 그를 위해서 MFC(Microsoft
Foundation Classes)를 공부했다. 공부하던 언어가 C++이었고 그것을 기반으로 해서 GUI를 만들 수 있는
라이브러리는 MFC가 가장 최선이었기 때문이다.
-> MFC에 대해서 들었던건 최악의 라이브러리 M(미치고) F(팔짝뛰는) C(클래스라이브러리)라고 하는등 온
갖 혹평은 다 들었지만 사용시에는 딱히 기능을 잘 이용하고 버그를 피해가면 되는 것이었다. 생각보다는
잘 사용해서 툴을 제작할 수 있었다.
실제 완성된 스테이지 툴
실제 타일들의 이미지를 맵에 배치하고 수정이 가
능하다.
플레이어 제작, 스테이지 아이콘 제작, 스테이지
제작, 카드 제작, 텍스쳐 에디터를 탭으로 만들어
항목을 분리하여 편의성을 높인다.
스플릿 기능을 사용하여 윈도우 창을 나눈다.
참가할 플레이어를 수정한다.
2. 300종의 카드.
-> 각기 소환수 100종, 마법100종, 장비100종의 카드를 만들기를 원했고 실제 그렇게 만들었다.
-> 당연히 툴을 사용했고 다양한 효과를 위해서 그를 구분하는 방식을 클래스화 시켰다.
-> 카드라는 클래스 내부에는 카드별로 다른 동작을 하기 위한 브릿지 패턴을 사용했다.
실제 완성된 카드에디터
카드의 이미지를 보여주고
설명과 능력치 등을 설정하고
소환되는 몬스터의 이미지
도 보여준다.
만들어진 카드는 리스트로
적재된다.
카드 추가나 수정 모두 가능
2-1 EXTRA. 새로운 난수 알고리즘
-> 새로운 난수 발생 알고리즘이 필요.
-> 구글링을 통해서 검색.
-> 메르헨 트위스터와 WELL이 물망에 오름.
-> WELL이 사용법이 더 간단함.
-> WELL512를 사용하기로 결정.
-> 안정적인 난수 생성을 위해서 시드 값은
_strtime_s(dbuffer); 시에서 획득한 시간
값을 사용함.
2-2 EXTRA. 플레이어 클래스 및 카드관리
플레이어가 미리 준비한 DECK의 카드
45장이 들어간다.
준비한 카드를 뒤섞어서 실제 사용할 DECK을 저장
한 벡터.
플레이어가 손에 쥐고 있
는 카드들
특수한 동작을 하는 카드들. 셔플 시 회전하거나 한
장을 드로우 할 때 하늘에서 부터 떨어지는 애니메
이션을 실행할 카드들의 배열…
길 찾기 알고리즘을 위해서 플레이어가 이미 지나간
타일들의 인덱스를 저장하는 MAP 지금 와서 생각해
보면 굳이 MAP일 필요는 없었다.
4. 턴 방식.
기존의 구상했던 턴방식에 대한 구현은 모두 실시간으로 동작하는 가운데 if문으로 실제 동작을 막아놓는
것이었다.
Public Bool bMyTurn;
if(bMyTurn)
{
동작 실행;
}
하지만 그 if문에 대한 처리도 귀찮았고 내가 보기에는 실제적으로 실용적이지 못했다. 그래서 다음과 같은
구조를 사용해서 적용해봤다.
-> 매 1턴 1턴마다 Queue<CPlayer>를 사용하여 플레이어객체를 지정한다.
-> Queue안에 들어있는 front()의 실제 동작함수를 실행한다.
-> 실제 동작이 끝나면 Pop시켜서 실행이 끝난 객체를 제거한다.
-> Queue<CPlayer>의 Empty체크를 하여 비어있다면 1턴이 끝났다는 것이다.
EXTRA. 아쉬운 점
1. 파일 입출력과 데이터 정리는 짜증나는 일이 아니다.
모두들 세이브파일을 만들거나 저장을 하거나 게임을 지속시키는 것을 그다지 중요하게 생
각지 않는다. 눈앞의 그래픽효과에 신경 쓴다.
내가 아쉬운 것이 아니라 모두가 그렇게 생각한다는 것이 아쉽다. 파일 입출력은 귀찮고 짜
증나는 일이 아니며 코드의 구조만큼이나 데이터의 구조 또한 중요하다.
하지만 처음으로 시도한 일이라 그런지 제대로 구조를 못 잡았던 점이 있었다. 결국 저장후
이어서 하는 것은 구현하지 못하고 카드데이터와 스테이지 구조만 완료할 수 있었다.
2. 구조의 문제점.
실제 프로그래밍을 하면서 각 클래스와 데이터들을 좀더 효율적으로 관리하기 위한 구조를
잡지 못했다. 클래스의 함수는 너무 많아지고 가독성은 점점 떨어져갔다.
혼자 하는 습작 프로젝트니 상관 없다는 생각은 너무 안이하다고 생각하고 아름다운 구조
를 목표로 삼는 계기가 되었다.
EXTRA. 얻은점
1. 파일 입출력.
2. 코드와 데이터는 별개다.
3. 툴은 최고야!
4. 좋은 클래스 구조가 좋은 코드를 낳는다.
시기
프로그래밍 5개월 차
기한
15일 (인원수 : 3)
장르
스테이지형식 RPG
05
DIRECTX 2.5D TEAM
프로젝트 이슈
1.
렌더링 구조.
2.
맵 구조 및 컬링.
3.
데이터 구조.
* 주요 업무 : 지형 & 컬링 & 오브젝트로딩
1. 렌더링구조.
-> 2.5D를 처음 시작하면서 DIRECTX9.0을 처음으로 접했다.
-> 모든 3D는 각 버텍스 정점 위에 텍스처를 매핑시키는 것이다.
-> 2.5D에서 맵을 제외한 모든 4개의 점으로 구성된 버텍스에 텍스처를 매핑시키는 작업이었다.
-> 맵은 그런 버텍스를 일정 개수만큼 연결해서 만들어내는 것으로 내가 맵을 담당하게 되었다.
렌더링 한다.
점에
이미지를 매핑한다
2. 맵 구조 및 컬링.
-> 맵은 전에 만들던 타일맵과 비슷하게 사각형 점점을 여러 개 연결해서 만든다.
-> 높이맵 방식을 사용한다. 정점의 높낮이를 통해서 맵의 굴곡을 표현하는 방식.
-> 하지만 CCW를 끄고 Z버퍼를 OFF시키고 렌더링 하기 때문에 굴곡이 많은 경우 뒤에 렌더링한 면이 앞에
서 렌더링 해도 보인다는 점이 있다. 즉 직육면체 박스를 렌더링 해도 뒤에있는 면이 보이는 현상이 존재한
다. 완전한 3D모델링을 렌더링 하면 없을 문제지만. 2.5D는 그에 대한 문제를 해결하는 것 자체를 목표로 잡
기 때문에 (즉 어떠한 모델링도 사용하지 않고 직접 맵을 만드는 것) 그에 대한 해결책이 필요했다.
맵의 뒷면도 보인다.
보
는
방
향
이런 식으로 보인다.
2-1 EXTRA. 실제 맵 렌더링코드.
/*, std::greater<float>*/
multimap<float, CObj*>::iterator SortIter = CObjMgr::GetInst()->GetSort().begin();
QSortVtx(m_pQuickSort, 0, idex-1);
m_TriCnt = 0;
먼저 플레이어가 보는 방향을 기준으로 가장 먼저 보일 버텍스와 다음에
보일 버텍스를 구분하여 소팅 한다.
for(int x = 0 ; x < idex ; ++x)
{
int iIndex
= m_pQuickSort[x].index;
float pivot = m_pQuickSort[x].VtxZ;
m_pSortIdx[m_TriCnt]._0 = iIndex;
m_pSortIdx[m_TriCnt]._1 = iIndex + VTXCNTX;
m_pSortIdx[m_TriCnt]._2 = iIndex + VTXCNTX + 1;
++m_TriCnt;
m_pSortIdx[m_TriCnt]._0 = iIndex;
m_pSortIdx[m_TriCnt]._1 = iIndex + VTXCNTX + 1;
m_pSortIdx[m_TriCnt]._2 = iIndex + 1;
++m_TriCnt;
}
Render();
각 정리된 버택스의 렌더링 순서를 변경해줘야 하기 때
문에 인덱스버퍼의 값을 다시 부여 해준다.
만약 소팅STL이 비어있지 않고 어떤 객체가 렌더링 되
려고 할때 몬스터나 플레이어가 그 앞에 있다면 먼저 맵
을 렌더링 하고 그다음 몬스터를 렌더링 한다.
if(!CObjMgr::GetInst()->GetSort().empty())
{
if( SortIter != CObjMgr::GetInst()->GetSort().end() && pivot + VTXSIZEX*3 <= SortIter->first * -1 )
{
Render();
SortIter->second->Render();
++SortIter;
ZeroMemory(m_pSortIdx, sizeof(VTXTEXSORT) * m_iMaxSort);
m_TriCnt = 0;
//continue;
}
}
이런 식으로 맵의 일부 -> 몬스터 -> 맵의
일부 -> 몬스터 식으로 렌더링을하며 맵과
몬스터의 렌더링 순서를 조정한다..
다음 몬스터가 존재한다. 일단 여기까지의
맵을 렌더링 한다.
바로 다음 몬스터를 렌더링 한다.
몬스터가 존재한다. 일단 여기까지의 맵을
렌더링 한다.
바로 다음 몬스터를 렌더링 한다.
보
는
방
향
3. 데이터구조.
-> 스테이지를 세팅하고 데이터를 로딩하는 구조를 제작해야 했는데.
-> 다음과 같이 와이어프레임으로 맵을 볼 수 있으며 몬스터를 제작할 수 있게 만들었다.
실제 완성된 맵툴
실제 완성된 몬스터툴
EXTRA. 아쉬운 점
1. 데이터 구조! 어떻게 해야 좀더 효과적이지?
전에 했던걸 그대로 답습하는 데이터 구조를 짜게 되었다. 데이터도 동적으로 관리할 수는
없을까? 파일을 읽을 때 꼭 데이터의 순서를 맞춰야 하나? 만약 순서가 바뀌거나 혹은 새로
운 데이터가 추가된다면 그에 대한 대처를 어떻게 해야 하나?
이때는 고민해도 아직은 해결책이 없었다.
2. 유연하지 못한 상속구조.
상속을 기본으로 하는 구조는 클래스를 너무 많게 만들고 하위 클래스에서는 사용하지 않
는 기능을 물려받는 악순환이 계속된다는 것을 느끼게 되었다. 구조를 만들면서도
HAS-A, IS-A에 맞는가 아리송한 상속이 몇 번 나오게 되었고
하지만 이 프로젝트로 인해서 다른 구조를 연구하게 만드는 계기가 되었다.
EXTRA. 얻은점
1. 3D의 기본 버텍스.
2. 데이터도 동적인 구조가 필요하다.
3. 팀원들과의 끈끈함.
4. 스스로 만든 정렬을 처음으로 사용해 봄.
시기
프로그래밍 8개월 차
기한
45일 (인원수 : 7)
장르
MMORPG
05
DIRECTX 3D TEAM
프로젝트 이슈
1.
새로운 프레임워크
2.
DIRECTX9.0 3D기술과 HLSL.
3.
플레이어 & 애니메이션제어.
4.
툴을 C#으로 만든다.
* 주요 업무 : HDR & 범프매핑
& 플레이어애니메이션
1. CScene은 CLayer를 STL Vector에 보관하며 순
회하면서 CLayer 의 함수를 실행한다.
1. 새로운 프레임워크 구조
2. Ccomponent까지 계층구조를 이루며 각 함수를
실행해 나간다.
3. CGameObject는 자기 자식으로 CGameObject
를 가질 수 있다.
Ex) CGameObject인 플레이어는 같은
CGameObject인 검을 들고 있을 수 있다.
4. CGameObject는 컴포넌트를 통해서 게임내 객
체가 될 수 있다.
CComponent
-UINT m_iComTag
-bool m_bVitality;
CBase
#int m_iRefCount;
#tstring m_strTag;
#CBase* m_pParent;
CSceneNode
+RetType init(void)
+RetType Schedule(const float& _fTime)
+RetType Update(void)
+RetType Render(void)
-CSceneNode* m_pObjParent;
0..*
CScene
-vector<CLayer*> m_vecLayer;
+RetType init(void)
+RetType Schedule(const float& _fTime)
+RetType Update(void)
+RetType Render(void)
CGameObject
CLayer
0..*
+list<CGameObject*> m_ObjList;
+RetType init(void)
+RetType Schedule(const float& _fTime)
+RetType Update(void)
+RetType Render(void)
0..*
+list<CSceneNode*> m_ChildList
+vector<CComponent*> m_vecCom
+RetType init(void)
+RetType Schedule(const float& _fTime)
+RetType Update(void)
+RetType Render(void)
0..*
1-1. 새로운 렌더링 프레임워크
렌더타겟 매니저를 렌더타겟을 관리 및 멀티렌더 타겟을 운용한다.
렌더링 기술들을 클래스로 캡슐화 시켜서 인터페이스만 제공하여 코드를 간결하게 만드는데 주력.
내가 맡은 것은 범프 매핑과 HDR로 동작과 내용을 클래스화 시켜 언제든지 끄고 켜는것이 가능하
도록 했다.
2. DIRECTX9.0 3D기술과 HLSL
각 렌더타겟 생성(C++)
렌더타겟 매니저(C++)
1. 현재 사용할 수 있는 그래픽 디바이스에서는
4개의 타겟 을 사용할 수가 있다. (메모리가 허
용하는 한 몇 개의 타겟 이든 만들 수 있지만 동
시에 사용할 수 있는 타겟은 4개이다.)
(한번에 사용 가능한 타겟의 개수는 장치 포인
터를 만들 때 얻을 수 있는 D3DCAPS9 구조체
의 NumSimultaneousRTs에서 얻어온다.)
1. 디퍼드 렌더링을 위한 G버퍼를 만들고 관리하
기 위한 멀티렌더 타겟클래스를 만든다.
2. 디퍼드 렌더링에 사용할 Diffuse, Position,
Normal, Depth 개의 타겟을 생성한다.
02
그래픽 기술 (디퍼드 렌더링)
디퍼드 렌더링 쉐이더(HLSL)
1. 범프 매핑을 사용하므로 최종 노말 값은 범프매
핑의 노말값이 되어야 한다.
애니메이션 메쉬의 경우 바이노말과 탄젠트도
스키닝을 해줘야 한다.
1. 4개의 G버퍼에 조명처리를 하기 위에 필요한
값을 저장한다.
02
그래픽 기술 (HDR 렌더링)
디퍼드 렌더링 결과
02
그래픽 기술 (HDR 렌더링)
HDR
HDR CLASS(C++)
1. HDR 구현에 있어 선행적으로 선형공간과 감마
공간에 대해서 이해 해야 한다.
2. 간략히 요약하자면 우리가 보고 있는 컴퓨터 화
면은 이미 감마가 적용되어있는 상태의 화면이
라는 것이다.
감마가 적용됐다는 것은 색상에 감마공간의 색
상으로 표현된다는 것이고 이것을
pow(color,2.2) 로 연산해 색상공간을 보정해
줘야 한다.
3. 메쉬를 추출할 때 함께 추출된 텍스처는 이미
감마공간이다.
02
그래픽 기술 (HDR 렌더링)
HDR CLASS FUNCTION(C++)
1. 디퍼드 렌더링 이후 라이팅타겟 만을 축
소한 후 다운스케일타겟에 복사한다.
2. 복사한 타겟은 이후 이후 평균 휘도를 구
할. 평균 휘도를 위한 톤맵 등에 이용되며
HDR 클래스의 함수들을 거쳐서 최종 타
겟에 출력하여 화면을 렌더링 한다.
02
그래픽 기술 (HDR 렌더링)
디퍼드 렌더링 후 HDR 결과
3. 플레이어 & 애니메이션제어
1. 스킬의 액션이나 일반공격의 액션을 담아
둔다.
2. 하나하나의 동작을 액션이라는 클래스를
통해서 관리한다.
CPlayerMotion
2. 스킬이나 액션 그 자체의 능력치를 종합
해 놓는 클래스.
-CAnimationGeometry* m_pAnimationGeometry
-CMainPlayerScript* m_pParentScript
-vector<CAction*> m_vecBaseAction
-vector<CAction*> m_vecSkillAction
-CPlayerSkill* m_pPlayerSkill
+RetType CPlayerMotion(): :Progress(const float& _fTime)
CMainPlayerScript
1..*
CPlayerSkill
-CPlayerMotion* m_ArrMotion|MAINCHARATER_STATE_MAX|
-CPlayerItem*m_pPlayerItem;
-CPlayerSkill*m_pPlayerSkill
+int init(void)
+int Schedule(const float& _fTime)
+int Update(void)
+int Render(void)
1
1
3. 플레이어가 장비하고 있는 아이템들과 아
이템들의 기능과 능력치를 가지고 있는
클래스.
-TSKILLMOTION m_QuickMtion|QUICK_SKILL_MAX|
-TSKILLMOTION m_WindowMtion|SKILL_BOOK_MAX|
CPlayerItem
-tItem m_ArrEquipItem|EQUIP_TYPE_MAX|
-tItem m_ArrItemQuickSlot|QUICK_ITEM_MAX|
-tItem m_ArrInvenItem|INVEN_MAX|
3. 플레이어 & 애니메이션제어
CMainPlayerScript
-CPlayerMotion* m_ArrMotion|MAINCHARATER_STATE_MAX|
1. CPlayerMotion 클래스는 동작 하나하나를
클래스와 시킨 CAction 클래스를 포함한
다. 이를 배열로 놓은 이유는 마을에서 할
수 있는 액션들과 전투시에 사용할 액션
들이 다르기 때문에 마을에서는 사용하지
도 않을 액션들을 막는다.
+int init(void)
+int Schedule(const float& _fTime)
+int Update(void)
+int Render(void)
1..*
CPlayerMotion
-CAnimationGeometry* m_pAnimationGeometry
-CMainPlayerScript* m_pParentScript
-vector<CAction*> m_vecBaseAction
-vector<CAction*> m_vecSkillAction
-CPlayerSkill* m_pPlayerSkill
+RetType CPlayerMotion(): :Progress(const float& _fTime)
2. 다형성을 이용하여 스킬 모션과 일반 공격
모션은 CAction이라는 공통의 부모를 사용
하여 만들어 진다.
하지만 관리는 STL Vector를 통해서 따로
관리를 받는다.
3. 플레이어 & 애니메이션제어
1. 실제 애니메이션은 모두 각 데이
터파일에서 읽어들인 데이터들로
관리한다.
기본공격 실행코드
1. STL Vector에 저장되어 있는 액션들은
m_iCurAction에 의해서 어떤 액션이 실행
되며 m_iCurAction은 각 액션들에서 변경
하여 동작들이 연결되는 것처럼 실행한다.
모션 실행코드
3. 플레이어 & 애니메이션제어
1. 타격 박스가 OFF 일 때는 타격 박스의 색
깔은 하얗다. 캐릭터가 검을 들고만 다녀
도 충돌이 일어나는 경우를 방지한다.
타격 BOX OFF
타격 BOX ON
2. 타격 박스가 ON 일 때는 타격 박스의 색
깔은 붉다. 이 순간에는 검이 닿는 범위의
적들에게 타격을 가한다.
4. 툴을 C#으로 만든다.
1. C#을 이용해서 만든 엑셀데이터 컨버전
툴을 이용해서 데이터 파일로 만들고 각
캐릭터 별 데이터를 통해서 모션과 기술
들을 발동시킨다.
모션 데이터
4-1 EXTRA. 언어의 차이
-> 본시 프로젝트에서 맡은 업무가 C#은 아니었지만 실제 툴을 제작하는 팀이 C#으로 툴을 만들게 되어서
C#에 대해서 공부하는 계기가 되었다.
-> 일단 생산성이나 기본적인 지원부분에서 C#은 C++보다 상당히 쉬웠지만 툴 제작자들이 C#으로
DIRECTX를 사용하지 못해서 결국 툴에는 쉐이더기술이 적용되지 못했다.
-> 또한 저장시 데이터 포맷이 원할하지 않아서 초반에 많은 문제가 있었지만 참가자로서 직접
Marshalling 기법을 사용해서 해결했다.
EXTRA. 아쉬운 점
1. 컴포넌트 구조 잘 사용하고 계십니까?
뭐든지 시작은 어렵다지만 컴포넌트 구조를 처음 적용해서 사용하는 것은 처음에는 정말
고역이었다. 하지만 나에게는 정말 마음에 드는 작업이었다. 내가 잘 사용하지 못했다는 것이
문제다.
2. C#에서 DIRECTX를 사용하지 못한 것.
처음부터 툴 팀에 들어있던 것은 아니지만 C++로 제작되는 클라이언트 서버 & C#으로 제
작되는 툴이라는 구조로 프로젝트가 진행되었다. 하지만 결국 C#으로 제작되는 툴에서는
DIREXTX를 사용하지 못했다는 점이 끝내 아쉽다.
3. 서버가 전투까지 구현되지 못한점.
마찬가지로 서버팀은 아니었지만 거래와 채팅만 완성 됐을 뿐 전투에서까지 서버를 통한
플레이가 만들어지지 못한 점은 너무나도 아쉽다.
EXTRA. 얻은점
1. 컴포넌트 구조가 좋아요.
2. 정신적으로 성장하는 계기.
3. 무언가를 만들겠다면 원본을 상상해라.
4. 뭐든지 할 수 있다.
시기
프로그래밍 11개월 차
기한
5일
장르
디펜스 모작
06
2D JAVA ANDROID
프로젝트 이슈
1.
자바와 안드로이드의 시작하다.
2.
자바에서 해보는 컴포넌트 구조.
3.
라인으로 뭐든지 만들어라.
1. 자바와 안드로이드의 시작하다.
-> 자바 프로젝트 그 중에서는 자바 기초를 때고 바로 안드로이드로 넘어갔다.
-> 역시나 처음 시작하는데 가장 어려운 점은 환경조성.
-> 안드로이드 SDK와 그 이외 개발환경을 조성하는데 오히려 더 많은 시간이 걸렸다.
-> 또한 이왕 JAVA를 사용하는 거 JAVA와 관련된 GUI시스템을 알아보다 스윙을 사용하기로 했다.
-> 최초 만들어 보기로 생각한 게임은 센터 디펜스 이다.
1.
플레이어의 기체는 화면 중앙에서 조금도 움직일 수 없다.
2.
적들은 화면의 곳곳에서 등장하며 플레이어는 중앙에서 포대를 돌려서 등장하는 적들을 요격해야 한다.
3.
이때 등장하는 모든 몬스터와 탄환은 선으로 그린다.
4.
이때 포대를 돌리기 위해서는 핸드폰을 기울이는 자이로스코프센서를 이용했다.
2. 자바에서 해보는 컴포넌트 구조.
4. 실제 컴포넌트를 가지고 있고 그것을 실행
하기 위한 게임오브젝트.
3. 오브젝트를 모아놓고 관리하는 ObjectPack
클래스 안에 실제 이터레이터패턴으로 실행
될 오브젝트들을 담아둔다.
2. 오브젝트들을 관리하는 오브젝트Pack들을
관리하는 클래스 Scene은 시작 할때 로딩을
위해서 각기 SceneStarter클래스를 필요로 한
다.
1. 게임 루프 쓰레드 안에서 실제 Scene의 실
제 함수들이 실행된다.
2-1. 컴포넌트를 분류해 보았다.
1. 실험적으로 실제 크게 역할이 나뉜다고 생각하는 컴포넌트들을 상속구조로 분리했다.
-> 실제로는 그저 데이터의 크기가 커지는 결과가 되었다. 그냥 하나의 컴포넌트를 역할에 따라서 실행해야 할지도
모르겠다.
2. 게임오브젝트로서 자신과 같은 게임오브젝트를 가질 수 있다.
-> 부모오브젝트의 움직임을 따라가는 방식을 따를지 아닌지를 결정하는 ChildMoveType라는 변수를 넣었
지만 실제로는 사용하지 않았다.
3. 검색을 할 때는 HashMap을 사용하고 실제 루프를 돌며 실행을 할때는 ArrayList를 사용하는 방법을 생각
했지만 역시나 메모리는 증가로 이어졌다고 본다.
3. 라인으로 뭐든지 만들어라.
JAVA SWING으로 만들어본 툴
1. 적이나 플레이어들을 라인으로 구성하기로
했는데 플레이어들은 LineRenderer라는 클래
스에서 구성하며 LineData라는 클래스 안에서
Figure라는 도형하나의 클래스로 구성되어 있
다.
2. Figure 클래스는 JavaVector2라는 점을 표
현하기 위한 클래스들로 구성되어 있다.
3. 점의 수정 및 삭제, 도형의 수정 및 삭제 기
능들을 구성했다.
3-1 EXTRA. 회전하고 총을 쏜다.
1. 포탄과 적의 충돌은 원 충돌을 사용했다.
2. 점의 회전공식을 이용해서 몬스터와 포탑
등 모든 객체들의 렌더링 한다.
3. 간단한 GUI기능을 구현해보기 위해서 버튼
박스를 렌더링 하고 터치시 좌우로 추가 포대
가 설치되도록 만들었다.
에뮬레이터에서는 글자가 깨진다는 것을 깨
달았다.
EXTRA. 아쉬운 점
1. 더 많은 컨텐츠.
물론 기한을 일주일로 잡고 처음 하는 자바와 안드로이드라고 하더라도 이미 C++의 경험
자로서 다양한 총알이나 여러 몬스터들의 패턴들을 제대로 많이 구현하지 못한 점이 아쉽다.
EXTRA. 얻은점
1. JAVA & ANDROID 프로그래밍의 감.
2. 툴은 언제나 쓸모 있다.
3. 언어의 차이와 각 언어의 지향점에 대해서 고민하는 계기.
시기
프로그래밍 14개월 차
기한
4개월(현재 2개월)
장르
오리지널 RPG
07
UNITY 3D
현재 진행 중 입니다.