Wykrywanie kolizji

0

Mam dość ogólne pytanie dotyczące wykrywania kolizji w grach 2-D. Chciałbym wykrywać kolizję między różnymi obiektami, takimi jak auta, kule, czy trójkąty. Używam XNA. To mój pierwszy taki problem.

0

Wszystko zalezy od tego, czy ksztalt moze byc dowolny, czy tez jest okreslona figura geometryczna. Kolejna sprawa jest fakt, czy mozesz go okreslic wektorowo, czy tylko rastrowo (np.: brzegi samochodu, narysowane nieprzezroczyscie na bitmapie sprite'a).

0

Na początek może kolizję dwóch prostokątnych samochodów. Pozycje mogę określić wektorowo. Tzn. mam współrzędne X i Y, a także wielkość bitmapy. Jednak obracam ją co też trzeba będzie uwzględnić.

0

Ogolnie, jak chodzi o kolizje wielokatow, zajrzyj tutaj:

http://www.codeproject.com/KB/GDI-plus/PolygonCollision.aspx

0

Szczerze mówiąc to trochę skomplikowanie to wygląda.

0

No bo takie jest. W większości aplikacji zamiast używać złożonych kształtów wykorzystuje się ich przybliżenia w formie kół lub prostokątów. Pamiętaj, jeśli coś jest dla ciebie skomplikowane, to na pewno będzie dla komputera mało wydajne, gdy coś jest proste, to będzie szybko działać. Dla prostokąta, wystarczy porównać kilka wartości, by wiedzieć czy obiekty się pokrywają, dla koła jest ich trochę więcej, ale też mało, a dla samochodu, to może się okazać, że twoja gra po uruchomieniu będzie miała 2FPS zamiast np. 60FPS.

0

Ale samochód ma kształt prawie prostokąta.

A poza tym w tutorialu z którego się uczę, jest taki sposób:
http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series2D/Coll_Detection_Overview.php

Tylko go nie do końca rozumiem.

0

Ale załóżmy, że chciałbym wykryć kolizję między dwoma prostokątami. Czy wystarczy takie coś:

public bool Kolizja (Vector2 poz1, Vector2 roz1, Vector2 poz2, Vector2 roz2)
{
         if(poz1.X < poz2.X && poz1.X < poz2.X + roz2.X)
                return true;
         if(poz2.X < poz1.X && poz2.X < poz1.X + roz1.X)
                return true;
         if(poz1.Y < poz2.Y && poz1.Y < roz2.Y + poz2.Y)
                return true;
         if(poz2.Y < poz1.Y && poz2.Y < roz1.Y + poz1.Y)
                return true;

         else
                return false;
}
0

Sknociłeś to, zauważ, że jeśli współrzędne X się pokrywają, a Y nie, to obiekty się nie pokrywają a w twoim algorytmie już

if(poz1.X < poz2.X && poz1.X < poz2.X + roz2.X)
                return true;
         if(poz2.X < poz1.X && poz2.X < poz1.X + roz1.X)
                return true;

Zwróci true i pojawi się błąd

0

O ile nie poknociłeś nic z warunkami, co ma być mniejsze od czego, to ten algorytm powinien działać, ale najlepiej niech go ktoś jeszcze sprawdzi, bo ja nie mam teraz czasu. Musze poprawić oceny w budzie.

public bool Kolizja (Vector2 poz1, Vector2 roz1, Vector2 poz2, Vector2 roz2)
{
         if(
                ((poz1.X < poz2.X && poz1.X < poz2.X + roz2.X)||(poz2.X < poz1.X && poz2.X < poz1.X + roz1.X))
                &&
                ((poz1.Y < poz2.Y && poz1.Y < roz2.Y + poz2.Y)||(poz2.Y < poz1.Y && poz2.Y < roz1.Y + poz1.Y))
         ) return true;
                
         return false;
}
0

Napisałem takie coś, ale nie działa do końca dobrze:

        public bool Kolizja(Vector2 poz1, Vector2 roz1, Vector2 poz2, Vector2 roz2)
        {
            if (poz1.X >= poz2.X && poz1.X < poz2.X + roz2.X && poz1.Y >= poz2.Y && poz1.Y < poz2.Y + roz2.Y)
                return true;
            if (poz1.X < poz2.X && poz1.X + roz1.X >= poz2.X && poz1.Y >= poz2.Y && poz1.Y < poz2.Y + roz2.Y)
                return true;
            if (poz1.X <= poz2.X && poz1.X > poz2.X + roz2.X && poz1.Y <= poz2.Y && poz1.Y > poz2.Y + roz2.Y)
                return true;
            if (poz1.X + roz1.X >= poz2.X && poz1.X < poz2.X && poz1.Y + roz1.Y > poz2.Y && poz1.Y < poz2.Y)
                return true;

            return false;
        }
0
//zakładam, że roz.X >= 0, roz.Y >= 0
public bool Kolizja(Vector2 poz1, Vector2 roz1, Vector2 poz2, Vector2 roz2)
{
   return poz1.X <= (poz2.X + roz2.X) && poz2.X <= (poz1.X + roz1.X)
       && poz1.Y <= (poz2.Y + roz2.Y) && poz2.Y <= (poz1.Y + roz1.Y);
}
0

Nie to też nie działa, tak jak należy. Jest identycznie jak przy mojej metodzie.

0

A podaj sytuację w której kod się psuje, oraz co się dzieje, może wtedy będziemy wiedzieli w czym problem. Spisz wszystkie 4 wektory.

0

Zrobiłem log, z pozycjami obu aut kiedy występuje kolizja. Oto jego wycinek:
auto1: X = 337,3 Y = 173,1
auto2: X = 326,7 Y = 204,4
auto1: X = 337,9 Y = 173,2
auto2: X = 327,8 Y = 204,4
auto1: X = 338,4 Y = 173,2
auto2: X = 328,8 Y = 204,4
auto1: X = 338,9 Y = 173,2
auto2: X = 329,8 Y = 204,4
auto1: X = 339,4 Y = 173,3
auto2: X = 330,8 Y = 204,4
auto1: X = 339,9 Y = 173,3
auto2: X = 331,8 Y = 204,4
auto1: X = 340,4 Y = 173,4
auto2: X = 332,8 Y = 204,4
auto1: X = 340,9 Y = 173,4
auto2: X = 333,9 Y = 204,4
auto1: X = 341,3 Y = 173,5
auto2: X = 334,9 Y = 204,5
auto1: X = 341,7 Y = 173,6
auto2: X = 335,9 Y = 204,5
auto1: X = 342,1 Y = 173,7
auto2: X = 336,9 Y = 204,5
auto1: X = 342,5 Y = 173,7
auto2: X = 338,0 Y = 204,5
auto1: X = 342,8 Y = 173,8
auto2: X = 339,0 Y = 204,5
auto1: X = 343,1 Y = 173,9
auto2: X = 340,0 Y = 204,5
auto1: X = 343,4 Y = 174,1
auto2: X = 341,0 Y = 204,5
auto1: X = 343,7 Y = 174,2
auto2: X = 342,0 Y = 204,5
auto1: X = 344,0 Y = 174,3
auto2: X = 343,0 Y = 204,5
auto1: X = 344,2 Y = 174,4
auto2: X = 344,1 Y = 204,5
auto1: X = 344,5 Y = 174,5
auto2: X = 345,1 Y = 204,5
auto1: X = 344,7 Y = 174,6
auto2: X = 346,1 Y = 204,5

Ciężko określić kiedy kolizja nie występuje. Jak coś to mogę podesłać plik .exe i cały kod źródłowy.

Tylko podejrzewam, że ten kod może nie uwzględniać obróceń pojazdów.

0

Na mój gust dwa obiekty się zderzają, jeśli zachodzi koniunkcja:

  • O1.L <= O2.P
  • O1.P >= O2.L
  • O1.G <= O2.D
  • O1.D >= O2.G

gdzie:

  • O1, O2 - obiekty
  • L, P, G, D - lewo, prawo, góra, dół
  • a punkt 0,0 jest w lewym, górnym rogu planszy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1