충돌 사각형 응답


10

이동 가능한 사각형을 두 개 이상의 사각형과 충돌시키는 데 어려움이 있습니다.

SFML을 사용 하고 있으며 intersects2 개의 직사각형을 사용하여 교차점을 반환 하는 편리한 함수가 있습니다. 직사각형으로 가득 찬 벡터가 있는데 움직일 수있는 직사각형이 충돌하기를 원합니다. 다음 코드를 사용 하여이 과정을 반복하고 있습니다 (p는 이동 가능한 사각형입니다).

IsCollidingWith부울을 반환하지만 SFML을 사용 intersects하여 교차점을 해결합니다.

while(unsigned i = 0; i!= testRects.size(); i++){
   if(p.IsCollidingWith(testRects[i]){
        p.Collide(testRects[i]);
   }
}

실제 Collide()코드 :

void gameObj::collide( gameObj collidingObject ){

 printf("%f %f\n", this->colliderResult.width, this->colliderResult.height);

if (this->colliderResult.width < this->colliderResult.height) {
    // collided on X
    if (this->getCollider().left < collidingObject.getCollider().left ) {
        this->move( -this->colliderResult.width , 0);
    }else {
        this->move( this->colliderResult.width, 0 );
    }

}

if(this->colliderResult.width > this->colliderResult.height){
    if (this->getCollider().top < collidingObject.getCollider().top ) {
        this->move( 0, -this->colliderResult.height);
    }else {     
        this->move( 0, this->colliderResult.height );
    }

}

IsCollidingWith()코드는 다음 과 같습니다.

bool gameObj::isCollidingWith( gameObj testObject ){
if (this->getCollider().intersects( testObject.getCollider(), this->colliderResult )) {
    return true;
}else {
    return false;
}

Rect장면에 1 개만있을 때 제대로 작동합니다 . 그러나 둘 이상 Rect이 있으면 한 번에 2 개의 충돌을 해결할 때 문제가 발생합니다.

이것을 올바르게 처리하는 방법에 대한 아이디어가 있습니까? 내 문제를 보여주기 위해 YouTube비디오를 업로드 했습니다 . 가장 오른쪽의 콘솔은 교차점의 너비와 높이를 보여줍니다. 콘솔에서 한 번에 2 개의 충돌을 계산하려고한다는 것을 알 수 있습니다. 문제가 발생한 곳이라고 생각합니다.

마지막으로 아래 이미지는 내 문제를 훌륭하게 보여줍니다.

여러 개의 다른 사각형과 충돌하는 사각형


비디오 링크가 끊어졌습니다.
XiaoChuan Yu

인가 collider에 의해 반환 된 객체 this->getCollider()에 의해 갱신은 this->move()?
XiaoChuan Yu 23.34에

더 많은 정보를 추가해 주시겠습니까? 정확히 무엇이 문제입니까? YouTube 비디오는 예측 가능한 동작을 나타내는 것으로 보이며 장면에는 다른 사각형이 하나만 있습니다.
Wackidev

답변:


3

이미지는 볼록한 모양 (특히 직사각형)을 사용하여 바닥과 같은 평평한 표면을 시뮬레이션 할 때 발생하는 많은 문제 중 하나를 보여줍니다. 이 알고리즘은 캐릭터가 바닥을 구성하는 도형의 내부 가장자리에 붙어있게합니다.

이를위한 간단한 해결책은 수직 충돌 만 확인하고 수정 한 다음 수평 충돌을 다시 확인하는 것입니다. 넘어지지 않고 벽을 미끄러지려고하지 않는 경우에는 먼저 수평 충돌을 확인해야합니다. 언제 가장 먼저 확인할지 어떻게 알 수 있습니까? 속도의 어떤 구성 요소가 더 큰지에 따라이를 수행 할 수 있습니다 (수평 이동이 큰 경우 먼저 수직 충돌을 확인하고, 그렇지 않으면 수평 충돌을 확인).

더 간단하고 성능이 뛰어난 것은 대신 세상의 가장자리 목록을 생성하는 것입니다. 즉, 바닥을 구성하는 상자의 경우 상단 모서리 만 실제로 충돌 할 수 있음을 나타내는 플래그를 설정 한 다음 다른 모서리와의 충돌을 무시합니다. SFML의 충돌 루틴을 사용할 수는 없지만 솔직히 단순히 박스 충돌은 게임에서 작성할 수있는 가장 쉬운 코드입니다. 이 기술은 월드가 그리드에 정렬 된 경우 특히 효과적입니다. 해당 기술에 대한 우수한 메타넷 자습서 (http://www.metanetsoftware.com/technique.html/)를 확인합니다.

당신은 당신과 같은 간단한 2D 플랫 포머 게임을 구축하려고 다른 많은 문제에 부딪 칠 것입니다. 지금까지 내가 본 가장 좋은 리소스는 다음과 같습니다.이 리소스를 읽고 다시 읽습니다.

http://higherorderfun.com/blog/2012/05/20/the-guide-to-implementing-2d-platformers/



0

2 개의 충돌을 계산하는 것이 문제가 아니라 성능 문제라고 생각합니다. 충돌을 올바르게 처리하려면 두 번 테스트해야 할 수도 있습니다. 다이어그램을 사용하여 A가 먼저 B에 대해 테스트되는지 생각하면 다른 상자에 대해서도 테스트해야하며 다른 상자와 충돌 할 수 있습니다.

도움이 되길 바랍니다.


0

이것은 당신이 가장 빠른 시간을 결정하는 것을 시도해야한다, 정말 최적의 방법은 아닙니다 이동을 따라 첫 번째 점은 경로 객체 또는 , 충돌이 발생 (계산 된 시간 또는 위치)이 위치로 개체를 이동을에 시도 이동 후 관통 위치를 기준으로 수정하는 것은 매우 문제가되지만 약간의 변화만으로 현재 프로세스를 사용할 수 있습니다. 충돌이 없을 때까지 계속 확인하십시오.

bool collided = true;
while(collided) {
   collided = false
   while(unsigned i = 0; i!= testRects.size(); i++){
      if(p.IsCollidingWith(testRects[i]){
         collided = true
         p.Collide(testRects[i]);
      }
   }
}

이로 인해 상황이 발생할 수 있습니다 무한 루프로 (충돌에서 상자를 옮기면 다른 컬렉션이 발생하고 충돌에서 상자를 옮기면 이전과 동일한 충돌 위치로 다시 이동합니다)

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