본문 바로가기

개발 프로젝트/Win32 - VampireSurvivor 모작

로그라이크 게임 구현 1주차(4)

이번 글에선 부드러운 움직임 구현에 관해 적겠다.

https://pang2h.tistory.com/375

 

Win32 - 키보드 입력으로 사각형 움직이기

 키보드 입력으로 사각형을 움직여봅니다. # Win32 프로그래밍을 이해하고 있어야합니다. # 알지 못하는 경우 여기에서부터 시작할 것을 권장합니다. # 본 문서는 Direct2D 기반으로 구현합니다. Win3

pang2h.tistory.com

내가 MFC수업을 들을 땐 키보드 처리를 '키보드 다운 윈도우 메세지' (WM_KEYDOWN)에서 처리하게끔 구현했다

그런데 이러한 방법으로 처리하면 부드럽게 움직이지 않는다.

 

1.........111111111111111

지금 한번 시도해보자.

1을 꾹 누르면 1이 따따따딱 바로 찍히는게 아니라

처음 누르고 얼마 지나서 연속적으로 찍히기 시작한다.

위에 내가 예시로 든 것처럼 말이다.

 

WM_KEYDOWN 메세지는 키보드 명령이 입력 되었을 때 받는 메세지이다.

그런데 키보드를 꾹 누른다면 앞에서 예시를 든 것처럼 잠깐의 텀이 생긴다.

이를 우회하기 위해 키보드를 누르는 행위(WM_KEYDOWN 메세지를 발생하는 행위)와

키보드 메세지 처리를 분리할 필요가 있다.

 

static bool keyLayout[256];

 

 case WM_KEYDOWN:
    {
        keyLayout[wParam] = 1;
        
        break;
    }

 

 

void CharacterMoveFun()
{
    POINT newPoint;
    if (keyLayout[VK_LEFT] == keyLayout[VK_RIGHT])
        newPoint.x = 0;
    else if (keyLayout[VK_LEFT])
        newPoint.x = -7;
    else 
        newPoint.x = +7;


    if (keyLayout[VK_UP] == keyLayout[VK_DOWN])
        newPoint.y = 0;
    else if (keyLayout[VK_UP]) {
        newPoint.y = -7;
        if (keyLayout[VK_LEFT]) {
            newPoint.x = -5;
            newPoint.y = -5;
        }
        else if (keyLayout[VK_RIGHT]) {
            newPoint.x = 5;
            newPoint.y = -5;
        }
    }    
    else {
        newPoint.y = +7;
        if (keyLayout[VK_LEFT]) {
            newPoint.x = -5;
            newPoint.y = 5;
        }
        else if (keyLayout[VK_RIGHT]) {
            newPoint.x = 5;
            newPoint.y = 5;
        }

 

우리가 키보드를 누르면 그 키보드의 코드를 해석하여 bool 자료형의 배열에 저장한다.

그리고 그 bool 배열에 저장된 자료를 해석하고 키보드 명령을 수행한다.

 

이렇게 하면 키보드를 꾹 누르면 꾹 누른 키가 무엇인지만 판단한다. (keyLayout[wParam] = 1;)

그리고 키보드를 처리하는 함수는 메세지 처리 함수에서 처리하는게 아닌 버퍼링을 처리하는 함수에 넣으면 된다.

 

 while (!peekbool)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
            {
                peekbool = true;
            }
            else
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }

        if (dwTime + 32 < GetTickCount64() && bGameProgress)
        {
            dwTime = GetTickCount64();
            
            CharacterMoveFun();
            InvalidateRect(hwnd, NULL, TRUE);
        }

    }


    return 0;
}