Ponieważ jest to oparte na twoim drugim pytaniu, dam rozwiązanie, kiedy prostokąt jest wyrównany względem osi.
Najpierw budujesz prostokąt bieżącego obiektu za pomocą następujących wartości:
int boxLeft = box.X;
int boxRight = boxLeft + box.Width;
int boxTop = box.Y;
int boxBottom = boxTop + box.Height;
Następnie musisz mieć pozycję starego obiektu (którą możesz zapisać na każdym obiekcie lub po prostu przekazać do funkcji), aby utworzyć prostokąt starego obiektu (gdy nie kolidował):
int oldBoxLeft = box.OldX;
int oldBoxRight = oldBoxLeft + box.Width;
int oldBoxTop = box.OldY;
int oldBoxBottom = oldBoxTop + box.Height;
Teraz, aby wiedzieć, skąd pochodzi kolizja, musisz znaleźć stronę, w której poprzednia pozycja nie znajdowała się w obszarze kolizji i gdzie jest nowa pozycja. Ponieważ, gdy o tym pomyślisz, dzieje się tak, gdy się zderzasz: strona, która nie zderzyła się, wchodzi w inny prostokąt.
Oto, jak możesz to zrobić (te funkcje zakładają, że istnieje kolizja. Nie należy ich wywoływać, jeśli nie ma kolizji):
bool collidedFromLeft(Object otherObj)
{
return oldBoxRight < otherObj.Left && // was not colliding
boxRight >= otherObj.Left;
}
Rince i powtórz.
bool collidedFromRight(Object otherObj)
{
return oldBoxLeft >= otherObj.Right && // was not colliding
boxLeft < otherObj.Right;
}
bool collidedFromTop(Object otherObj)
{
return oldBoxBottom < otherObj.Top && // was not colliding
boxBottom >= otherObj.Top;
}
bool collidedFromBottom(Object otherObj)
{
return oldBoxTop >= otherObj.Bottom && // was not colliding
boxTop < otherObj.Bottom;
}
Teraz, do faktycznego wykorzystania z odpowiedzią na kolizję z drugiego pytania:
if (collidedFromTop(otherObj) || collidedFromBottom(otherObj))
obj.Velocity.Y = -obj.Velocity.Y;
if (collidedFromLeft(otherObj) || collidedFromRight(otherObj))
obj.Velocity.X = -obj.Velocity.X;
Ponownie, to może nie być najlepsze rozwiązanie, ale zwykle tak wybieram wykrywanie kolizji.