Поскольку это основано на вашем другом вопросе, я дам решение, когда прямоугольник будет выровнен по оси.
Сначала вы строите прямоугольник текущего объекта со следующими значениями:
int boxLeft = box.X;
int boxRight = boxLeft + box.Width;
int boxTop = box.Y;
int boxBottom = boxTop + box.Height;
Далее у вас должна быть позиция старого объекта (которую вы можете сохранить на каждом объекте или просто передать функции), чтобы создать прямоугольник старого объекта (когда он не сталкивался):
int oldBoxLeft = box.OldX;
int oldBoxRight = oldBoxLeft + box.Width;
int oldBoxTop = box.OldY;
int oldBoxBottom = oldBoxTop + box.Height;
Теперь, чтобы узнать, откуда произошло столкновение, вы должны найти сторону, где старая позиция не находилась в зоне столкновения и где находится ее новая позиция. Потому что, когда вы думаете об этом, это то, что происходит, когда вы сталкиваетесь: сторона, которая не сталкивалась, входит в другой прямоугольник.
Вот как вы могли бы это сделать (эти функции предполагают наличие коллизии. Их не следует вызывать, если коллизии нет):
bool collidedFromLeft(Object otherObj)
{
return oldBoxRight < otherObj.Left && // was not colliding
boxRight >= otherObj.Left;
}
Ринс и повторить.
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;
}
Теперь для фактического использования с ответом на столкновение из другого вопроса:
if (collidedFromTop(otherObj) || collidedFromBottom(otherObj))
obj.Velocity.Y = -obj.Velocity.Y;
if (collidedFromLeft(otherObj) || collidedFromRight(otherObj))
obj.Velocity.X = -obj.Velocity.X;
Опять же, это не может быть лучшим решением, но это так, как я обычно иду для обнаружения столкновений.