* Scene 클래스는 모든 개별 클래스의 최상위 부모 클래스이다.
* 생성자와 소멸자를 protected로 선언하고, SceneManager만 frend class로 등록하여 SceneManager를 통해서만 처리할 수 있게 만들어 준다.
class CScene
{
friend class CSceneManager;
protected:
CScene();
virtual ~CScene();
* 해당 씬에서 생성된 GameObject의 주소를 모두 담아놓을 list를 전방 선언한다.
일반 포인터 변수가 아닌 공유 포인터 클래스로 선언하여 메모리 릭을 방지해 준다.
protected:
std::list<CSharedPtr<class CGameObject>> m_ObjList;
* GameObject를 생성하는 데 사용되는 템플릿 함수 CreateObject를 선언 및 정의한다.
이 함수는 상속받은 개별 씬의 Init 함수에서 사용될 함수이다.
ex)MainScene 함수에서 Player 객체를 생성해야 한다면
CreateObject<Player>("Player");
public:
//기본값으로 "GameObject"를 받고,
//필요할 때 원하는 오브젝트의 이름을 넣어서 생성해 주는 함수.
template <typename T>
T* CreateObject(const std::string& Name = "GameObject")
{
T* Obj = new T;
Obj->SetName(Name);
if (!Obj->Init())
{
SAFE_RELEASE(Obj);
return nullptr;
}
//혹시나 생성된 T*를 삽입하는데 에러가 발생할 수도 있으므로
//업캐스팅 하여 리스트에 넣어준다.
m_ObjList.push_back((CGameObject*)Obj);
return Obj;
}
* Update(), Render() 함수의 구조는 기본적으로 동일하다.
생성된 GameObject의 주소를 담은 list를 iterator로 순회하며 개별 오브젝트의 Update(), Render()함수를 호출한다.
void CScene::Update(float DeltaTime)
{
std::list<CSharedPtr<class CGameObject>>::iterator iter = m_ObjList.begin();
std::list<CSharedPtr<class CGameObject>>::iterator iterEnd = m_ObjList.end();
while (iter != iterEnd)
{
//Active == false -> 해당 게임오브젝트를 제거하겠다
if (!(*iter)->GetActive())
{
//리스트에서 제거하는 순간 SharedPtr의 소멸자가 호출되어
//카운트가 감소한다,.
iter = m_ObjList.erase(iter);
//cf)stl::List 특성 상 erase()를 호출하면 end 노드가 바뀔 수 있으므로
//삭제를 하면 무조건 다시 받아와야 한다.
iterEnd = m_ObjList.end();
continue;
}
//Enable == false -> 해당 게임오브젝트는 현재 활성화되어있지 않다.
//업데이트, 렌더링 하지 않고 스킵.
else if (!(*iter)->GetEnable())
{
++iter;
continue;
}
(*iter)->Update(DeltaTime);
++iter;
}
}
< 코드 원본 >
//Class CScene
//Scene.h
#pragma once
#include "../GameInfo.h"
class CScene
{
//아무나 선언 못하게 하고, SceneManager 클래스를 통해서만 처리할 수 있게 만들어 줄 것이다.
friend class CSceneManager;
//앞으로는 클래스 생성을 아무데서나 할 수 없게 제한적으로 해 줄 예정.
//왜냐하면 나중에 여러명이서 만드는 프로젝트가 되게 되면
//서로 각자가 설계한 클래스끼리 꼬이거나
//서로 사용법을 잘 몰라서 클래스를 뒤죽박죽 생성할 수도 있기 때문.
//그러므로 클래스는 최대한 좁은 통로로 생성할수 있게끔 해서
//정해진 방식대로 쓸 수 있게 유도해야 한다.
//다른 사람이 쓸 떄도 편하게 쓸 수 있도록 설계
//씬에 내가 원하는 오브젝트를 만들어서 집어넣어 줌
protected:
CScene();
virtual ~CScene();
//게임오브젝트를 넣어놓을 리스트
//CShardPtr의 T타입에 CGameObject를 넣어줌.
//CShardPtr은 T* m_Ptr이라는 멤버 변수를 가지고 있음.
//->CGqmeObject* m_Ptr이 됨.
//CGameObject 클래스를 담고 있는 CsharedPtr,
//CSharedPtr은 해당 CGameObject의 주소를 가지고 있다.(포인터 역할)
//해당 CSharedPtr 목록을 가지고 있는 리스트
std::list<CSharedPtr<class CGameObject>> m_ObjList;
public:
bool Init();
void Update(float DeltaTime);
void Render(HDC hDC, float DeltaTime);
public:
//기본값으로 "GameObject"를 받고,
//필요할 때 원하는 오브젝트의 이름을 넣어서 생성해 주는 함수.
template <typename T>
T* CreateObject(const std::string& Name = "GameObject")
{
T* Obj = new T;
Obj->SetName(Name);
if (!Obj->Init())
{
SAFE_RELEASE(Obj);
return nullptr;
}
//혹시나 생성된 T*를 삽입하는데 에러가 발생할 수도 있으므로
//업캐스팅 하여 리스트에 넣어준다.
m_ObjList.push_back((CGameObject*)Obj);
return Obj;
}
};
//Class CScene
//Scene.cpp
#include "Scene.h"
#include "../GameObject/GameObject.h"
CScene::CScene()
{
}
CScene::~CScene()
{
}
bool CScene::Init()
{
return true;
}
void CScene::Update(float DeltaTime)
{
std::list<CSharedPtr<class CGameObject>>::iterator iter = m_ObjList.begin();
std::list<CSharedPtr<class CGameObject>>::iterator iterEnd = m_ObjList.end();
//cf) iterator의 타입을 자동으로 잡아주는 연산자가 존재
//auto: 선언과 동시에 무조건 대입을 해주어야 한다.
//대입된 타입으로 타입이 선언된다.
//하지만 아직 연습 단계이므로 직접 타입을 잡아 주자.
//auto iter = m_ObjList.begin();
while (iter != iterEnd)
{
//Active == false -> 해당 게임오브젝트를 제거하겠다
if (!(*iter)->GetActive())
{
//리스트에서 제거하는 순간 SharedPtr의 소멸자가 호출되어
//카운트가 감소한다,.
iter = m_ObjList.erase(iter);
//cf)stl::List 특성 상 erase()를 호출하면 end 노드가 바뀔 수 있으므로
//삭제를 하면 무조건 다시 받아와야 한다.
iterEnd = m_ObjList.end();
continue;
}
//Enable == false -> 해당 게임오브젝트는 현재 활성화되어있지 않다.
//업데이트, 렌더링 하지 않고 스킵.
else if (!(*iter)->GetEnable())
{
++iter;
continue;
}
(*iter)->Update(DeltaTime);
++iter;
}
}
void CScene::Render(HDC hDC, float DeltaTime)
{
//Update()와 똑같은 과정 반복.
std::list<CSharedPtr<class CGameObject>>::iterator iter = m_ObjList.begin();
std::list<CSharedPtr<class CGameObject>>::iterator iterEnd = m_ObjList.end();
while (iter != iterEnd)
{
//Active == false -> 해당 게임오브젝트를 제거하겠다
if (!(*iter)->GetActive())
{
//리스트에서 제거하는 순간 SharedPtr의 소멸자가 호출되어
//카운트가 감소한다,.
iter = m_ObjList.erase(iter);
//cf)stl::List 특성 상 erase()를 호출하면 end 노드가 바뀔 수 있으므로
//삭제를 하면 무조건 다시 받아와야 한다.
iterEnd = m_ObjList.end();
continue;
}
//Enable == false -> 해당 게임오브젝트는 현재 활성화되어있지 않다.
//업데이트, 렌더링 하지 않고 스킵.
else if (!(*iter)->GetEnable())
{
++iter;
continue;
}
(*iter)->Render(hDC, DeltaTime);
++iter;
}
}
'WIN32API FrameWork > 원본' 카테고리의 다른 글
220509_WIN32API_6-1_총알 발사 - 총알 클래스 구현 (0) | 2022.05.12 |
---|---|
220504_WIN32API_Framework_5-3_실제 Scene 만들고 실행(MainScene) (0) | 2022.05.08 |
220504_WIN32API_Framework_5-1_SceneManager (0) | 2022.05.08 |
220504_WIN32API_Framework_4_스마트 포인터(참조 카운트) (0) | 2022.05.06 |
220503_WIN32API_3-3_조작에 따라 회전하는 총 만들기(삼각함수) (0) | 2022.05.05 |