24/03/25
34화. Win32API Scene (1)
화면전환 :
현재 Start_Scene 만 화면에서 다루고 있는데 게임을 구현할땐, 여러 Scene을 자유롭게 전환할 수 있어야한다.
때문에 해당 기능을 구현 해본다.
Scene 을 변경해주는 기능은 Scene을 관리하는 SceneMgr 클래스에서 수행해줘야한다.
CScene::update() 함수는 Scene이 관리하는 Object 객체들의 update() 함수를 호출해주는 작업을 담당하기에 virtual 키워드를 붙이지 않았었다.
하지만 화면전환 관련으로 Scene의 자식객체들이 updata() 중 추가적으로 구현해야하는 기능이 추가되었기에 CScene::update() 함수를 가상함수로 전환한다.
가상함수로 전환했지만, 기본적으로 Scene이 관리하는 객체들의 update() 함수를 호출해주는 작업은 계속 수행해야하기에 자식객체들이 override 한 update() 함수안에서 부모객체인 CScene 클래스의 update() 함수를 호출해준다.
화면전환 구현 :
Enter 키 입력을 받으면 Start_Scene에서 Tool_Scene으로 변경되도록 구현해볼 예정
ChangeScene() 함수에서 아래와 같이 씬 매니저가 가지고 있는 현재 씬을 가리키는 멤버 변수(m_pCurScene)의 주소값만 변경하면 되는가?
이렇게 간단하게 구현되면 좋겠지만 이렇게 화면전환을 하게되면 문제가 발생할 수 있다.
키 입력을 받자마자 바로 Scene을 변경하게되면 해당 프레임의 모든 작업을 종료하지 않고 갑작스럽게 화면전환이 되면서 객체등의 데이터갱신(update) 와 렌더링 모두에 영향이 가게된다.
- 모든 객체들을 갱신하지 못한체 갑작스레 화면전환이 됨으로 인해 프레임 동기화 처리가 되지 않는다.
- 데이터 갱신은 A _Scene에서 했는데 출력되는 화면은 B_Scene인 이상한 상황이 발생할 수 있다.
- Scene에 진입, 탈출 할때 호출되는 Enter(), Exit() 함수의 작업이 완료되지 못한다.
이러한 이유 때문에 화면전환 역시 이벤트 등록을 하여 지연처리를 통해 이루어져야한다.
이벤트 등록을 통한 화면전환이 이루어져야 하기에 func.h 파일에 화면전환 이벤트 함수(ChagneScene)을 만들어주다.
이후, EventMgr의 update() 함수에서 이벤트 처리를 해줄때, 기존에 만들어두었던 SceneMgr의 ChangeScene() 함수를 호출해준다.
프레임 동기화를 위해 "이벤트 처리(지연처리)"를 통해 SceneMgr 클래스의 ChangeScene() 함수를 호출해줬다.
이는 CSceneMgr::ChangeScene() 함수가 아무나 호출할 수 있는 함수가 아니라는 의미다.
때문에 private 로 선언하고 EventMgr 클래스를 friend 선언해준다. (EventMgr 를 통해서만 호출 가능)
함수 템플릿화 (Safe_Delete_Vec) :
vector에 들어있는 원소들의 메모리 해제와 vector를 비우는 작업은 많이 반복되고 정형화된 작업이다.
때문에 이런 정형화된 반복작업들은 간단히 템플릿 함수화 하여 함수호출 한번으로 처리되도록 하면 편하다.
호출할때 정확하게는 T가 어떤 타입을 의미하는지 명시해줘야하지만, 적어주지 않아도 컴파일러가 유추해준다.
템플릿 함수는 그 자체만으로는 함수가아니다.
요청된 T에 대한 타입이 정의되어야지만, 호출되어 해당 정보를 기반으로 함수를 만들어주는 "함수 생성기"다.
이 차이를 명확히 짚고 넘어가야한다.
35화. Win32API Object (1)
Object 보완 :
Object 클래스 생성시 미흡했던 부분을 보완한다.
만약 오브젝틀를 복사한다면...? :
충돌체 멤버 변수의 경우 주소타입 이기에 기본 복사생성자로 복사를 하게되면, 사본 객체가 원본객체의 충돌체를 가리키게된다.
완벽한 사본이라면 같은 기능은 하되 자신만의 충돌체를 가지고 있어야한다. ("깊은복사")
m_bAlive 의 경우도 원본의 값을 복사하는건 의미가 없다. 만약 원본의 상태가 Dead 상태여서 사본도 Dead로 복사한다고 한들 EventMgr 에 의해서 Dead 상태가 된 것이 아니기에 삭제되지도 않는다.
때문에 복사 생성자를 직접 정의해줘야한다. -> Collider 생성, 상태값 ALIVE 설정
Player 를 복사한다면...? :
Player 객체도 포인터 타입 객체를 가지고 있긴 하지만 Texture 는 리소스 타입으로 엔진에서 공유하여 사용하는 타입이다.
때문에 사본 객체가 원본객체의 리소스를 같이 가리키고 있어도 문제될 것이 없다.
때문에 복사생성자를 정의 해주더라도 해당 값에 대한 작업은 해줄필요없다.
복사 생성자 간편하게 호출 (Clone) :
복사 생성자가 성공적으로 호출되어 원본과 같은 기능과 자신만의 충돌체를 가진 사본 객체가 생성되었다.
하지만, 복사 생성자의 호출이 불편함 감이 없잖아 있다.
CObject* pOtherPlayer = new CPlayer(*(CPlayer*)pPlayer);
때문에 Object 클래스에 Clone() 이라는 순수 가상 함수를 만들어 자식 객체들이 자신의 사본을 만들어 반환해주는 함수를 생성하도록 강제성을 부여해준다.
Clone() 힘수를 순수 가상함수로 선언했기에 CObject 를 상속하는 자식 객체들 (Monster, Player, Missile) 은 모두 Clone() 함수를 구현해야한다.
Clone() 함수 메크로(Clone -> CLONE) :
Clone() 함수는 Object 클래스를 상속하는 모든 자식 객체들이 구현해야하는 함수이며, 형식이 정형화 되어 있기 때문에 메크로 설정을 해준다.
Player, Monster, Missile 클래스 Clone() 함수 메크로 전환 :
Next Note
Win32API_StudyNote_8
24/03/25 36화. Win32API Animation (1)
coder-qussong.tistory.com
'Win32API' 카테고리의 다른 글
Win32API_StudyNote_9 (0) | 2024.03.28 |
---|---|
Win32API_StudyNote_8 (0) | 2024.03.25 |
Win32API_StudyNote_6 (0) | 2024.03.24 |
Win32API_StudyNote_5 (0) | 2024.03.22 |
Win32API_StudyNote_4 (0) | 2024.03.21 |