카메라는 컴포넌트 기반으로 만들어져 객체(Actor)에 부착되며, 해당 객체의 위치를 기준으로 씬(Scene)을 렌더링합니다.
카메라는 Component 클래스를 상속받아 구현되며, 이 컴포넌트는 Actor의 일부로 추가됩니다.
class CameraComponent : public Component
{
public:
CameraComponent();
virtual ~CameraComponent() override;
virtual void BeginPlay() override;
virtual void TickComponent() override;
virtual void Render(HDC hdc) override;
};
CameraComponent: 카메라의 역할을 수행하는 클래스.Component: 모든 컴포넌트의 기본 클래스.CameraComponent: Component를 상속받아, 카메라 기능을 수행.CameraComponent::CameraComponent() {}
CameraComponent::~CameraComponent() {}
void CameraComponent::TickComponent()
{
if (_owner == nullptr)
return;
Vec2 pos = _owner->GetPos();
// TEMP: 카메라 위치 제한 설정
pos.x = ::clamp(pos.x, 400.f, 3024.f - 400.f);
pos.y = ::clamp(pos.y, 300.f, 2064.f - 300.f);
GET_SINGLE(SceneManager)->SetCameraPos(pos);
}
_owner: 이 컴포넌트를 소유한 Actor를 참조. GetPos(): Actor의 현재 위치를 가져옵니다.clamp: 화면 경계 밖으로 카메라가 이동하지 않도록 제한.SetCameraPos: 씬 매니저(SceneManager)에 현재 카메라 위치를 업데이트.class SceneManager
{
public:
Vec2 GetCameraPos() { return _cameraPos; }
void SetCameraPos(Vec2 pos) { _cameraPos = pos; }
private:
Vec2 _cameraPos = { 400, 300 }; // 카메라 초기 위치
};
GetCameraPos: 현재 카메라 위치를 반환.SetCameraPos: 카메라 위치를 설정.CameraComponent에서 카메라 위치를 계산하고 SceneManager로 전달.SceneManager는 이 위치를 기반으로 씬의 렌더링을 조정.Player::Player()
{
_flipbookUp = GET_SINGLE(ResourceManager)->GetFlipbook(L"FB_MoveUp");
_flipbookDown = GET_SINGLE(ResourceManager)->GetFlipbook(L"FB_MoveDown");
_flipbookLeft = GET_SINGLE(ResourceManager)->GetFlipbook(L"FB_MoveLeft");
_flipbookRight = GET_SINGLE(ResourceManager)->GetFlipbook(L"FB_MoveRight");
// 플레이어에 카메라 컴포넌트 추가
CameraComponent* camera = new CameraComponent();
AddComponent(camera);
}
Player) 생성 시 카메라 컴포넌트를 추가.AddComponent: 컴포넌트를 Actor에 추가하는 함수.void Actor::AddComponent(Component* component)
{
if (component == nullptr)
return;
component->SetOwner(this); // 컴포넌트에 소유주(Actor) 설정
_components.push_back(component); // 컴포넌트를 벡터에 추가
}
void Actor::Render(HDC hdc)
{
for (Component* component : _components)
{
component->Render(hdc);
}
}
Actor가 가진 모든 컴포넌트의 Render 메서드를 호출.CameraComponent는 렌더링 기능을 가지지만 현재 구현에서는 빈 상태.카메라 위치에 따라 플레이어와 배경의 렌더링 위치를 조정하여, 카메라가 이동할 때 화면 중앙이 적절히 업데이트되도록 처리.
void FlipbookActor::Render(HDC hdc)
{
if (_flipbook == nullptr)
return;
Vec2 cameraPos = GET_SINGLE(SceneManager)->GetCameraPos();
::TransparentBlt(hdc,
(int32)_pos.x - info.size.x / 2 - ((int32)cameraPos.x - GWinSizeX / 2),
(int32)_pos.y - info.size.y / 2 - ((int32)cameraPos.y - GWinSizeY / 2),
info.size.x,
info.size.y,
info.texture->GetDC(),
(info.start + _idx) * info.size.x,
info.line * info.size.y,
info.size.x,
info.size.y,
info.texture->GetTransparent());
}
cameraPos: 현재 카메라의 위치를 가져옵니다.(int32)cameraPos.x - GWinSizeX / 2(int32)cameraPos.y - GWinSizeY / 2void SpriteActor::Render(HDC hdc)
{
Vec2 cameraPos = GET_SINGLE(SceneManager)->GetCameraPos();
::BitBlt(hdc,
(int32)_pos.x - size.x / 2 - ((int32)cameraPos.x - GWinSizeX / 2),
(int32)_pos.y - size.y / 2 - ((int32)cameraPos.y - GWinSizeY / 2),
size.x,
size.y,
_sprite->GetDC(),
_sprite->GetPos().x,
_sprite->GetPos().y,
SRCCOPY);
}
enum LAYER_TYPE
{
LAYER_BACKGROUND,
LAYER_OBJECT,
LAYER_UI,
LAYER_MAXCOUNT
};
enum으로 정의.Actor는 특정 레이어에 속하며, DevScene에서 레이어별로 관리.vector<Actor*> _actors[LAYER_MAXCOUNT];
void DevScene::AddActor(Actor* actor)
{
if (actor == nullptr)
return;
_actors[actor->GetLayer()].push_back(actor);
}
void DevScene::Render(HDC hdc)
{
for (const vector<Actor*>& actors : _actors)
for (Actor* actor : actors)
actor->Render(hdc);
}
_actors: 레이어별로 Actor를 저장.LAYER_BACKGROUND → LAYER_OBJECT → LAYER_UI.