응애맘마조
8방향 캐릭터 본문
주의 : 해당 게시글의 코드는 캐릭터의 움직임을 구현하기 위해 사용한 것으로 특정 게임의 모션을 사용하였습니다. 기타 표절 목적이나 수익 창출을 위해 사용한 것이 아님을 밝힙니다.
8방향 캐릭터 움직임에 대한 것이 과제였습니다. 캐릭터를 만들 때 각각의 클래스로 만들어서 하는 것이 맞지만 캐릭터의 종류나 이미지, 만약 액션 게임 계열이라면 들 수 있는 무기 등등 경우의 수가 굉장히 많아집니다. 따라서 최상위 클래스를 만들어 상속을 받게 하는 것이 가장 이상적입니다.
//Character.h
#pragma once
enum Dir_State
{
L,
T,
R,
B,
LT,
RT,
LB,
RB
};
class Character
{
public:
ObRect* col;
Vector2 moveDir;
Dir_State dirState;
float frameY[8];
};
최상위 클래스 Character.h입니다. cpp에서는 #include "stdafx.h"만 있으므로 따로 코드블럭으로 작성하지 않겠습니다.
//TitanSoul.h
#pragma once
enum class T_State
{
IDLE,
WALK,
ROLL
};
class TitanSoul : public Character
{
public:
ObImage* walk;
ObImage* roll;
T_State state;
float rollTime;
public:
TitanSoul();
~TitanSoul();
void Update();
void Render();
void Idle();
void Walk();
void Roll();
void LookAtTarget(Vector2 target);
void Input();
};
TitanSoul.h 입니다. 캐릭터의 움직임을 위해 게임 내 캐릭터 스프라이트 이미지를 사용하였습니다.
//TitanSoul.cpp
#include "stdafx.h"
TitanSoul::TitanSoul()
{
col = new ObRect;
walk = new ObImage(L"Walk.png");
roll = new ObImage(L"Roll.png");
col->scale = Vector2(walk->imageSize.x / 6.0f, walk->imageSize.y / 8.0f) * 5.0f;
col->isFilled = false;
walk->scale = Vector2(walk->imageSize.x / 6.0f, walk->imageSize.y / 8.0f) * 5.0f;
walk->maxFrame = Int2(6, 8);
walk->SetParentRT(*col);
roll->scale = Vector2(roll->imageSize.x / 6.0f, roll->imageSize.y / 8.0f) * 5.0f;
roll->maxFrame = Int2(6, 8);
roll->SetParentRT(*col);
roll->isVisible = false;
frameY[L] = 2;
frameY[R] = 0;
frameY[T] = 1;
frameY[B] = 3;
frameY[LT] = 6;
frameY[RT] = 7;
frameY[LB] = 5;
frameY[RB] = 4;
state = T_State::IDLE;
}
TitanSoul::~TitanSoul()
{
SafeDelete(walk);
SafeDelete(col);
SafeDelete(roll);
}
void TitanSoul::Update()
{
switch (state)
{
case T_State::IDLE:
Idle();
break;
case T_State::WALK:
Walk();
break;
case T_State::ROLL:
Roll();
break;
}
col->Update();
walk->Update();
roll->Update();
}
void TitanSoul::Render()
{
col->Render();
walk->Render();
roll->Render();
}
void TitanSoul::Idle()
{
LookAtTarget(INPUT->GetWorldMousePos());
Input();
//walk
if (moveDir != Vector2(0.0f, 0.0f))
{
state = T_State::WALK;
walk->ChangeAnim(ANIMSTATE::LOOP, 0.1f);
}
}
void TitanSoul::Walk()
{
LookAtTarget(INPUT->GetWorldMousePos());
Input();
//idle
if (moveDir == Vector2(0.0f, 0.0f))
{
state = T_State::IDLE;
}
//roll
if (INPUT->KeyDown(VK_SPACE))
{
state = T_State::ROLL;
roll->isVisible = true;
walk->isVisible = false;
roll->ChangeAnim(ANIMSTATE::ONCE, 0.1f);
rollTime = 0.6f;
}
col->MoveWorldPos(moveDir * 200.0f * DELTA);
}
void TitanSoul::Roll()
{
Input();
LookAtTarget(roll->GetWorldPos() + moveDir);
col->MoveWorldPos(moveDir * 500.0f * cosf((1.0f - rollTime / 0.6f) * DIV2PI) * DELTA);
//idle
rollTime -= DELTA;
if (rollTime < 0.0f)
{
state = T_State::IDLE;
roll->isVisible = false;
walk->isVisible = true;
}
}
void TitanSoul::LookAtTarget(Vector2 target)
{
Vector2 dir = target - col->GetWorldPos();
float radian = Utility::DirToRadian(dir);
if (radian > -DIV8PI && radian < DIV8PI)
{
dirState = R;
}
else if (radian > DIV8PI && radian < DIV8PI + DIV4PI)
{
dirState = RT;
}
else if (radian > DIV8PI + DIV4PI && radian < DIV8PI + DIV4PI * 2.0f)
{
dirState = T;
}
else if (radian > DIV8PI + DIV4PI * 2.0f && radian < DIV8PI + DIV4PI * 3.0f)
{
dirState = LT;
}
else if (radian > -(DIV8PI + DIV4PI * 3.0f) && radian < -(DIV8PI + DIV4PI * 2.0f))
{
dirState = LB;
}
else if (radian > -(DIV8PI + DIV4PI * 2.0f) && radian < -(DIV8PI + DIV4PI))
{
dirState = B;
}
else if (radian > -(DIV8PI + DIV4PI) && radian < -DIV8PI)
{
dirState = RB;
}
else
{
dirState = L;
}
walk->frame.y = frameY[dirState];
roll->frame.y = frameY[dirState];
}
void TitanSoul::Input()
{
moveDir = Vector2(0.0f, 0.0f);
if (INPUT->KeyPress('W'))
{
moveDir.y = 1.0f;
}
else if (INPUT->KeyPress('S'))
{
moveDir.y = -1.0f;
}
if (INPUT->KeyPress('A'))
{
moveDir.x = -1.0f;
}
else if (INPUT->KeyPress('D'))
{
moveDir.x = 1.0f;
}
moveDir.Normalize();
}
cpp파일입니다.
읽어주셔서 감사합니다.
'공부 > 2D과제' 카테고리의 다른 글
맵 만들기 (0) | 2023.02.01 |
---|---|
8방향 몬스터 (0) | 2023.01.30 |
쿠키런 2탄 : 착지, 젤리 먹기, 타격 (0) | 2023.01.25 |
쿠키런 1탄 : 달리기, 점프, 2단 점프, 슬라이드 (0) | 2023.01.20 |
슬라이드 퍼즐 (2) | 2023.01.18 |