*** 공부 방법 ***
1. 코딩을 해야 하는 부분은 첫 부분에 변수나 함수, 메소드에 대한 선언이 코드블럭으로 표시되어 있다. //ex) MakeFunction(); 2. 코드블럭 하단에는 해당 선언에 대한 구현 로직이 작성되어 있다. 처
hyrule.tistory.com
- 사실 스킬 쿨타임은 개별적으로 구현해도 전혀 상관없지만,
통일성과 편의성을 위해 구조체와 열거체, vector 자료구조를 사용하여 구현해 보자.
- 스킬 쿨타임 정보를 담은 구조체를, 배열 vector 안에 넣어서 관리하고,
- 스킬을 사용하는 각 클래스는 열거체에 각 스킬의 순서를 정해놓고 , vector 자료구조에 해당 번호로 저장해준 뒤, 필요할 때마다 꺼내서 사용한다.
- 스킬 쿨타임은 Update() 함수에서 vector 순회를 통해 일괄적으로 관리해준다.
struct SkillCoolTimeSet
{};
- 현재 구현한 클래스인 CPlayer, CMonster 두 캐릭터는 총알을 발사한다.
- 두 클래스에 공통적으로 쿨타임 시스템을 적용할 수 있으므로 해당 클래스의 공통 부모 클래스에 구현하는 것이 적합하다.
- 해당 구조체에는
-- 스킬 쿨타임을 몇 초로 설정할 지,
-- 스킬 쿨타임이 몇 초 남았는지,
-- 현재 스킬 쿨타임인지
에 대한 변수가 들어가야 한다.
- 만약 생성자에서 스킬 쿨타임을 따로 입력받으면, 해당 스킬 쿨타임으로 설정되게 만들어 주자.
Character.h
//스킬 쿨타임 체크용 구조체. 각각 스킬은 해당 객체에서 열거체를 통해 관리할것.
struct SkillCoolTimeSet
{
float CoolTime;
float CoolTimeLeft;
bool isCoolTime;
SkillCoolTimeSet(float cooltime = 5.f) :
CoolTime(cooltime),
CoolTimeLeft(0.f),
isCoolTime(false)
{
}
};
- 이제 쿨타임을 배열 벡터에 넣어 관리할 것이다. 클래스 안에 선언해준다.
//Character.h
protected:
std::vector<SkillCoolTimeSet> m_SkillCoolTimeSet;
CheckSkillCoolTime();
- 편의성을 위한 해당 메소드를 구현한다.
- CheckSkillCoolTime() 메소드는 Character을 상속받는 객체들의 Update()메소드에서 사용한다.
-- 인자로 스킬의 최대 갯수(열거체로부터 얻어올 수 있다)와 DeltaTime을 받아온다.
--- 열거체로부터 Vector()의 최대 사이즈를 받아서 순회를 돌며,
--- 스킬 쿨타임에 진입한 스킬들에 대한 남은 쿨타임을 계산하고,
--- 쿨타임이 끝나면 다시 사용이 가능하도록 바꿔주는 메소드이다.
//Character.cpp
void CCharacter::CheckSkillCoolTime(int SkillEnumEnd, float DeltaTime)
{
//등록된 스킬의 수만큼 순회를 돈다.
for (size_t i = 0; i < SkillEnumEnd; ++i)
{
//만약 스킬의 쿨타임이면,
if (m_SkillCoolTimeSet[i].isCoolTime)
{
//스킬의 쿨타임의 남은 시간을 DeltaTime만큼 감소시킨다.
m_SkillCoolTimeSet[i].CoolTimeLeft -= DeltaTime;
//만약 스킬 쿨타임이 다 돌았으면
if (m_SkillCoolTimeSet[i].CoolTimeLeft <= 0.f)
{
//스킬을 다시 사용 가능하도록 활성화시킨다.
m_SkillCoolTimeSet[i].isCoolTime = false;
}
}
}
}
EnterSkillCoolTIme();
- 각 스킬 메소드에서 호출할 메소드이다.
-- 해당 스킬을 사용했을 경우, 스킬 사용 여부를 true로 바꾸고,
-- 스킬의 남은 쿨타임 시간을 설정해준다.
//Character.cpp
//스킬 사용시 이 함수에 스킬의 Enum을 넣으면 편하게 처리 가능
void CCharacter::EnterSkillCoolTIme(int SkillEnum)
{
//스킬이 쿨타임에 진입했다고 바꾸고
m_SkillCoolTimeSet[SkillEnum].isCoolTime = true;
//스킬의 쿨타임 남은 시간을 초기화한다.
m_SkillCoolTimeSet[SkillEnum].CoolTimeLeft = m_SkillCoolTimeSet[SkillEnum].CoolTime;
}
- 설정이 완료되었으면 플레이어의 총알 발사 로직에 쿨타임을 적용해 보자.
- 플레이어의 스킬 목록을 열거체로 만들어주어야 한다.
- 아직은 스킬이 평타밖에 없으므로, 평타만 등록해 준다.
//Player.h
enum class EPlayerSkill
{
BasicAttack,
End
};
- CPlayer 초기화 시 배열 벡터를 스킬 갯수만큼 미리 리사이즈해놓고, 스킬 쿨타임을 설정해준다.
bool CPlayer::Init(CGameObject* Obj)
{
//...이외의 코드들...//
//스킬 설정
m_SkillCoolTimeSet.resize((size_t)EPlayerSkill::End);
m_SkillCoolTimeSet[(int)EPlayerSkill::BasicAttack].CoolTime = 0.5f;
//...이외의 코드들...//
return true;
}
- 아직은 평타밖에 구현되어있지 않으므로, 해당 평타 로직에 스킬 쿨타임 관련 로직을 추가하면 끝.
void CPlayer::GunFire()
{
//쿨타임이면 그냥 return
if (m_SkillCoolTimeSet[(int)EPlayerSkill::BasicAttack].isCoolTime)
return;
//쿨타임이 아니면 쿨타임으로 바꾸는 메소드를 호출하고
EnterSkillCoolTIme((int)EPlayerSkill::BasicAttack);
//스킬 로직 진행
CBullet* Bullet = m_OwnerScene->CreateObject<CBullet>("PlayerBullet", this);
Bullet->SetSpeedDir(1000.f, m_Dir);
Bullet->SetPos(m_GunTipPos);
}
- 스킬 쿨타임을 0.5초로 설정했으므로, 평타 버튼을 광클릭해도 평타가 0.5초마다 발사되는지 확인해 보자.
'WIN32API FrameWork > 한단계씩 직접 구현' 카테고리의 다른 글
29. CreateObject 메소드 수정 (0) | 2022.05.23 |
---|---|
28. 스킬 구현 1 - 토네이도 총알 (0) | 2022.05.23 |
26. Input 기능 개선 - 입력 바인딩 제거하기 (0) | 2022.05.23 |
25. GameObject의 주/종관계 형성 (0) | 2022.05.22 |
24. 입력을 받아 총을 발사하는 플레이어 (0) | 2022.05.21 |