Win32 API/기초

Win32 API 기초 : Collider (2)

시플마 2024. 7. 27. 17:17

Collider의 위치를 설정하기 위해

멤버 m_vPosOffset과 m_vFinalPos를 두었고

 

크기를 설정하기 위해 멤버 m_vColliderSize를 두었습니다.

해당 멤버는 SetColliderSize 멤버 함수를 통해 설정합니다.

 

 

m_vPosOffset은 Collider가 오브젝트의 위칫값으로부터

얼마나 떨어져 있는지를 나타내기 위한 멤버입니다.

 

 

18번째 줄에 있는 finalupdate 함수는

Collider가 오브젝트를 따라다닐 수 있도록

위치를 설정해 줍니다.

 

finalupdate 함수의 정의를 보면

 

Collider가 어떤 오브젝트에 달려 있는지

멤버 m_pOwner에 저장했었죠? 

해당 오브젝트의 위칫값을 GetPos 함수를 통해 얻어

지역 변수 ObjectPos에 대입합니다.

 

그리고 Collider에 오브젝트의 위칫값과

해당 오브젝트의 위칫값으로부터 얼마나

떨어져 있을지에 대한 정보를 저장하고 있는

m_vPosOffset을 더해 m_vFinalPos에 최종적으로

저장합니다. 해당 멤버에 저장된 위칫값이

Collider가 있을 최종 위치입니다.

 

 


 

 

 

프로그램을 만드는 중에 Collider의 범위가

눈으로 보이면 조금 더 만드는 게 수월하겠죠.

 

실제 프로그램이 완성되면 Collider의 범위가

보일 필요가 없지만요.

 

이를 위해  Collider 객체는

 

render 멤버 함수를 갖고 있습니다.

 

Collider는 Collider의 위칫값과 크기를 고려하여

사각형으로 구현되게 하였습니다.

 

이를 윈도우 창에 띄우려면

펜과 브러쉬를 만들고 이를 사용해

DC에 그려내야 하는 것이죠.

 

이때 다른 객체에 펜과 브러쉬의 정보를 미리

저장하였다가 펜과 브러쉬의 사용이 끝나 소멸되면

다른 객체에 저장한 정보를 통해 펜과 브러쉬를

다시 선택해 주어야 하죠.

 

이 복잡한 과정은 CSelectGDI 클래스를 만들고

이 클래스로 만든 객체를 통해 수행하도록 하겠습니다.

 

 

그 전에 코어 객체가 자주 사용하는 펜과 브러쉬는

아예 처음부터 갖고 있도록 하겠습니다.

 

우선 펜과 브러쉬 관련하여 enum class를 만듭니다.

 

펜의 종류로 Red, Blue, Green가 있으며

브러쉬의 종류로는 Hollow가 있습니다.

 

Hollow는 가운데를 색으로

채우지 않고 공백으로 두는 겁니다.

 

Collider의 범위만 눈에 보이면 되므로

Collider의 테두리만 그려주는 것이죠.

 

 

그리고 CCore 헤더 파일로 가서

 

펜과 브러쉬를 배열로 저장하는

두 개의 멤버를 만들어 줍니다.

 

멤버가 private로 선언되었기 때문에

 

Get 함수를 구현하여 다른 곳에서 불러올 수 있도록 하겠습니다.

 

 

그리고 CCore 소스 파일로 가서

 

코어 객체가 init 함수를 통해 초기화를 진행할 때

CreatePen 함수를 통해 자주 쓰게 될 펜과 브러쉬들을 생성해 줍니다.

 

Hollow 브러쉬는 만들 필요 없이 GetStockObject 함수를

통해 Hollow 브러쉬를 직접 얻어서 사용할 수 있습니다.

 

윈도우에서도 Hollow 브러쉬는 자주 쓸 것이라 판단하고

함수로 간단하게 얻어서 사용할 수 있도록 한 것이죠.

 

 

이제 CSelectGDI 클래스의 헤더 파일을 보시죠.

 

DC를 저장할 멤버 m_dc와, 

펜이 사용 후 소멸되기 전에 따로 저장하여 

펜이 소멸되면 다시 펜을 선택할 수 있도록

그 펜을 멤버 m_hDefaultPen에 저장합니다.

 

멤버 m_hDefaultBrush도 마찬가지입니다.

 

 

그리고 CSelectGDI 클래스의 생성자를 

두 개로 두었죠.

 

하나는 펜을 생성하고 선택하는 생성자이고

또 하나는 브러쉬를 생성하고 선택하기 위한

생성자입니다. 인자에 따라 다르게 동작하는

같은 이름의 함수( 생성자 )를 오버로딩한 것이죠.

 

 

먼저 펜을 위한 생성자를 보면

 

CSelectGDI  클래스의 객체가 생성될 때 인자로

넣은 펜의 색상과 일치하는, 코어 객체가 갖고 있는 펜을

GetPen 함수를 통해 얻어 옵니다.

 

그리고 지역 변수 hPen에 저장합니다.

 

그리고 SelectObject 함수를 통해 

hPen을 선택하고 이를 미리 m_hDefaultPen에

저장합니다.

 

 

브러쉬를 위한 생성자도 똑같이 동작합니다.

 

 

이후 Collider의 render 함수의 동작이 완료되어

윈도우 창에 Collider의 범위가 그려지면

펜과 브러쉬는 소멸되겠죠.

 

즉 CSelectGDI  클래스의 객체도 소멸될 겁니다.

 

그럼 이때 소멸자가 호출되면

m_hDefaultPen에 저장된 펜과 

m_hDefaultBrush에 저장된 브러쉬를

선택하도록 합니다.

 

 


 

 

Collider의 render 함수에서

RED 펜을 갖고 있는 객체 p와

 

HOLLOW 브러쉬를 갖고 있는 

객체 b를 만들었으니 Rectangle 함수를 통해

빨간 테두리에 가운데가 뚫린 Collider의 범위가

윈도우 창에 표현될 겁니다.

 

 

 


 

 

 

CPlayer는 Collider를 갖고 있을 겁니다.

 

그래서 플레이어 객체가 생성될 때

GetCollider 함수를 통해 Collider를 가져오고

그 Collider의 크기를 SetColliderSize 함수를 통해

설정해 줍니다.

 

 

Collider는 CObject 클래스에서

멤버 m_pCollider로 관리하고 있습니다.

 

그래서 GetCollider 함수도 CObject 클래스에 있습니다.

 

모든 오브젝트는 CObject 클래스로부터 파생된

클래스를 통해 만들어집니다. 따라서 Collider가

존재하는 것은 아니지만 일단 모든 오브젝트는

Collider를 저장하는 멤버를 갖고 있죠.

 

 

27번째 줄을 보시면 component_render 함수가 있습니다.

 

CObject 클래스의 소스 파일에서 확인해 보니

오브젝트의 멤버 m_pCollider가 nullptr이 아니면,

즉 Collider를 갖고 있는 객체라면

해당 Collider의 render 함수를 호출합니다.

 

충돌 범위를 갖고 있는 오브젝트라면

윈도우 창에서 그 범위를 눈으로

확인할 수 있도록 하는 것이죠.

 

 

component_render 함수는 

render 함수가 호출될 때마다 실행됩니다.

즉 윈도우 창에 오브젝트가 그려질 때마다

같이 호출되는 것이죠. 

 

이때 오브젝트가 Collider를

보유하고 있는지, 그렇지 않은지에 따라

component_render 함수가 동작할 수도,

동작하지 않을 수도 있는 것입니다.

 

 


강의 출처 : https://www.youtube.com/watch?v=As-EL_jee5Q&list=PL4SIC1d_ab-ZLg4TvAO5R4nqlJTyJXsPK&index=26