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.
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).
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ć.
Ogolnie, jak chodzi o kolizje wielokatow, zajrzyj tutaj:
http://www.codeproject.com/KB/GDI-plus/PolygonCollision.aspx
Szczerze mówiąc to trochę skomplikowanie to wygląda.
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.
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.
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;
}
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
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;
}