*** 공부 방법 ***
1. 코딩을 해야 하는 부분은 첫 부분에 변수나 함수, 메소드에 대한 선언이 코드블럭으로 표시되어 있다. //ex) MakeFunction(); 2. 코드블럭 하단에는 해당 선언에 대한 구현 로직이 작성되어 있다. 처
hyrule.tistory.com
- 저번에 만들었던 각도 구하기 메소드를 활용해 몬스터가 매 3발마다 플레이어를 향해 총을 쏘게 만들어보자.
- 우선, 총을 발사하기 위해서는 '플레이어'의 좌표값이 필요한데...
좌표값에 접근하기 위해서는 우선 CPlayer에 접근하는 방법을 생각해봐야 한다.
-- 방법은 2가지가 있다.
---1. 플레이어의 주소는 자주 쓰이므로 아예 CGameManager 클래스에 CPlayer의 주소를 등록해 놓고,
필요할 때마다 호출해서 주소를 받기.
---- 이렇게 하게 되면, CPlayer를 초기화할 때 등록해 주는 과정도 추가로 작성 주어야 한다.
---2. CScene에서 모든 게임오브젝트의 목록에 접근하여 원하는 CGameObject를 찾아주는 메소드를 만들기
2번 방식을 쓰기 위해서는 CScene에 접근하기 위한 방법도 추가해주어야 한다.
----2-1. CSceneManager에서 CScene에 접근하기
----2-2. CGameObject이 생성될 때, 자신이 소속된 CScene을 등록해서 CScene에 접근하기.
---- 현재 구동되고 있는 CScene은 CSceneManager 에서 관리하고 있으므로, 실제 접근은 CSceneManager에서 현재 CScene에 접근하는 방식으로 구현해야 한다.
- 편의를 위해 모두 구현해보자.
▼1번
//GameManager.h에 추가할 내용
private:
//플레이어 헤더 포함시키지 않고 전방선언(코드꼬임 방지)
//플레이어는 자주 쓰이므로 변수로 따로 잡아놓고,
//다른 객체에서 요청 시 주소를 반환해준다.
class CPlayer* m_Player;
public:
void SetPlayer(class CPlayer* Player);
class CPlayer* GetPlayer() const;
//GameManager.cpp에 추가할 내용
void CGameManager::SetPlayer(CPlayer* Player)
{
m_Player = Player;
}
CPlayer* CGameManager::GetPlayer() const
{
return m_Player;
}
//Player.cpp에 추가할 내용
#include "../GameManager.h"
bool CPlayer::Init()
{
//Player의 주소를 CGameManager에 등록한다.
CGameManager::GetInst()->SetPlayer(this);
//...이외의 코드들...
}
▼2-1 번
//SceneManager.h에 해당 내용 추가
public:
CScene* GetScene() const
{
return m_PresentScene;
}
▼2-2 번
//GameObject.h에 해당 내용 추가
protected:
CScene* m_OwnerScene;
private:
void SetOwnerScene(CScene* Scene)
{
m_OwnerScene = Scene;
}
public:
CScene* GetOwnerScene() const
{
return m_OwnerScene;
}
게임오브젝트에서 자신을 생성한 CScene을 등록해 주고 등록하는 메소드도 추가해 준다.
public:
template <typename T>
T* CreateObject(const std::string& Name = "GameObject")
{
//...기존 코드들...
//게임오브젝트가 생성될 때 생성한 씬을 등록.
Obj->SetOwner(this);
//...기존 코드들...
}
CScene에서 게임오브젝트를 생성할 때, 생성한 CScene의 클래스 주소를 등록해 준다.
CScene::FindObject()
- 이제 CScene에 접근할 수 있는 방법을 마련했으므로 CScene에서 등록된 CGameObject의 '이름'(문자열)을 통해 접근하는 메소드를 추가해 준다.
- m_ObjList를 iterator로 순회 돌면서 이름이 일치하는 CGameObject를 찾으면 주소를 반환한다.
CGameObject* CScene::FindObject(const std::string& Name)
{
std::list<CSharedPtr<class CGameObject>>::iterator iter = m_ObjList.begin();
std::list<CSharedPtr<class CGameObject>>::iterator iterEnd = m_ObjList.end();
while (iter != iterEnd)
{
if ((*iter)->m_Name == Name)
return *iter;
++iter;
}
return nullptr;
}
- 이제 CMonster에서 CPlayer의 위치를 받아올 수 있다.
- 이제 이 주소를 받아다가 플레이어를 향해 총을 쏘는 로직을 구현한다.
- 각도를 구해서 발사하는 로직은 플레이어의 총 방향 구현과 비슷하다.
-- 각도의 코사인값은 x축 방향 벡터가 되고, 사인값은 y축 방향 벡터가 된다.
//GameInfo.h에 해당 변수 추가 선언
private:
int m_InhancedFireCycle;
int m_InhancedFireCount;
* 여기서는 2-1번 방법을 사용하여 CPlayer의 주소를 받아왔다.
//GameInfo.cpp에 해당 코드 추가
#include "../GameManager.h"
#include "../GameObject/Player.h"
void CMonster::Update(float DeltaTime)
{
//...기존 코드들...
m_BulletDurationTimer += DeltaTime;
if (m_BulletDurationTimer > m_BulletDuration)
{
CBullet* Bullet = CSceneManager::GetInst()->GetScene()->CreateObject<CBullet>("Bullet");
Bullet->SetSpeedDir(1000.f, Vector2(-1.f, 0.f));
++m_InhancedFireCount;
if (m_InhancedFireCount == m_InhancedFireCycle)
{
CGameObject* Player = m_OwnerScene->FindObject("Player");
if (Player)
{
float angle = m_Pos.Angle(Player->GetPos());
Vector2 Dir;
Dir.x = cosf(angle);
Dir.y = sinf(angle);
Bullet->SetSpeedDir(1000.f, Dir);
}
m_InhancedFireCount = 0;
}
Bullet->SetPos(m_Pos.x, m_Pos.y);
m_BulletDurationTimer = 0.f;
}
}
'WIN32API FrameWork > 한단계씩 직접 구현' 카테고리의 다른 글
25. GameObject의 주/종관계 형성 (0) | 2022.05.22 |
---|---|
24. 입력을 받아 총을 발사하는 플레이어 (0) | 2022.05.21 |
22. 특정 목표까지의 각도 구하기 (0) | 2022.05.21 |
21. 총알 발사하기 / 목표물까지의 각도 구하기 (0) | 2022.05.20 |
20. (활용)몬스터 만들기 (0) | 2022.05.20 |