플레이어 애니메이션
이번엔 비트맵이미지를 불러와 플레이어가 가만히있을때와 이동할때 애니메이션을 추가해보겠습니다.
비트맵 이미지 추가
우선 비트맵 매니저를 통해 이미지를 추가해줍니다. 수업에선 플레이어가 아래 위 왼쪽 오른쪽을 보고있는 이미지를 담고있는 4개의 스프라이트를 사용하였습니다.
CBitmap_Manager::Get_Instance()->Insert_Bitmap(L"../Image/Player/Player_DOWN.bmp", L"Player_DOWN");
CBitmap_Manager::Get_Instance()->Insert_Bitmap(L"../Image/Player/Player_LEFT.bmp", L"Player_LEFT");
CBitmap_Manager::Get_Instance()->Insert_Bitmap(L"../Image/Player/Player_RIGHT.bmp", L"Player_RIGHT");
CBitmap_Manager::Get_Instance()->Insert_Bitmap(L"../Image/Player/Player_UP.bmp", L"Player_UP");
MainApp의 레디에서 CBitMap_Manager를 통해 이미지를 4개 추가해줍니다.
프레임 구조체
typedef struct tagFrame
{
int iFrameStart; //애니메이션의 시작시간 입니다 기본값 0으로 설정합니다
int iFrameEnd; //애니메이션의 끝점 입니다 각 애니메이션마다 장수가 다르기때문에 이렇게 사용합니다.
int iFrameState; // 현재 상태를 저장해놓는 변수입니다
DWORD dwFrameSpeed;
//GetTickCount를 통해 시간값을 불러오고 이를통해 프레임을 제어해줍니다
DWORD dwFrameTime;
// 프레임의 시간을 저장해놓는 변수입니다 GetTickCount를통해 초기화 합니다.
}FRAME;
애니메이션에 사용하기위한 정보를 담을 구조체 tagFrame을 선언해줍니다.
플레이어클래스 변수 추가
다음은 플레이어 클래스에 애니메이션을 구현하기위한 변수를 추가해줍니다.
public:
enum STATE {IDLE, WALK, ATTACK, HIT, DIE};
// 상태를 표시하기위한 열거체입니다. 예제로 우선 IDLE과WALK를 만들어봅니다.
private:
FRAME m_tFrame; //프레임 구조체를 통해 정보를 관리합니다
TCHAR* m_pFrameKey; //프레임키로 저장한 이미지를 불러옵니다
STATE m_eCurState; //FSM을이용해 상태변경을 관리하기위한변수입니다.
STATE m_eNextState; //FSM을이용해 상태변경을 관리하기위한변수입니다.
변수를 추가해주었다면 Ready부분에서 변수를 초기화해줍니다.
m_pFrameKey = L"Player_DOWN";
m_tFrame.iFrameStart = 0;
m_tFrame.iFrameEnd = 3;
m_tFrame.iFrameState = 0;
m_tFrame.dwFrameSpeed = 100;
m_tFrame.dwFrameTime = GetTickCount();
플레이어 함수 추가
다음으로 플레이어 클래스에 프레임을 증가시키는 함수와 상태를 변경해주는 함수 2개를 구현해줍니다.
void MoveFrame();
void Change_State();
MoveFrame()
void CPlayer::MoveFrame()
{
if (m_tFrame.dwFrameTime + m_tFrame.dwFrameSpeed < GetTickCount())
{
++m_tFrame.iFrameStart;
m_tFrame.dwFrameTime = GetTickCount();
}
if (m_tFrame.iFrameStart > m_tFrame.iFrameEnd)
m_tFrame.iFrameStart = 0;
}
dwFrameTime + m_tFrame.dwFrameSpeed 과 현재시간을 비교해 프레임을 증가 시켜준후 만약 FrameStart가 End를 넘어갔다면 0으로 다시초기화 해줍니다. 이를통해 4장의 이미지가 반복해서 출력될것입니다.
ChangeState()
플레이어의 행동에따라 상태를 변경해줄 함수를 구현합니다.
void CPlayer::Change_State()
{
if (m_eCurState != m_eNextState)
{
switch (m_eNextState)
{
case CPlayer::IDLE:
m_tFrame.iFrameStart = 0;
m_tFrame.iFrameEnd = 3;
m_tFrame.iFrameState = 0;
m_tFrame.dwFrameSpeed = 100;
m_tFrame.dwFrameTime = GetTickCount();
break;
case CPlayer::WALK:
m_tFrame.iFrameStart = 0;
m_tFrame.iFrameEnd = 5;
m_tFrame.iFrameState = 1;
m_tFrame.dwFrameSpeed = 100;
m_tFrame.dwFrameTime = GetTickCount();
break;
case CPlayer::ATTACK:
m_tFrame.iFrameStart = 0;
m_tFrame.iFrameEnd = 5;
m_tFrame.iFrameState = 2;
m_tFrame.dwFrameSpeed = 100;
m_tFrame.dwFrameTime = GetTickCount();
break;
case CPlayer::HIT:
break;
case CPlayer::DIE:
break;
default:
break;
}
m_eCurState = m_eNextState;
}
}
FSM을통해 현재 상태와 다음 상태를 비교해 그에따른 m_tFrame값을 변경해줍니다.
앞에 구현한 두함수는 Late_Update에서 반복해서 호출되도록해줍니다
키입력 부분 변경
이제 키입력에따라 플레이어의 다음상태를 변경해주면 됩니다.
int CPlayer::Update_GameObject()
{
//각각 방향에 해당하는 프레임키로 변경해주고
//다음 상태를 WALK로 설정해줍니다.
if (GetAsyncKeyState(VK_LEFT) & 0x8000)
{
m_tInfo.fX -= m_fSpeed;
m_pFrameKey = L"Player_LEFT";
m_eNextState = WALK;
CScroll_Manager::Set_ScrollX(m_fSpeed);
}
else if (GetAsyncKeyState(VK_RIGHT) & 0x8000)
{
m_tInfo.fX += m_fSpeed;
m_pFrameKey = L"Player_RIGHT";
m_eNextState = WALK;
CScroll_Manager::Set_ScrollX(-m_fSpeed);
}
else if (GetAsyncKeyState(VK_UP) & 0x8000)
{
m_tInfo.fY -= m_fSpeed;
m_pFrameKey = L"Player_UP";
m_eNextState = WALK;
CScroll_Manager::Set_ScrollY(m_fSpeed);
}
else if (GetAsyncKeyState(VK_DOWN) & 0x8000)
{
m_tInfo.fY += m_fSpeed;
m_pFrameKey = L"Player_DOWN";
m_eNextState = WALK;
CScroll_Manager::Set_ScrollY(-m_fSpeed);
}
else
m_eNextState = IDLE;
//키 입력이 들어오지 않을땐 IDLE로 해줍니다.
if (GetAsyncKeyState(VK_SPACE) & 0x8000)
m_bIsJump = true;
return OBJ_NOEVENT;
}
Author And Source
이 문제에 관하여(플레이어 애니메이션), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jacod2/플레이어-애니메이션저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)