*** 공부 방법 ***
1. 코딩을 해야 하는 부분은 첫 부분에 변수나 함수, 메소드에 대한 선언이 코드블럭으로 표시되어 있다. //ex) MakeFunction(); 2. 코드블럭 하단에는 해당 선언에 대한 구현 로직이 작성되어 있다. 처
hyrule.tistory.com
- 설명보다 이미지를 보는게 더 빠르게 이해될것 같아서 이미지로 첨부.

- 이걸 구현해보자.
- 전반적인 구현 방법은 CBullet과 비슷하다. 새 클래스를 만들어고 CBullet 코드를 복사하여 수정하면 된다.
- 힌트
-- 내가 철퇴를 들고 앞으로 돌진하면서 훨윈드를 돌고있는데, 철퇴 끝 부분만 표시되고 있다고 생각하면 된다.
-- '나'는 표시되지 않지만, 위치값(Vector2 m_Pos)은 가지고 있어야 한다. '나'는 지정한 방향(Vector2 m_Dir)으로 계속 이동한다.
-- '나'의 위치를 기준으로, 회전하는 철퇴 끝의 위치(Vector2 m_RotatingBulletCenter)를 계산한다.
--- 철퇴 끝의 위치를 계산하는 방법은 CPlayer의 총구 끝의 위치를 계산하는 방법과 동일하다.
--- 철퇴 끝의 위치를 구했으면, 해당 위치에서 실제로 총알을 그려낸다.
더보기
//TornadoBullet.h
#pragma once
#include "../GameInfo.h"
#include "GameObject.h"
class CTornadoBullet :
public CGameObject
{
friend class CScene;
private:
float m_Speed;
Vector2 m_Dir;
float m_Distance;
bool m_isSet;
//회전 반경
float m_RotatingRadius;
//회전 속도
float m_RotatingAngleSpeed;
//실제 표시되는 총알의 중심점
Vector2 m_RotatingBulletCenter;
//각도 저장
float m_RotatingAngle;
protected:
CTornadoBullet();
CTornadoBullet(const CTornadoBullet& Obj);
virtual ~CTornadoBullet();
public:
bool Init(CGameObject* Obj = nullptr);
void Update(float DeltaTime);
void Render(HDC hDC, float DeltaTime);
//창 밖을 넘어가면 파괴(임시)
bool DestroyCheck();
void SetSpeedDir(float _x, Vector2 Dir)
{
m_isSet = true;
m_Speed = _x;
m_Dir = Dir;
}
};
//TornadoBullet.cpp
#include "TornadoBullet.h"
CTornadoBullet::CTornadoBullet()
{
}
CTornadoBullet::CTornadoBullet(const CTornadoBullet& Obj) :
CGameObject(Obj),
m_Dir(Obj.m_Dir),
m_Speed(Obj.m_Speed),
m_Distance(Obj.m_Distance)
{
}
CTornadoBullet::~CTornadoBullet()
{
}
bool CTornadoBullet::Init(CGameObject* Obj)
{
CGameObject::Init(Obj);
m_RotatingRadius = 100.f;
m_RotatingAngleSpeed = 1080.f;
m_RotatingAngle = 0.f;
m_Speed = 50.f;
m_Distance = 0.f;
SetSize(50.f, 50.f);
SetPivot(0.5f, 0.5f);
return true;
}
void CTornadoBullet::Update(float DeltaTime)
{
this->CGameObject::Update(DeltaTime);
//파괴 조건이 만족되면 총알 제거
//거리를 벗어났거나, 총알 기본세팅을 하지 않았다면 그냥 제거
if (DestroyCheck() || !m_isSet)
{
SetActive(false);
}
m_Pos += m_Dir * m_Speed * DeltaTime;
//매 프레임 총알의 회전량을 구한다.
m_RotatingAngle += m_RotatingAngleSpeed * DeltaTime;
//각도가 360도를 넘어가면, 360도를 뺴줘서 숫자가 너무 커지지 않도록 해준다.
if (m_RotatingAngle >= 360.f)
m_RotatingAngle -= 360.f;
//라디안값을 구한다.
float RotAngleRad = DegreeToRadian(m_RotatingAngle);
//라디안값을 통해 토네이도 총알의 중심점을 구해낸다.
m_RotatingBulletCenter.x = m_Pos.x + (cosf(RotAngleRad) * m_RotatingRadius);
m_RotatingBulletCenter.y = m_Pos.y + (sinf(RotAngleRad) * m_RotatingRadius);
m_Distance += m_Speed * DeltaTime;
}
void CTornadoBullet::Render(HDC hDC, float DeltaTime)
{
CGameObject::Render(hDC, DeltaTime);
//구한 토네이도 총알의 중심점으로부터 총알을 그려낸다.
Vector2 RenderLeftTop = m_RotatingBulletCenter - (m_Size * m_Pivot);
Ellipse(hDC, (int)RenderLeftTop.x,
(int)RenderLeftTop.y,
(int)(RenderLeftTop.x + m_Size.x),
(int)(RenderLeftTop.y + m_Size.y));
}
bool CTornadoBullet::DestroyCheck()
{
if (m_Distance >= 1000.f)
return true;
return false;
}
- 완성되었으면 실제 발사를 시켜보자.
더보기
1. 사용할 키 등록(Ctrl + 1)
//Input.cpp
bool CInput::Init()
{
//...기존 코드들...//
//플레이어 스킬 1번을 Ctrl + 1로 등록.
//CPlayer에서 처리해주어도 되지만,
//키 등록 자체는 원칙적으로 CInput에서 처리해주는 것이 맞다
AddBindKey("TornadoBulletFire", '1');
SetKeyCtrl("TornadoBulletFire");
//...기존 코드들...//
return true;
}
2. 스킬 번호 등록 및 스킬 로직 처리 메소드 등록
//Player.h
//스킬 목록 열거체에 스킬을 등록
enum class EPlayerSkill
{
BasicAttack,
TornadoBulletFire,
End
};
//스킬 로직 처리 메소드를 등록
private:
void TornadoBulletFire();
3. 키와 스킬 로직 메소드를 연결, 쿨타임 설정(3초)
//Player.cpp
bool CPlayer::Init(CGameObject* Obj)
{
//...기존 코드들...//
//입력 바인딩 추가
CInput::GetInst()->AddBindFunction<CPlayer>("TornadoBulletFire", Input_Type::Down,
this, &CPlayer::TornadoBulletFire);
//스킬 설정
m_SkillCoolTimeSet.resize((size_t)EPlayerSkill::End);
m_SkillCoolTimeSet[(int)EPlayerSkill::BasicAttack].CoolTime = 0.5f;
m_SkillCoolTimeSet[(int)EPlayerSkill::TornadoBulletFire].CoolTime = 3.f;
//...기존 코드들...//
return true
}
4. 스킬 로직 입력
//Player.cpp
void CPlayer::TornadoBulletFire()
{
//쿨타임이면 그냥 return
if (m_SkillCoolTimeSet[(int)EPlayerSkill::TornadoBulletFire].isCoolTime)
return;
//쿨타임이 아니면 쿨타임으로 바꾸는 메소드를 호출하고
EnterSkillCoolTIme((int)EPlayerSkill::TornadoBulletFire);
//스킬 로직 진행
CTornadoBullet* Bullet = m_OwnerScene->CreateObject<CTornadoBullet>("TornadoBulletFire", this);
Bullet->SetSpeedDir(400.f, m_Dir);
Bullet->SetPos(m_GunTipPos);
}
- 문제없이 구현했다면 맨 위의 이미지와 같이 작동될 것이다.
'WIN32API FrameWork > 한단계씩 직접 구현' 카테고리의 다른 글
| 30. 스킬 구현 2 - 아우렐리온 솔 W (0) | 2022.05.23 |
|---|---|
| 29. CreateObject 메소드 수정 (0) | 2022.05.23 |
| 27. 스킬 쿨타임 (0) | 2022.05.23 |
| 26. Input 기능 개선 - 입력 바인딩 제거하기 (0) | 2022.05.23 |
| 25. GameObject의 주/종관계 형성 (0) | 2022.05.22 |