dx_23일차_Action
과제:
메인퀘스트 : 다음주 월요일까지
공격은 원거리 공격 근거리 공격 두개 구현
-> 몬스터 구현하고 공격 구현해서
피격 구현하기
1. 캐릭터 공격을 만든다
근접/원거리의 공통된부분을 묶는 cookieAttack을 만든다.
-> 근접공격 원거리공격을만들고 cookieAttack을 상속받게한다.
// 공격할때 점프, 이동 모두 할거기 떄문에 점프를 상속받아도 될거같았지만
중복되더라도 깔끔하게 Attack에서 새로 만들어서 상속받자.
(충돌처리, ?)
cookieAttack.h/cpp
#pragma once
class CookieAttack : public CookieAction
{
protected:
const float JUMP_POWER = 600.0f;
const float FLOOR_EPSILON = 2.0f;
public:
CookieAttack() = default;
~CookieAttack() = default;
virtual void Update() override;
protected:
bool IsCollisionFloor();
};
////////////////////////////////////////
#include "Framework.h"
void CookieAttack::Update()
{
velocity.y -= GRAVITY * DELTA;
target->Translate(Vector2::Up() * velocity.y * DELTA);
Move();
Action::Update();
}
bool CookieAttack::IsCollisionFloor()
{
RectCollider* cookie = ((Cookie*)target)->GetCollider();
RectCollider* floor = FloorManager::Get()->Collision(cookie);
if (floor == nullptr) return false;
float cookieBottom = cookie->RightBottom().y;
float floorTop = floor->RightTop().y;
if (cookieBottom < floorTop && cookieBottom > floorTop - FLOOR_EPSILON)
{
target->Translate(Vector2::Up() * (floorTop - cookieBottom));
return true;
}
return false;
}
이제 애니메이션이 끝나면 Idle 상태로 돌아오게 하기위해서 함수포인터 와 옵저버 패턴을 활용하기로 결정!
근데 여기서 난관!
SetEvent를 string 키값이 있는데 이를 만들어두기만하고 활용을 안했다.
클립에서의 SetEvent는 지정해주는 부분이 있어 이벤트를 만들어 넣을 수 있었는데
Action에서는 이가 없기에 새로 만들어주어야한다고 생각했다.
class Action
{
virtual void Update();
virtual void Start();
virtual void End() {}
void SetEvent(string key, Event event) { events[key] = event; }
Clip* GetClip(int index) { return clips[index]; }
protected:
vector<Clip*> clips;
int curState = 0;
map<string, Event> events;
};
이 때 End 순수가상함수에서 정의를 해버릴까? 아니면 업데이트에서 이벤트가 있을때 이를 실행해 줄까를 고민했다.
하지말자
그냥 클립의 이벤트를 가져다 넣어버리자
actions[ATTACK_MELEE] = new CookieMelee(this);
//옵저버패턴써서 넣고싶었는데 액션이 끝날때를 생각이 안난다. 좀만 미뤄두자
actions[ATTACK_MELEE]->GetClip(0)->SetClipEvent(bind(&Cookie::SetIdle, this));
actions[ATTACK_RANGE] = new CookieRange(this);
actions[ATTACK_RANGE]->GetClip(0)->SetClipEvent(bind(&Cookie::SetIdle, this));
완료했더니 공격할때마다 중력을 받아서 아래로 내려가는 버그가 발생!

버그다 버그
이때! 아이들상태일때도 바닥과 충돌처리를 일으켜서 해결하는방법을 생각 -> 바로 실행해보자
이러면 많은곳에서 바닥충돌처리를 하니까 점프에서만 처리하지말고 cookieaction으로 옮기자
성공(!)
다음문제인 IDLE상태일떄도 중력추가해서 떨어지게끔하자
2. 적 만들기
(enemy또한 여러 상태가 있을거같으니까 후에 여러상태로 나누기 위해서 EnemyAction을 만들어준다.)
EnemyAction.h/cpp
#pragma once
class EnemyAction : public Action
{
protected:
const string PATH = "Resources/Textures/Cookie/Enemy/";
const float GRAVITY = 980.0f;
public:
EnemyAction() = default;
EnemyAction(string file, bool isLoop, float speed = 1.0f);
~EnemyAction() = default;
void SetTarget(Transform* target) { this->target = target; }
protected:
// bool IsCollisionFloor();
protected:
Transform* target;
Vector2 velocity;
};
//
#include "Framework.h"
EnemyAction::EnemyAction(string file, bool isLoop, float speed)
: Action("Resources/Textures/Cookie/Enemy/", file, isLoop, speed)
{
}
Enemy.h/cpp
#pragma once
class CookieEnemy : public GameObject
{
public:
const float GRAVITY = 980.0f;
const float FLOOR_EPSILON = 2.0f;
enum State
{
IDLE, PATROL, ATTACK, DEAD
};
public:
CookieEnemy();
~CookieEnemy();
void Update() override;
void Render() override;
void PostRender();
RectCollider* GetCollider() { return collider; }
private:
void SetAction(int state);
bool IsCollisionFloor();
private:
RectCollider* collider;
map<State, Action*> actions;
State curState = IDLE;
Vector2 velocity;
};
///////////////////////////////
#include "Framework.h"
CookieEnemy::CookieEnemy()
{
actions[IDLE] = new EnemyAction("Kitty_Idle.xml", true, 0.4f);
actions[IDLE]->Start();
collider = new RectCollider({ 100, 100 });
collider->SetParent(this);
collider->SetTag("EnemyBody");
collider->Load();
}
CookieEnemy::~CookieEnemy()
{
for (auto action : actions)
delete action.second;
delete collider;
}
void CookieEnemy::Update()
{
velocity.y -= GRAVITY * DELTA;
IsCollisionFloor();
actions[curState]->Update();
UpdateWorld();
collider->UpdateWorld();
}
void CookieEnemy::Render()
{
worldBuffer->Set(world);
worldBuffer->SetVS(0);
actions[curState]->Render();
collider->Render();
}
void CookieEnemy::PostRender()
{
RenderUI();
collider->RenderUI();
}
void CookieEnemy::SetAction(int state)
{
if (curState == state) return;
curState = (State)state;
actions[curState]->Start();
}
bool CookieEnemy::IsCollisionFloor()
{
RectCollider* floor = FloorManager::Get()->Collision(collider);
if (floor == nullptr) return false;
float cookieBottom = collider->RightBottom().y;
float floorTop = floor->RightTop().y;
if (cookieBottom < floorTop && cookieBottom > floorTop - FLOOR_EPSILON)
{
Translate(Vector2::Up() * (floorTop - cookieBottom));
return true;
}
return false;
}
플레이어와 충돌처리는 좀 있다 하고,
총알 구현하러 ㄱㄱ
3. 총알구현
총알에 애니메이션을 넣느냐 마느냐에 따라 Quad 를 상속받을까 Action을 상속받을까 생각했는데
action을 상속받으면 콜라이더나 액티브 끄고 키는 기능을 다시 만들어야 해서
1).Quad를 상속 받는방법
이나 기본 불릿기능은 쿠키나,enemy처럼
2) GameObject 를 상속받고 세부적인 총알(관통, 차지, 일반)들이 Bullet을 상속받아서 bulletmanager로 관리하는방법
3) Action을 상속받기 : 신경쓸게 많아서 X