ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Direct2D] 등속 운동, 등가속 운동, 중력 구현
    C++/미분류 2024. 5. 17. 18:08

    지난 글에서 게임의 프레임 레이트를 구하고, 이미지를 출력하고, 이미지를 방향키로 움직여보았습니다.

    [DirectX] QPC로 FPS(프레임 레이트) 구현하기
    [Direct2D] 비트맵 이미지 움직이기 (2)

    이번 글에서는 위 코드들을 기반으로 이미지가 아래로 떨어지는 기능을 구현해보겠습니다.

     


     

    0. OnRender함수 분리

     

    더보기

    기존 OnRender함수는 이미지의 위치를 업데이트 하는 기능과 렌더링 하는 기능을 모두 담당했습니다.

    이제 위치 등과 관련된 물리량을 업데이트 하는 기능을 분리하도록 하겠습니다.

     

    분리하는 함수는 Update라 명명하겠습니다.

    void MyApp::Update() {
        LARGE_INTEGER currentTime;
        QueryPerformanceCounter(&currentTime);
        FLOAT deltaTime = (FLOAT)(
            (DOUBLE)(currentTime.QuadPart - myPrevTime.QuadPart) / (DOUBLE)(myFrequency.QuadPart)
            );
        myPrevTime = currentTime;
    
        frameTime.push_back(deltaTime);
        while (frameTime.size() > frameAvgCount) frameTime.pop_front();
    
        FLOAT totalTime = 0.0f;
        for (auto& i : frameTime) {
            totalTime += i;
        }
        FLOAT frameRate = 1 / (totalTime / frameAvgCount);
        ...
    }

    분리된 Update함수는 OnRender 함수의 Tick을 기반으로 한 모든 기능을 담당합니다.

    위 코드는 deltaTime 및 프레임 레이트를 계산하는 코드이며, Tick 및 이동과 관련된 함수의 호출은 생략했습니다. 

     

    OnRender함수를 분리했으므로, 윈도우 프로시저에 Update함수를 호출하는 코드를 추가하겠습니다.

    ...
    case WM_PAINT:
        myApp->Update();
        myApp->OnRender();
        result = 0; wasHandled = true;
        break;
    ...

    윈도우 프로시저의 PAINT메시지에 Update함수를 호출하는 코드를 추가했습니다.

     

    1. 등속 운동 구현하기

     

    더보기

    등속 운동은 일정한 속도로 운동하는 것을 의미합니다.

    이 프로젝트에서는 이미 구현이 되어있는 운동으로, 지금까지 구현했던 모든 물체는 등속 운동을 하는 상태였습니다.

    따라서 낙하하는 운동에는 어울리지 않지만, 등가속 운동과 비교를 위해 등속 운동으로 낙하를 구현해보겠습니다.

     

    등속 운동은 이전 코드와 동일하게 고정된 속도와 deltaTime을 이용합니다.

    void MyApp::Update() {
        ...
        FLOAT downSpeed = 10.f;
        FLOAT downTick = downSpeed * deltaTime;
        myCharacterBitmap->Move(0, downTick);
        ...
    }

    위 코드는 초당 10의 속도로 이미지가 떨어지도록 합니다.

    방향키를 통해 움직이는 코드와 동일합니다.

     

    2. 등가속 운동 구현하기

     

    더보기

    등가속 운동은 가속도가 일정한 운동을 의미합니다.

    일정한 가속도를 지정하고, 그 가속도만큼 속도를 변화시키는 방식으로 구현하겠습니다.

    void MyApp::Update() {
        ...
        FLOAT downSpeed = 10.f;
        FLOAT gravity = 9.8f;
        downSpeed += gravity * deltaTime;
        FLOAT downTick = downSpeed * deltaTime;
        myCharacterBitmap->Move(0, downTick);
        ...
    }

    위 코드는 초기 속도가 10이고, 가속도가 9.8인 등가속 운동을 구현합니다.

    등속 운동에서 속도가 변화하는 것을 볼 수 있습니다.

     

    3. 개선점

     

    더보기

    두 가지 구현으로 이미지를 아래로 이동시켜봤습니다.

    중력이라는 느낌이 드는 구현은 등가속 운동이지만, 등속 운동 또한 상황에 따라 사용할 수 있습니다.

     

    또한 현실의 중력에 가까운 구현을 위해서는 고려해야 할 사항이 몇 가지 추가로 존재합니다.

    자유 낙하 운동의 경우 중력 뿐 아니라 공기저항 또한 고려해야 하며, 충돌 등 낙하 이후를 고려할 경우 물체의 질량 또한 고려해야 합니다.

     

    위 고려 사항에 더하여, 단순하게 이동량과 물리량을 시간에 따라 증, 감소시키는 방법 외에도 물리량의 변화량에 대한 여러 해석학적 접근을 통해 정확도를 올리는 방법도 생각할 수 있습니다.

     

    위 내용에 의한 개선은 이후 다른 글에서 다룰 수 있도록 하겠습니다.

     


     

    이번 글에서 사용된 전체 코드는 아래 Github에서 확인하실 수 있습니다.

     

    GitHub - ruru14/WinapiStudy: WinAPI및 DirectX를 공부하며, 간단한 운동 법칙을 적용해봅니다.

    WinAPI및 DirectX를 공부하며, 간단한 운동 법칙을 적용해봅니다. Contribute to ruru14/WinapiStudy development by creating an account on GitHub.

    github.com

     

    이번 글의 구현을 통해, 움직이는 이미지에 낙하하는 효과를 적용했습니다.

    하지만 아직 바닥이 구현되지 않아, 이미지가 화면 밖으로 나가는 현상이 발생합니다.

    다음 글에서는 바닥을 만들어 이미지의 낙하를 멈추는 방법을 알아보도록 하겠습니다.

     

    이번 글이 도움이 되셨기를 바랍니다.

    감사합니다.

    'C++ > 미분류' 카테고리의 다른 글

    [Direct2D] 점프 구현  (1) 2024.06.13
    [Direct2D] 충돌 및 지형 구현  (0) 2024.05.31
    [Direct2D] ID2D1Effect : Chroma key  (1) 2024.04.22
    [Direct2D] ID2D1Effect : Edge detection  (0) 2024.04.17
    [Direct2D] ID2D1Effect : Color matrix  (0) 2024.04.12

    댓글

Designed by Tistory.