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

물리엔진 - 벽 충돌 part2. 좌우 벽 구현 본문

DEV/Direct2D

물리엔진 - 벽 충돌 part2. 좌우 벽 구현

F.R.I.D.A.Y. 2021. 5. 14. 12:46
반응형

 

물리엔진 - 벽 충돌 part1. 바닥 구현

 이전 시간의 중력 구현에 이어 이번에는 지나갈 수 없는 벽을 구현해봅니다. 벽  물리엔진을 구성하다보니 주로 게임에 빗대는 경우가 많은데, 벽이라 함은 물체가 뚫고 지나갈 수 없는 것을

pang2h.tistory.com

 위 시리즈와 연계해 작성합니다. 프로젝트 코드는 다음에서 이어집니다.


Index

  • 좌우 벽 충돌
  • 생각해보기

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


좌우 벽 충돌copy^

 플래시 게임 등에서 바닥을 형성한 것 외에 추가로 구현한 것이 있습니다. 좌우로 벽을 만났을 때 캐릭터가 이동하지 못하도록 하는 것입니다. 이것 또한 Calculate 메서드에서 처리하면 구현할 수 있습니다.

 

 <벽 충돌 part.1 바닥 구현>과 방향만 다르지 동일한 내용이기 때문에 해당 코드를 참고해 역으로 계산하면 수비게 코드를 작성할 수 있습니다.

 

 또한, 좌우 이동은 서로 상반된 명령이기 때문에 연산 간소화를 위하 처음에 분기를 통해 연산 규모를 줄입니다.

if(moveSpeed < 0.f){

}

 위 분기는 캐릭터가 좌측으로 움직이려할 때의 연산입니다. 그 안에 추락하는 코드와 유사하게 코드를 작성해주면 됩니다.

if (moveSpeed < 0.f) {
    for (size_t i = 0; i < cGround; ++i) {
        if (!(ground[i].top < rcCenter.y + rcSize.height / 2.f && 
            rcCenter.y - rcSize.height / 2.f < ground[i].bottom)) continue;
            // y축 위치가 맞지 않는 애들 제외

        if (rcCenter.x - rcSize.width / 2.f < ground[i].right) continue;
            // 위치보다 우측에 있는것들 제외

        if (abs(ground[i].right - rcCenter.x - rcSize.width / 2.f) < 0.001f) { 
            // 맡닿은 벽이 있으면 중단 중단
            moveSpeed = 0.f;
            break;
        }
        
        if (rcCenter.x - rcSize.width / 2.f + moveSpeed < ground[i].right) { 
            // 이동속도보다 간격 없으면 그 차이를 이동속도로 수정
            float gap = ground[i].right - rcCenter.x + rcSize.width /2.f;
            moveSpeed = gap;
        }
    }
}

 이 코드에서는 바닥으로 작용하는 벽은 상관하지 않는데, 두 번째 if 분기에서 벽의 우측 값이 현재 위치보다 높기때문에 알아서 빠져나갑니다.

 

 이 코드를 구현하면 아래 영상에서 보는 것과 같이 좌측에서 우측으로 갈 때는 벽을 무시하지만, 우측에서 좌측으로 갈 때는 벽의 영향을 받는다는 것을 알 수 있습니다.

 

 좌측에서 우측으로 이동하는 것에도 영향을 주려면 우측에서 좌측으로 이동하는 코드에 반대로 동작하면 됩니다.

if (moveSpeed < 0.f) {
    ...
}
else if(moveSpeed > 0.f) {
    for (size_t i = 0; i < cGround; ++i) {
        if (!(ground[i].top < rcCenter.y + rcSize.height / 2.f && rcCenter.y - rcSize.height / 2.f < ground[i].bottom)) continue;
        // y축 위치가 맞지 않는 애들 제외
        
        if (ground[i].left < rcCenter.x + rcSize.width / 2.f) continue;

        if (abs(rcCenter.x + rcSize.width / 2.f - ground[i].left) < 0.001f) {
            moveSpeed = 0.f;
            break;
        }

        if (ground[i].left < rcCenter.x + rcSize.width / 2.f + moveSpeed) {
            float gap = ground[i].left - (rcCenter.x + rcSize.width / 2.f);
            moveSpeed = gap;
        }

    }
}

 

 동일한 방식으로 위쪽으로 점프할 때 벽을 만나면 통과하지 못하도록 구성할 수 있습니다.

 

 

생각해보기copy^

 

물리엔진 - 점프 구현하기

 이전 시간에는 캐릭터가 바닥을 만났을 때, 더이상 아래로 내려가지 않도록 했습니다. 이번에는 점프를 구현해보겠습니다. 점프 구현  단순히 만들면 그냥 키 입력을 받았을 때 이동속도로 음

pang2h.tistory.com

 해당 포스트의 코드와 함께 구현을 했다면, 특정 상황[1]에서 벽으로 인식한 대상을 넘어서는 문제가 발생합니다. 해당 문제는 이동하는 곳의 시점을 정확하게 체크하지 않고, 한 곳[2]을 빠트렸기 때문에 발생합니다.

 

728x90
반응형

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

지뢰찾기 - 그리기 툴  (0) 2021.07.03
지뢰찾기  (0) 2021.06.28
물리엔진 - 좌우 이동  (0) 2021.05.14
물리엔진 - 점프 구현하기  (0) 2021.05.13
물리엔진 - 벽 충돌 part1. 바닥 구현  (0) 2021.05.11