C. 포트리스 모작 #3
6. 포신과 총알 구현하기
w, s키를 누르면 포신의 각도가 변경되도록 구현해볼것임
a. 플레이어 키값에 따른 값 설정하기
clamp : 어떤영역에 포함되기 원할 때 사용하는 함수
b. 포신 값에 따라 UI 설정하기
c. 총알 만들기
1 ) 기본 총알을 만들기
2) 위 총알을 생성해주기
d. 총알 특성 구현하기
1) 스피드 구현하기
여기서 총알이 소멸되면, 턴을 종료시켜야하는데
턴을 종료시키는 코드는 ChangePlayerTurn에 있음
➡ 따라서 현재 씬을 가져오는 코드를 생성해줘야함
2) 포물선 구현하기
👉 먼저 속도와 가속도에 대해서 공부하기
위에서 공부했듯, 가속도에 대한 개념을 가지고 포물선을 구현함
3) 바람 영향 구현하기
중력 코드와 마찬가지로 바람은 x방향에 영향을 주면 끝
4) 소유주 생성하기
소유주는 총알뿐만 아니라 펫같은 컨텐츠에서 꼭 필요한 개념
내 총알이 나를 쏘면 안되니, 충돌처리하기 전에 만들어주자
7. 충돌처리하기
a. 총알의 충돌감지
bullet이 update될 때 충돌처리를 해야함
8. 나머지 부분 구현해주기
a. 스테미너 UI 구현하기
b. 키에따른 다른 미사일 구현하기
문제점 1) 총알에서 유도탄 구현하기
미사일 내부에서 isSpecial 변수를 이용해 미사일 종류에따라 다른 코드를 구현했지만
이렇게되면 나중에 다양한 미사일이 생길 때 마다 코드의 양이 방대해져 유지보수가 어려울것으로 판단해서
예전에 구현한 미사일 파일을 사용해 구현하려고 했다
문제점 2) 미사일 추가하기
예전에 사용하던 코드는 총알과 다른 부분이 많아서 수정해야 할 코드가 많았음
<최종 미사일 코드>
◽◽◽
#include "pch.h"
#include "Missile.h"
#include "TimeManager.h"
#include "ObjectManager.h"
#include "FortressScene.h"
#include "SceneManager.h"
Missile::Missile() : Object(ObjectType::Projectile)
{
}
Missile::~Missile()
{
}
void Missile::Init()
{
// TODO : Data 나중에 이 데이터를 통해서 플레이어의 체력을 깎아줘야함
//_stat.hp = 1;
//_stat.maxHp = 1;
_stat.speed = 300; //유도탄은 처음 0.2초 이후 설정된 속도로 움직임
_radius = 20.f; //충돌 범위
}
void Missile::Update()
{
float deltaTime = GET_SINGLE(TimeManager)->GetDeltaTime();
//타겟 찾기
if (_target == nullptr) //못찾았다면
{
//0.2초 전 쭉 날아가기
_pos += _speed * deltaTime;
// 0.2초 후에 유도탄
_sumTime += deltaTime;
if (_sumTime >= 0.2f)
{
//주변에 있는 오브젝트 가져오기
const vector<Object*>& objects = GET_SINGLE(ObjectManager)->GetObjects();
for (Object* object : objects)
{
if (object->GetObjectType() != ObjectType::Player) //플레이어가 아니라면 넘어가고
continue;
if (object == _owner) //소유주여도 넘어가기
continue;
_target = object; //상대 Player면 타겟팅
break;
}
}
}
else //위 반복문에서 상대 Player를 찾았다면
{
Vector dir = _target->GetPos() - GetPos(); //벡터를 구하려면 상대위치 - 내위치
dir.Normalize(); //단위벡터로 만들어주기
// 유효한 데이터일까?
_target->SetPos(_target->GetPos());
_pos += dir * deltaTime * _stat.speed; //이동해야하는 위치를 단위벡터 * 시간 * 속도로 구하기
//충돌
Vector dir2 = _target->GetPos() - GetPos();
float dist = sqrt(dir2.x * dir2.x + dir2.y * dir2.y); //거리공식
if (dist < 20) {
//종료시키는 코드는 포트리스씬의 ChangePlayerTurn에 있음
auto* scene = dynamic_cast<FortressScene*>(GET_SINGLE(SceneManager)->GetCurrentScene());
if (scene)
scene->ChangePlayerTurn(); //턴을 완료하기
GET_SINGLE(ObjectManager)->Remove(this); //자폭시키기
return;
}
}
// 범위가 넘어가면 소멸
if (_pos.y > GWinSizeY * 1.5 || _pos.y < -GWinSizeY * 1.5)
{
//종료시키는 코드는 포트리스씬의 ChangePlayerTurn에 있음
auto* scene = dynamic_cast<FortressScene*>(GET_SINGLE(SceneManager)->GetCurrentScene());
if (scene)
scene->ChangePlayerTurn(); //턴을 완료하기
GET_SINGLE(ObjectManager)->Remove(this); //자폭시키기
return;
}
}
void Missile::Render(HDC hdc)
{
//충돌판정을 감지할 radius
Utils::DrawCircle(hdc, _pos, static_cast<int32>(_radius));
}
9. 코드의 문제점 찾기
a. 오브젝트 매니저
오브젝트 매니저를 사용하는 것 보다 객체를 각 씬에서 들고있는게 더 좋지만
온라인게임에서는 또 오브젝트 매니저가 유용하게 사용된다
b. UI매니저의 데이터 관리
c. 생포인터 사용
'컴퓨터 그래픽스 : 수학 > 게임 수학' 카테고리의 다른 글
[게임 프로그래머 입문 올인원] 게임수학 : 속도와 가속도 (101강) (0) | 2024.04.16 |
---|---|
[게임 프로그래머 입문 올인원] 게임수학 : 포트리스 모작 #2 (100강) (1) | 2024.04.16 |
[게임 프로그래머 입문 올인원] 게임수학 : 포트리스 모작 #1 (99강) (0) | 2024.04.15 |
[게임 프로그래머 입문 올인원] 게임수학 : 역삼각함수 (98강) (0) | 2024.04.11 |
[게임 프로그래머 입문 올인원] 게임수학 : 외적 (97강) (0) | 2024.04.11 |