Problem trapi mnie od bardzo długiego czasu i nie jestem pewien czy jestem za młody żeby to zrozumieć, czy po prostu pomijam jakąś ważną część, ale za nic nie mogę zrozumieć jak napisać prostą, działającą kolizję używając Rectangle - jak w prostych platformówkach, pomijając fakt skoków itp. - po prostu, aby jeden Rectangle, używając WSAD mógł poruszać się po TiledMap'ie zbudowanej z Rectangle oznaczających ściany - i przez nie, normalnie w świecie - nie przenikał.
List<Rectangle> levelHitboxes = new List<Rectangle>();
Lista Rectangle oznaczających ściany. Każdy rectangle ma swoją pozycję w świecie i wymiary równe 32x32.
Vector2 position; // Pozycja gracza
Rectangle playerHitbox; // Hitbox gracza
Gracz również jest Rectangle'm o wymiarach 32x32, gdzie jego X i Y oznacza Vector2 position.
Próbowałem wiele razy umieścić kolizję, która wygląda mniej więcej tak:
// Dla skrótu - pozycje ściany
int RLEFT = rect.X;
int RRIGHT = rect.X + rect.Width;
int RUP = rect.Y;
int RDOWN = rect.Y + rect.Height;
// Dla skrótu - pozycje gracza
int PLEFT = playerHitbox.X;
int PRIGHT = playerHitbox.X + playerHitbox.Width;
int PUP = playerHitbox.Y;
int PDOWN = playerHitbox.Y + playerHitbox.Height;
foreach(Rectangle rect in levelHitboxes){
if(playerHitbox.Intersects(rect)){
if(PRIGHT > RLEFT && PLEFT < RLEFT){
// Collision RIGHT
collisionRight = true;
}
if(PLEFT < RRIGHT && PRIGHT > RRIGHT){
// Collision LEFT
collisionLeft = true;
}
if(PDOWN > RUP && PUP < RUP){
// Collision DOWN
collisionBot = true;
}
if(PUP < RDOWN && PDOWN > RDOWN){
// Collision TOP
collisionTop = true;
}
}
}
Kolizja świruje tylko w dwóch osiach (X i Y), gdy działa tylko jedna, wszystko jest jak należy. Przykładem jest dotknięcie góry ściany przez dół gracza i nagle odpala się kolizja Left Right i Top, gdzie gracz nie dotyka swoją prawą oraz lewą stroną niczego.
Czytałem sporo na temat kolizji w Internecie, może nie dokładnie, sam nie wiem, ale nigdy nie znalazłem sensownego rozwiązania. Nie chcę zbytnio korzystać z dodatkowych bibliotek czy silników, chciałbym poznać sam dogłębne rozwiązanie tego problemu, bo wydaje mi się, że nie jest aż takie trudne, ale brakuje mi tego "klucza".