* 생성시킨 객체 주변을 회전하는 총알 n개를 만들어 보자
* 스킬 사용 버튼을 누를 시 회전 속도와 범위가 늘어난다.
* LOL의 챔피언 '아우렐리온 솔'의 W스킬과 비슷함.
//Class CRotatingBullet: public CGameObject
//RotatingBullet.h
#pragma once
#include "GameObject.h"
//소환한 클래스의 주변에 3개 생성되어 주변을 도는 총알
class CRotatingBullet :
public CGameObject
{
friend class CScene;
protected:
CRotatingBullet();
CRotatingBullet(const CRotatingBullet& obj);
virtual ~CRotatingBullet();
virtual bool Init();
virtual void Update(float DeltaTime);
virtual void Render(HDC hDC, float DeltaTime);
private:
//생성 시 회전 총알의 주인이 누구인지 저장
CSharedPtr<CGameObject> m_Master;
//첫번째 총알의 각도
float m_Angle;
//회전 속도
float m_RotatingSpeed;
//주인 객체와의 거리
float m_Dist;
//회전 방향 조절용 변수
float m_Dir;
//만들 총알 갯수
int m_BulletNum;
//만들어진 총알의 위치를 저장할 배열(동적 할당 - BulletNum만큼의 배열 크기를 가짐)
Vector2* m_BulletVectorArr;
//주인 객체가 스킬을 시전했는지
bool m_SkillOn;
//스킬 사용시 확대 속도
float m_ExpandSpeed;
//스킬 사용시 기존 값 저장용
float m_DefaultRotSpeed;
float m_DefaultDist;
//스킬 시전 시 지속 시간 및 시전 후 지난 시간
float m_SkillDuration;
float m_PassedTime;
private:
//스킬
void BulletExpand(float DeltaTime);
public:
void SetMaster(CGameObject* ptr)
{
m_Master = ptr;
}
CGameObject* GetMaster() const
{
return *m_Master;
}
//스킬 Enable
void SkillEnable()
{
m_SkillOn = true;
}
void SetRotatingSpeed(float speed)
{
m_RotatingSpeed = speed;
}
float GetRotatingSpeed() const
{
return m_RotatingSpeed;
}
//기본값 저장용
void DefaultValue()
{
m_DefaultRotSpeed = m_RotatingSpeed;
m_DefaultDist = m_Dist;
}
};
//Class CRotatingBullet: public CGameObject
//RotatingBullet.cpp
#include "RotatingBullet.h"
CRotatingBullet::CRotatingBullet()
{
}
CRotatingBullet::CRotatingBullet(const CRotatingBullet& obj) :
CGameObject(obj),
m_Angle(obj.m_Angle),
m_Dist(obj.m_Dist),
m_RotatingSpeed(obj.m_RotatingSpeed),
m_Dir(obj.m_Dir),
m_Master(obj.m_Master),
m_BulletNum(obj.m_BulletNum),
m_ExpandSpeed(obj.m_ExpandSpeed),
m_SkillDuration(obj.m_SkillDuration),
m_BulletVectorArr(obj.m_BulletVectorArr),
m_DefaultDist(obj.m_DefaultDist),
m_DefaultRotSpeed(obj.m_DefaultRotSpeed),
m_PassedTime(obj.m_PassedTime)
{
}
CRotatingBullet::~CRotatingBullet()
{
delete[] m_BulletVectorArr;
}
bool CRotatingBullet::Init()
{
m_Angle = 0.f;
m_PassedTime = 0.f;
//회전 속도
m_RotatingSpeed = 90.f;
m_Dir = 1.f;
m_Dist = 100.f;
//주위를 회전하는 총알 갯수
m_BulletNum = 5;
m_BulletVectorArr = new Vector2[m_BulletNum];
m_Master = nullptr;
m_ExpandSpeed = 100.f;
m_SkillDuration = 4.f;
DefaultValue();
SetPivot(0.5f, 0.5f);
SetSize(30.f, 30.f);
return true;
}
void CRotatingBullet::Update(float DeltaTime)
{
//상태 업데이트 시점까지 주인 객체의 주소가 등록되지 않으면 이 객체를 삭제.
if (!m_Master)
{
SetActive(false);
return;
}
if(m_SkillOn)
BulletExpand(DeltaTime);
//주인을 따라다님
m_Pos = m_Master->GetPos();
//각도 조절
m_Angle += m_RotatingSpeed * DeltaTime;
//한바퀴 돌면 값을 내려줌
if (m_Angle > 360.f)
m_Angle -= 360.f;
//별의 위치 계산
for (int i = 0; i < m_BulletNum; ++i)
{
float angle = m_Angle + (360.f / m_BulletNum) * i;
Vector2 Dir = Vector2(cosf(DegreeToRadian(angle)), sinf(DegreeToRadian(angle)));
m_BulletVectorArr[i] = m_Pos + Dir * m_Dist;
}
}
void CRotatingBullet::Render(HDC hDC, float DeltaTime)
{
for (int i = 0; i < m_BulletNum; ++i)
{
Vector2 RenderLT = m_BulletVectorArr[i] - m_Size * m_Pivot;
Ellipse(hDC, (int)RenderLT.x, (int)RenderLT.y, (int)(RenderLT.x + m_Size.x), (int)(RenderLT.y + m_Size.y));
}
}
void CRotatingBullet::BulletExpand(float DeltaTime)
{
m_PassedTime += DeltaTime;
if (m_PassedTime < m_SkillDuration)
{
if(m_Dist < (m_Dist + m_ExpandSpeed))
{
m_Dist += 0.5 * m_ExpandSpeed * DeltaTime;
}
if (m_RotatingSpeed < (m_RotatingSpeed + m_ExpandSpeed))
{
m_RotatingSpeed += m_ExpandSpeed * DeltaTime;
}
}
else
{
if (m_Dist > m_DefaultDist)
{
m_Dist -= 0.5 * m_ExpandSpeed * DeltaTime;
}
if (m_RotatingSpeed > m_DefaultRotSpeed)
{
m_RotatingSpeed -= m_ExpandSpeed * DeltaTime;
}
}
//지속시간 이후 2배의 시간이 지나면 스킬 상태 off
if (m_PassedTime >= m_SkillDuration * 2.f)
{
m_SkillOn = false;
m_PassedTime = 0.f;
}
}
구현 이후 생성하고싶은 객체에서 자신을 주인 객체로 등록해준다.
//회전하는 총알 생성
CRotatingBullet* RotatingBullet = m_Scene->CreateObject<CRotatingBullet>("RotatingBulletPlayer");
RotatingBullet->SetMaster(this);
스킬 사용과 관련된 함수도 만들어 준다.
void CPlayer::Skill2BulletExpand()
{
if (m_VecCoolDown[2].CoolDownEnable)
return;
m_VecCoolDown[2].CoolDownEnable = true;
m_VecCoolDown[2].CoolDownLeft = m_VecCoolDown[2].CoolDown;
CRotatingBullet* RotatingBullet = (CRotatingBullet*)*(m_Scene->FindGameObject("RotatingBulletPlayer"));
RotatingBullet->SkillEnable();
}

'WIN32API FrameWork > 원본' 카테고리의 다른 글
220509_WIN32API_6-3_총알 발사 - 스킬 쿨타임 구현 (0) | 2022.05.12 |
---|---|
220509_WIN32API_6-2_총알 발사 - 쿨타임 구현과 실제 발사 (0) | 2022.05.12 |
220509_WIN32API_6-1_총알 발사 - 총알 클래스 구현 (0) | 2022.05.12 |
220504_WIN32API_Framework_5-3_실제 Scene 만들고 실행(MainScene) (0) | 2022.05.08 |
220504_WIN32API_Framework_5-2_Class Scene (0) | 2022.05.08 |
* 생성시킨 객체 주변을 회전하는 총알 n개를 만들어 보자
* 스킬 사용 버튼을 누를 시 회전 속도와 범위가 늘어난다.
* LOL의 챔피언 '아우렐리온 솔'의 W스킬과 비슷함.
//Class CRotatingBullet: public CGameObject
//RotatingBullet.h
#pragma once
#include "GameObject.h"
//소환한 클래스의 주변에 3개 생성되어 주변을 도는 총알
class CRotatingBullet :
public CGameObject
{
friend class CScene;
protected:
CRotatingBullet();
CRotatingBullet(const CRotatingBullet& obj);
virtual ~CRotatingBullet();
virtual bool Init();
virtual void Update(float DeltaTime);
virtual void Render(HDC hDC, float DeltaTime);
private:
//생성 시 회전 총알의 주인이 누구인지 저장
CSharedPtr<CGameObject> m_Master;
//첫번째 총알의 각도
float m_Angle;
//회전 속도
float m_RotatingSpeed;
//주인 객체와의 거리
float m_Dist;
//회전 방향 조절용 변수
float m_Dir;
//만들 총알 갯수
int m_BulletNum;
//만들어진 총알의 위치를 저장할 배열(동적 할당 - BulletNum만큼의 배열 크기를 가짐)
Vector2* m_BulletVectorArr;
//주인 객체가 스킬을 시전했는지
bool m_SkillOn;
//스킬 사용시 확대 속도
float m_ExpandSpeed;
//스킬 사용시 기존 값 저장용
float m_DefaultRotSpeed;
float m_DefaultDist;
//스킬 시전 시 지속 시간 및 시전 후 지난 시간
float m_SkillDuration;
float m_PassedTime;
private:
//스킬
void BulletExpand(float DeltaTime);
public:
void SetMaster(CGameObject* ptr)
{
m_Master = ptr;
}
CGameObject* GetMaster() const
{
return *m_Master;
}
//스킬 Enable
void SkillEnable()
{
m_SkillOn = true;
}
void SetRotatingSpeed(float speed)
{
m_RotatingSpeed = speed;
}
float GetRotatingSpeed() const
{
return m_RotatingSpeed;
}
//기본값 저장용
void DefaultValue()
{
m_DefaultRotSpeed = m_RotatingSpeed;
m_DefaultDist = m_Dist;
}
};
//Class CRotatingBullet: public CGameObject
//RotatingBullet.cpp
#include "RotatingBullet.h"
CRotatingBullet::CRotatingBullet()
{
}
CRotatingBullet::CRotatingBullet(const CRotatingBullet& obj) :
CGameObject(obj),
m_Angle(obj.m_Angle),
m_Dist(obj.m_Dist),
m_RotatingSpeed(obj.m_RotatingSpeed),
m_Dir(obj.m_Dir),
m_Master(obj.m_Master),
m_BulletNum(obj.m_BulletNum),
m_ExpandSpeed(obj.m_ExpandSpeed),
m_SkillDuration(obj.m_SkillDuration),
m_BulletVectorArr(obj.m_BulletVectorArr),
m_DefaultDist(obj.m_DefaultDist),
m_DefaultRotSpeed(obj.m_DefaultRotSpeed),
m_PassedTime(obj.m_PassedTime)
{
}
CRotatingBullet::~CRotatingBullet()
{
delete[] m_BulletVectorArr;
}
bool CRotatingBullet::Init()
{
m_Angle = 0.f;
m_PassedTime = 0.f;
//회전 속도
m_RotatingSpeed = 90.f;
m_Dir = 1.f;
m_Dist = 100.f;
//주위를 회전하는 총알 갯수
m_BulletNum = 5;
m_BulletVectorArr = new Vector2[m_BulletNum];
m_Master = nullptr;
m_ExpandSpeed = 100.f;
m_SkillDuration = 4.f;
DefaultValue();
SetPivot(0.5f, 0.5f);
SetSize(30.f, 30.f);
return true;
}
void CRotatingBullet::Update(float DeltaTime)
{
//상태 업데이트 시점까지 주인 객체의 주소가 등록되지 않으면 이 객체를 삭제.
if (!m_Master)
{
SetActive(false);
return;
}
if(m_SkillOn)
BulletExpand(DeltaTime);
//주인을 따라다님
m_Pos = m_Master->GetPos();
//각도 조절
m_Angle += m_RotatingSpeed * DeltaTime;
//한바퀴 돌면 값을 내려줌
if (m_Angle > 360.f)
m_Angle -= 360.f;
//별의 위치 계산
for (int i = 0; i < m_BulletNum; ++i)
{
float angle = m_Angle + (360.f / m_BulletNum) * i;
Vector2 Dir = Vector2(cosf(DegreeToRadian(angle)), sinf(DegreeToRadian(angle)));
m_BulletVectorArr[i] = m_Pos + Dir * m_Dist;
}
}
void CRotatingBullet::Render(HDC hDC, float DeltaTime)
{
for (int i = 0; i < m_BulletNum; ++i)
{
Vector2 RenderLT = m_BulletVectorArr[i] - m_Size * m_Pivot;
Ellipse(hDC, (int)RenderLT.x, (int)RenderLT.y, (int)(RenderLT.x + m_Size.x), (int)(RenderLT.y + m_Size.y));
}
}
void CRotatingBullet::BulletExpand(float DeltaTime)
{
m_PassedTime += DeltaTime;
if (m_PassedTime < m_SkillDuration)
{
if(m_Dist < (m_Dist + m_ExpandSpeed))
{
m_Dist += 0.5 * m_ExpandSpeed * DeltaTime;
}
if (m_RotatingSpeed < (m_RotatingSpeed + m_ExpandSpeed))
{
m_RotatingSpeed += m_ExpandSpeed * DeltaTime;
}
}
else
{
if (m_Dist > m_DefaultDist)
{
m_Dist -= 0.5 * m_ExpandSpeed * DeltaTime;
}
if (m_RotatingSpeed > m_DefaultRotSpeed)
{
m_RotatingSpeed -= m_ExpandSpeed * DeltaTime;
}
}
//지속시간 이후 2배의 시간이 지나면 스킬 상태 off
if (m_PassedTime >= m_SkillDuration * 2.f)
{
m_SkillOn = false;
m_PassedTime = 0.f;
}
}
구현 이후 생성하고싶은 객체에서 자신을 주인 객체로 등록해준다.
//회전하는 총알 생성
CRotatingBullet* RotatingBullet = m_Scene->CreateObject<CRotatingBullet>("RotatingBulletPlayer");
RotatingBullet->SetMaster(this);
스킬 사용과 관련된 함수도 만들어 준다.
void CPlayer::Skill2BulletExpand()
{
if (m_VecCoolDown[2].CoolDownEnable)
return;
m_VecCoolDown[2].CoolDownEnable = true;
m_VecCoolDown[2].CoolDownLeft = m_VecCoolDown[2].CoolDown;
CRotatingBullet* RotatingBullet = (CRotatingBullet*)*(m_Scene->FindGameObject("RotatingBulletPlayer"));
RotatingBullet->SkillEnable();
}

'WIN32API FrameWork > 원본' 카테고리의 다른 글
220509_WIN32API_6-3_총알 발사 - 스킬 쿨타임 구현 (0) | 2022.05.12 |
---|---|
220509_WIN32API_6-2_총알 발사 - 쿨타임 구현과 실제 발사 (0) | 2022.05.12 |
220509_WIN32API_6-1_총알 발사 - 총알 클래스 구현 (0) | 2022.05.12 |
220504_WIN32API_Framework_5-3_실제 Scene 만들고 실행(MainScene) (0) | 2022.05.08 |
220504_WIN32API_Framework_5-2_Class Scene (0) | 2022.05.08 |