Для правильной обработки нескольких столкновений потребуется подшаговый шаг, повторение проверок столкновений до тех пор, пока не прекратятся столкновения или не истечет счетчик. Вот как работают физические движки.
Я собираюсь показать другой метод. Это требует, чтобы не делать движение, которое вызвало столкновение и регулировать скорость наполовину каждого шага. Замедляйте до тех пор, пока не получите максимум log2(Velocity)
шагов (для скоростей <32, 5 шагов): </p>
foreach (var sprite in sprites)
{
if (sprite == this)
{
continue;
}
// it is good practice to use () for mixed && and ||
if ((Velocity.X > 0 && IsTouchingLeft(sprite)) || (Velocity.X < 0 && IsTouchingRight(sprite)))
{
Velocity.X *= 0.5f;
// by halving, the velocity will exponentially decay to 0
}
if ((Velocity.Y > 0 && IsTouchingTop(sprite)) || (Velocity.Y < 0 && IsTouchingBottom(sprite)))
{
Velocity.Y *= 0.5f;
}
if (sprite.rectangle.Intersects(rectangle))
{
hasDied = true;
}
// use new velocity to update the position.
}
Возможно, вам придется исправить условие смерти, пока неясно, когда оно должно быть запущено. Код, как написано, переместится вверх к другому объекту, но никогда не пересекается сам по себе.
Следующий код, как я полагаю, предназначен для вас (двигаться со скоростью 1 до наложения)
foreach (var sprite in sprites)
{
if (sprite == this)
{
continue;
}
// it is good practice to use () for mixed && and ||
if ((Velocity.X > 0 && IsTouchingLeft(sprite)) || (Velocity.X < 0 && IsTouchingRight(sprite)))
{
if (Velocity.X >= 2) // cap it at a minimum above 1
{
Velocity.X *= 0.5f;
// by halving, the velocity will exponentially decay to 0
}
if (sprite.rectangle.Intersects(rectangle))
{
Velocity.X = 0; // probably need to do this for Y here as well.
hasDied = true;
}
}
if ((Velocity.Y > 0 && IsTouchingTop(sprite)) || (Velocity.Y < 0 && IsTouchingBottom(sprite)))
{
if (Velocity.Y >= 2) // cap it at a minimum above 1
{
Velocity.Y *= 0.5f;
// by halving, the velocity will exponentially decay to 0
}
if (sprite.rectangle.Intersects(rectangle))
{
Velocity.Y = 0; // probably need to do this for X here as well.
hasDied = true;
}
}
}