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.