플레이어 애니메이션

이번엔 비트맵이미지를 불러와 플레이어가 가만히있을때와 이동할때 애니메이션을 추가해보겠습니다.

비트맵 이미지 추가

우선 비트맵 매니저를 통해 이미지를 추가해줍니다. 수업에선 플레이어가 아래 위 왼쪽 오른쪽을 보고있는 이미지를 담고있는 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; 
}

좋은 웹페이지 즐겨찾기