F.R.I.D.A.Y.

물리엔진 - 좌우 이동 본문

DEV/Direct2D

물리엔진 - 좌우 이동

F.R.I.D.A.Y. 2021. 5. 14. 01:47
반응형

 바로 전 시리즈에선 바닥 구현을 했습니다. 좌우로만 이동하면 이제 제대로 된 캐릭터 이동이 가능해지겠네요.

 


Index

  • 프로젝트 업데이트
  • 캐릭터 조작
  • 최종 코드
  • 다음 예고

Script from F.R.I.D.A.Y


프로젝트 업데이트copy^

 이번 포스트부터는 기존 제공한 프로젝트와 해당 프로젝트로 구성한 중력구현 등을 포함한 버전의 새로운 프로젝트를 사용합니다. 프로그램 사용이 보다 접근성이 높아야 흥미를 느낄 수도 있을것 같아 몇가지 기능을 추가했으니 참고해주세요.

PhysicsEngine.zip
0.01MB

 본 파일에 추가된 기능/소스코드는 다음과 같습니다.

  • 마우스 좌측버튼 및 마우스 끌기로 블럭 형성이 가능합니다.[1]
  • 마우스 우측버튼으로 형성된 블럭을 삭제할 수 있습니다.[2]

 

캐릭터 조작copy^

 캐릭터는 좌/우로 이동합니다. 이제 그 과정을 만들어보도록 하겠습니다. 키 입력에 대한 정보는 keyState 멤버로 바인딩되어 있으므로 키 입력과 관련해 수정을 할 필요는 없습니다.

 

 좌측 이동은 x값이 감소하는 방향입니다. 마찰력이 100%인 상태. 즉, 키 입력을 해제했을 때 즉시 멈추는 밀리지는 현상이 없는 상태로 구성할것입니다.

 

 Calculate 메서드에 아래 내용을 추가합니다.

static float moveSpeed = 5.f;

 

 그 다음, 점프 구현 다음 영역에 아래와 같은 코드를 입력해줍니다.

if (keyState[VK_LEFT]) moveSpeed = -5.f;
else moveSpeed = 0.f;

 하지만 이렇게 코드를 구성하면 제대로 동작하지 않을겁니다. 좌우측 이동은 서로 연관되어 있습니다. 때문에 좌우측을 연계해서 판단해주어야 합니다.

 

 우리가 고려해야할 사안은 이겁니다.

  • 좌우측 버튼이 함께 눌렸을 때는 움직이지 않을것
  • 좌우측 버튼중 하나라도 눌리지 않았을 때 움직이지 않을것
  • 좌측 버튼이 눌리면 x값을 뺄 것
  • 우측 버튼이 눌리면 x값을 더할 것

 이 때, 첫 번째 옵션과 두 번째 옵션은 합치는 것이 가능합니다.

if (keyState[VK_LEFT] == keyState[VK_RIGHT]) moveSpeed = 0.f;
else if (keyState[VK_LEFT]) moveSpeed = -5.f;
else if (keyState[VK_RIGHT]) moveSpeed = 5.f;

 

 keyState[VK_LEFT]와 keyState[VK_RIGHT]의 값이 모두 0[3]이거나 1[4]이면 moveSpeed는 0이 되고, 이 경우가 아닌 경우 각 상황에 맞게 moveSpeed를 옮겨줍니다.

 

 그리고 마지막 rcCenter에 x값에 moveSpeed를 더해줍니다.

rcCenter.x += moveSpeed;

 

최종 코드copy^

 이렇게 구성하면 이제 좌우 이동이 가능한 캐릭터를 구성할 수 있습니다. 이동 속도는 moveSpeed 값을 수정해 조절할 수 있겠네요.

void MainWindow::Calculate()
{
    static float gravity = 4.3f;
    static float dropSpeed = 0.f;
    static float moveSpeed = 5.f;
    if (canJump && keyState[VK_SPACE]) {
        dropSpeed = -30.f;
        canJump = false;
    }
    else {
        dropSpeed += gravity;
    }

    if (keyState[VK_LEFT] == keyState[VK_RIGHT]) moveSpeed = 0.f;
    else if (keyState[VK_LEFT]) moveSpeed = -10.f;
    else if (keyState[VK_RIGHT]) moveSpeed = 10.f;

    if (dropSpeed >= 0.f) {
        for (size_t i = 0; i < cGround; ++i) {
            if (!(ground[i].left < rcCenter.x + rcSize.width/ 2.f && 
                rcCenter.x - rcSize.width / 2.f < ground[i].right)) continue;

            if (ground[i].top < rcCenter.y + rcSize.height / 2) continue;

            if (abs(ground[i].top - rcCenter.y - rcSize.height / 2) < 0.001f) {
                dropSpeed = 0.f;
                canJump = true;
                break;
            }

            if (rcCenter.y + rcSize.height / 2 + dropSpeed > ground[i].top) {
                float gap = ground[i].top - rcCenter.y - rcSize.height / 2.f;
                dropSpeed = gap;
            
            }

        }
    }

    rcCenter.x += moveSpeed;
    rcCenter.y += dropSpeed;
}

 

다음 예고copy^

 영상을 보면 만들어진 블럭 위에 있을 수는 있지만, 블럭 위에 존재하지 않는다면 지나다닐 수 있네요. 약간 맞지 않는 것 같습니다. 그래서 다음번엔 블럭을 지나치지 못하도록 만들어보겠습니다.

 

728x90
반응형

'DEV > Direct2D' 카테고리의 다른 글

지뢰찾기  (0) 2021.06.28
물리엔진 - 벽 충돌 part2. 좌우 벽 구현  (0) 2021.05.14
물리엔진 - 점프 구현하기  (0) 2021.05.13
물리엔진 - 벽 충돌 part1. 바닥 구현  (0) 2021.05.11
물리엔진 - 중력 구현 안정화  (0) 2021.05.10