2D에서 코너 충돌을 처리하는 방법은 무엇입니까?


22

하향식 2D XNA 게임을 작성 중입니다. 처음부터 물리와 충돌을 직접 작성하여 배우려고합니다.

플레이어 스프라이트 캐릭터가 경계가 벽의 가장자리와 교차하는 위치로 이동하려고 할 때마다 바운스 각도 (입사각 = 반사각)를 알아 내고 플레이어를 벽에서 튕겨 충돌을 피합니다 .

두 개의 벽 모서리와 동시에 교차하는 스프라이트의 상황을 처리하는 방법을 알아내는 데 어려움이 있습니다.

코너 충돌

내 코드는 현재 두 개의 벽 모서리가 교차되었지만 어느 모서리가 먼저 닿았는지, 따라서 어느 모서리가 튀어 나올지를 알려주지 않습니다.

바운스 할 가장자리를 선택하기위한 수학적 테스트는 무엇입니까? 그것을 볼 때 보는 것은 분명하지만 나는 그것을위한 수학 시험을 알아 내려고 고심하고 있습니다.



감사합니다 Tetrad. 나는 그것을 보았지만 공이 내 직사각형 문제와 다르게 행동하는 것처럼 보였습니다. 위의 그림에서 직사각형 스프라이트는 벽의 아래쪽 가장자리에 닿아 튀어 나왔을 것입니다. 벽의 측면 모서리는 절대로 방정식에 들어오지 않았을 것입니다. 코드로 표현하고 결정하는 방법을 모르겠습니다.
TerryB

답변:


9

당신은 얼마나 멀리로 계산하면 이동, 당신은 아마는 x의 델타와 교차하는 모서리의 y 좌표에 기초 할 수있다. 나는 그것이 말이되는 더 나은 방법을 생각할 수없는 의미가 있기를 바랍니다.WallPlayer Sprite

예를 들어 다이어그램을 보면 테이크 x의 왼쪽 상단의 값 Player Sprite(이동 후를) 및 빼기 x의 오른쪽 하단 모서리의 가치를 Wall. y값에 대해 동일한 작업을 수행 한 후 더 큰 값을 확인하십시오. 핵심은 하나가 다른 것보다 크면 Player Sprite아마도 그면에서 교차한다는 것입니다.

다음은 이미지 예입니다 (이것은 내 선이 추가 된 이미지의 하위 섹션입니다).

교차점 예

이제 파란색 선이 녹색 선보다 큽니다. 이 경우 파란색 선은 또한 Player Sprite튀어 나올 것으로 예상되는 측면 에 있습니다.

두 값이 같으면 모퉁이에 맞습니다.

이제 이런 식으로하는 데 약간의 문제가 있습니다. (가) 경우 Player Sprite매우 빠른 여행 또는 충돌이 매우 가까운 코너입니다, 그것은이있을 가능성이 Player Sprite에 더 이상 갈 수 있습니다 Wall잘못된 방향으로. 이 경우 움직이는 물체의 속도를 확인해야 할 것입니다. ( Nathan Reed의 답변 참조 )

참고 : 필자는 @Blau이 언급 한 SAT 충돌 감지를 본질적으로 설명하려고한다고 생각하지만, 이것을 작성하는 데 오랜 시간을 보냈으므로 어쨌든 게시 할 것입니다. 잘하면 그것은 당신에게 도움이 될 것입니다.


감사합니다 Drackir! 그리고 내 벽이 스프라이트를 기준으로 회전하면 조금 까다 롭지 만 동일한 원리가 적용됩니다. 스프라이트가 벽과 충돌하지 않음을 의미하는 최소 길이 변위 벡터를 찾으십시오. 그런 다음 해당 벡터에 수직 인 벽을 바운스로 사용하십시오.
TerryB

@TerryB-회전은 조금 더 복잡합니다. 축 정렬 경계 상자 (AABB)를 읽을 수 있습니다. 기본적으로 회전 된 객체가 들어갈 수있는 가장 작은 상자를 테스트하지만 축이 데카르트 축에 맞춰 정렬되어있어 위와 동일한 원리를 사용합니다. 정사각형이 있고 45도 회전하여 다이아몬드로 만들었다 고 상상해보십시오. 충돌을 계산하는 것은 어렵고 비용이 많이들므로 먼저 다이아몬드의 각 점이 중간의 각면에 닿는 사각형 인 AABB를 사용하여 물체가 물체 근처에 있는지 확인하십시오.
Richard Marskell-Drackir

그런 다음 근처에 있음을 알면 각도와 교차하는지 확인하기 위해 더 많은 비용이 드는 계산을 수행 할 수 있습니다 (아마도 다른 질문 일 것입니다 :)).
Richard Marskell-Drackir

1
최소 변위가 항상 "어느 가장자리 충돌"에 대한 정답을 제공하지는 않기 때문에 -1; 내 대답을 참조하십시오.
Nathan Reed

@NathanReed-이것이 "이제 이렇게하는 데 약간의 문제가 있습니다"단락에서 속도 확인을 언급 한 이유입니다.
Richard Marskell-Drackir

15

최소 변위가 어느 모서리가 먼저 눌 렸는지 항상 올바른 답을 제공 하지는 않습니다 . 이 경우를 고려하십시오.

최단 변위 알고리즘을 깨는 경우

이것은 한 프레임 동안 블록이 다소 멀리 이동할만큼 속도가 높을 때 발생합니다. 어떤 모서리가 먼저 눌 렸는지 정확하게 감지하려면 각 모서리와의 충돌 시간을 해결하기 위해 선형 방정식을 설정해야합니다. 이 경우 OP 다이어그램에 설명 된 관련 방정식은 다음과 같습니다.

timeXCollision = (player.left - wall.right) / -player.velocity.x
timeYCollision = (wall.bottom - player.top) / player.velocity.y

(이것은 X- 오른쪽, Y- 업 좌표계를 가정 한 것입니다.) 일반적으로 player.velocity의 X 및 Y 구성 요소의 부호를 사용하여 테스트해야 할 에지 쌍을 결정해야합니다. 어쨌든 일단 충돌 시간이 계산되면 두 가지 중 가장 빠른 것이 처리해야 할 충돌입니다.


1
두 변수를 어떻게 구현할 수 있는지에 대한 예를 들어 주시겠습니까?
BjarkeCK

1

SAT 충돌 감지 가 필요합니다

기본적으로 객체 중 하나에 뺄셈 된 최소 변위 벡터를 찾아서 교차하지 않도록해야합니다.

이미지에서 최소 변위는 주황색 세그먼트입니다.

여기에 이미지 설명을 입력하십시오


4
최소 변위가 항상 "어느 가장자리 충돌"에 대한 정답을 제공하지는 않기 때문에 -1; 내 대답을 참조하십시오.
Nathan Reed

누가 물어 보니?
Blau

문제는 그것을 묻는 것입니다. "내 코드는 현재 두 개의 벽 모서리가 교차되었지만 어느 모서리가 먼저 닿았 는지, 따라서 어느 모서리가 튀어 나오지 않았는지 알려줍니다 ."
Nathan Reed

먼저? 문제는 첫 번째가 아니며, 두 가장자리와 동시에 충돌합니다. 문제는 어느 가장자리가 튀어 나올지에 대한 것입니다. 당신에게 적합한 한 가지 방법을 선택했습니다. 나는 다른 방법을 선택했습니다. 나에게 좋은, 둘 다 유효합니다
Blau

1
구석에서 둥글거나 구부러진 것처럼 물체가 서로 미끄러지도록 디자인 결정을 내리고 싶다면 이것이 결정이며 게임 플레이에 적합한 것일 수도 있습니다. 그러나 디자인 결정에 대한 질문은 없다고 생각합니다. 축 정렬 사각형을 서로 바운스하는 방법을 수학적 으로 묻습니다 . 이것은 해석의 문제가 아니다. 이 수학 문제는 어느 가장자리에서 튀어 나올지에 대한 명확하고 정확한 답변을 제공합니다.
Nathan Reed

0

비슷한 질문에 답변 했습니다

이전 위치 확인을 고려할 수도 있습니다.

예를 들어 왼쪽이 오른쪽의 오른쪽에 있고 충돌하는 경우 오른쪽 충돌이 발생했습니다.

이 작업을 수행하면 y 축 충돌 만 해결하고 충돌이 있는지 확인한 다음 x 축 충돌을 해결하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.