본 포스트는 JS(TS)로 캐릭터 이동 및 점프를 구현하는 방법을 기록하는 포스트입니다.
🧐 점프에 중력 적용
캐릭터가 점프 할 때는 등속도 운동보다는 포물선 운동처럼 중력의 영향을 받아서 상승 중에는 점점 느려지고, 하강 중에는 점점 빨라지는 것이 더 자연스럽습니다.
구현 방법은 현재 위치 = (현재 위치 - 목적지 높이) / n1 + n2
를 목적 높이에 도달할 때까지 반복적으로 더해주는 것입니다.
일단 임시로 현재 위치
는 600, 목적지 높이
200, n1
은 10, n2
는 0으로 가정해보겠습니다. ( n1
과 n2
는 임의의 숫자 )
첫 번째 계산에서는 (현재 위치 - 목적지 높이)
를 계산해서 400 즉, 총이동 거리가 계산됩니다. 그리고 / 10
을 통해서 총 40
이 나옵니다.
두 번째 계산에서는 360 / 10
=> 36
, 다음 계산에서는 324 / 10
=> 32.4
와 같은 형식으로 계산이 반복됩니다.
즉, 목적지에 가까워질수록 이동하는 거리가 짧아져서 점점 느려지는 효과를 볼 수 있습니다.
하지만 최종 목적 높이인 200에 점점 가까워지는 것이지 200에 도달할 수는 없기 때문에 n2
를 이용해 적당한 수치를 더해서 400에 도달할 수 있게 구성했습니다.
또한 점프의 간격은 n1
를 이용해서 조절할 수 있습니다.
그리고 상승 중일 때 사용했던 이동 거리들 ( 위 예시에서 40
, 36
, 32.4
… )을 배열에 기록해놓고 하강할 때 반대로 사용해서 점점 빨라지는 효과를 구현했습니다.
동작 예시는 아래
codepen
에서 볼 수 있습니다.
🤔 캐릭터 이동 및 점프 동시 동작 구현 방법
codepen
의 예시가 안보인다면0.25X
를 클릭하면 됩니다.
또한 아래 예시는 실제 코드에서 축약한 코드입니다.
1. 기존 방법 ( 동시 동작 ❌ )
keydown
으로 현재 누른key
를 저장함keyup
으로 현재 누른 키가 떼졌을 경우key
를 제거함requestAnimationFrame()
으로key
에 맞는 동작을 수행함 ( 방향키 => 움직임, 스페이스바 => 점프 )
기존에는 위의 방식대로 코드를 구성했습니다. 위 방식에서는 좌/우 이동의 경우에는 문제없이 동작했지만, 점프 기능이 들어가는 순간 문제가 발생했습니다. 우측으로 움직이면서 점프해야 하는 동시 동작이 필요한데 방향키를 누르다가 점프를 하게 되면 방향키는 무시하고 점프만 실행되는 문제가 발생했습니다. 즉, 이전에 클릭하던 key
는 무시되고 마지막으로 누른 key
만 정상 동작하는 문제가 발생했습니다.
keydown
/keyup
의 e.key
를 사용하는데 이벤트를 조금 더 살펴보니 하나의 키를 누른 상태에서 다른 키를 누르게 되면 기존 키 누름을 입력받지 않는 것으로 확인했습니다. 지금 저의 상황에서는 동시에 키를 눌렀을 경우 두 개의 키를 모두 사용해야 하는데 그게 안 돼서 해결 방법을 고민했습니다.
2. 수정한 방법 ( 동시 동작 ⭕ )
생각보다 간단하게 문제를 해결할 수 있었습니다.
핵심은 keydown
을 실행하면 반드시 keyup
을 실행되는 구조를 이해하는 것입니다.
즉, a
라는 키를 누르는 순간과 누르고 있는 경우 계속 keydown
이 발생합니다. 그리고 다른 키를 누르면 keydown
의 e.key
가 다른 값으로 변합니다. 하지만 a
라는 키를 떼는 순간 keyup
이 발생하기 때문에 keydown
시점에 키를 기록하고 keyup
시점에 키를 제거하는 방식을 사용했습니다.
특정 object
를 만들고 해당 object
에 keydown
의 시점에 누른 키를 기록하고 keyup
의 시점에 누른 키를 제거하는 방식을 사용했습니다.
이렇게 되면 keydown이 발생하고 나서 keyup이 발생하는 동안은 object
에 누른 키 값이 기록되게 됩니다.
따라서 해당 object
에 키 값이 들어가 있다면 계속 눌려져 있는 상태로 인식하도록 생각하고 애니메이션이 진행되도록 코드를 작성했습니다.
점프하면서 걷는 모션은 이미지 스프라이트를 편집하고나서 해결하고, 바닥에 떨어지지 않는 문제도 해결할 예정입니다.