충돌 감지 로직은 어디에 배치해야합니까?


19

작은 2D 게임 엔진을 개발 중입니다. 문자에는 현재 다음을 수행하는 페인트 방법이 있습니다.

  1. 속도 등에 따라 캐릭터의 새로운 위치를 계산하십시오.
  2. 충돌 그리드 셀 업데이트 **
  3. 새로운 위치에 캐릭터를 그리십시오

** 교차점 확인 횟수를 줄이기 위해 충돌 그리드를 만들었습니다.

이제 충돌을 감지하기 위해 생각한 기본 알고리즘은 다음과 같습니다.

For Each Character
    Check intersection with characters in surrounding 8 cells

이 코드를 페인트 방법에 간단히 넣을 수 있습니다. 그러나 여기에 내가 예상하는 문제가 있습니다.

두 문자 A와 B가 충돌 그리드의 인접한 셀에 있다고 가정합니다. 이제 문자 A의 반복에서 위의 알고리즘에 따라 B와 충돌 한 것을 감지합니다. 문자 B에 대한 반복에서 A와 충돌 한 것을 감지합니다.

그러나 A가 B와 충돌 한 것을 감지하면 B에게 A와 충돌했다는 사실을 알려야한다는 생각이 있습니다. 이렇게하면 두 명의 배우가 충돌 할 때 많은 비교가 필요합니다. 그러나 이것을 처리하는 방법을 모르겠습니다. 모든 캐릭터가 충돌을 확인하는 대신 게임 루프 내에서 충돌을 확인해야한다고 생각합니다.

이 접근법이 맞습니까? 이런 종류의 문제를 어떻게 처리 했습니까? 나는 충돌 그리드를 스스로 생각했다. 충돌 그리드 로직에 대한 대안이 있습니까?


나는 nitpick에 유감이지만, 2D 물리 라이브러리에 있습니다. 게임 물리학은 일반적으로 매우 근사치이므로 게임을 재생할 수 없게 만드는 솔루션은 훌륭하지만 올바르게 해결하려면 Box2D와 같은 특수 물리학을 사용하십시오 ... :-D
user712092

답변:


14

충돌 감지에 대한 일반적인 접근 방식은 A 또는 B가 자체적으로 충돌을 감지하지 않는 것입니다.

대신, 먼저 모든 객체를 이동 한 다음 별도의 충돌 시스템에서 모든 객체 쌍 사이의 충돌을 찾아 모든 객체에 충돌 한 사항을 알려주고 마지막으로 모든 객체를 렌더링합니다.

본질적으로 Paint () 함수 내에서 "이동, 충돌 확인, 그리기"를 수행하는 대신 "이동"및 "그리기"를 개별 호출하는 개별 함수 (먼저 모든 개체에 대해 "이동")로 분할 한 다음 모든 객체에 대해 "그리기"). 그리고 그 사이에 충돌이 있는지 확인하십시오.

고급 참고 : 물체 중 하나라도 감지 된 충돌에 반응하여 움직이면 물체의 충돌 응답으로 인해 다른 충돌이 발생하는 경우 "모든 쌍의 물체 사이의 충돌 찾기"단계를 반복해야 할 수도 있습니다.


이것이 올바른 일을하는 방법입니다. 물체가 자신의 책임을 처리하게하고 충돌 시스템은 장애물을 만날 때 발생하는 일을 결정해야합니다. 캐릭터 주변에 충돌 직사각형 / 실린더 (2d / 3d)를 일종의 초기 트리거로 사용할 수도 있습니다.
James P.

큰! 고급 음표와 관련하여 충돌에 반응하여 스스로 움직이는 물체와 충돌하는 물체에 대해서만 충돌을 다시 확인해서는 안됩니까? 검사 체인이 있지만 모든 객체의 충돌 검사를 피할 수 있습니다.
크래커


1

나는 당신이 말하는 것처럼 게임 루프의 모든 캐릭터에 대해 루프를 실행합니다.

내가하는 방식은 각 캐릭터의 상태를 유지하는 것이므로 A가 충돌을 확인하는 동안 A와 B가 충돌하면 A와 B가 적중으로 설정됩니다. B의 루프 시작 부분에서 id가 루프를 실행하지 않으면 이미 적중되었는지 확인합니다.

영향 코드를 루프에 넣었으므로 B에서 취해야 할 동작이 A의 루프에서 발생했기 때문에 충돌 결과를 엉망으로 만들 수 있으므로 B가 확인할 이유가 없습니다. .


그러나이 경우 A가 B와의 교차를 감지하면 B.hit이 true로 설정되므로 B는 모든 교차를 확인하지 않습니다. 그러나 다른 문자 C가 B와 교차하면 B가 감지하지 못합니까?
Cracker

미안 해요 A는 C와 교차하지 않으므로 C.hit은 여전히 ​​거짓입니다. B는 충돌을 확인하지 않습니다. 그러나 C는 B와 C 사이에 충돌이 있음을 확인하고 B에 정보를 전달합니다.
크래커

그러나 모든 A, B 및 C가 서로 교차하면 문제가 있다고 생각합니다. A는 B.hit과 C.hit을 true로 설정합니다. B와 C는 A와 충돌했다는 것을 알게 될 것입니다. 그러나 적중 속성이 true이므로 충돌을 확인하지 않습니다. B와 C의 충돌은 눈에 띄지 않게됩니다.
Cracker

모든 실행 가능한 충돌 객체를 일종의 컬렉션에 넣은 다음 컬렉션의 객체 다음에 오는 것들과의 충돌 만 검사하여 비슷한 방법으로 몰래 이동할 수 있습니다. IE : A 수표 대 B, C, D; B 검사 대 C, D; C 수표 대 D. 배후에서 이미 확인 했으므로 각각의 배후를 확인할 필요가 없습니다. 요소의 충돌을 완전히 건너 뛰는 것만 큼 빠르지는 않지만 그럼에도 유용합니다.
Lunin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.