Я написал систему обнаружения столкновений для игры, над которой я работаю, и я испытываю странный сбой, когда иногда снаряды будут проходить через игрока или стены, разбросанные по всему уровню. Поскольку снаряды можно стрелять под любым углом, я разложил ограничивающий прямоугольник каждого снаряда на несколько меньших ограничивающих прямоугольников, которые затем поворачиваю вокруг центра текстуры в соответствии с вращением снаряда в пространстве. По какой-то причине изредка снарядом Spear будет проходить через игрока или стену, даже через других нет.Снаряды, проходящие через другие объекты
Я использую следующие методы для определения вращения текстуры и перевести ограничивающие рамки:
public double RotateToFaceTarget()
{
double rotation = Math.Atan2((double)_direction.Y, (double)_direction.X);
return rotation;
}
public List<BoundingBox> TranslateBoundingBox(List<BoundingBox> box, double rotation)
{
List<BoundingBox> newBounds = new List<BoundingBox>();
foreach (BoundingBox b in box)
{
Vector2 boundsOrigin = new Vector2(b.Pos.X + b.Size.X/2, b.Pos.Y + b.Size.Y/2);
Vector2 texOrigin = new Vector2(_pos.X + _texture.Width/2, _pos.Y + _texture.Height/2);
Vector2 newPosBasedOnOrigin = Vector2.Transform(boundsOrigin - texOrigin, Matrix.CreateRotationZ((float)rotation)) + boundsOrigin;
newBounds.Add(new BoundingBox(newPosBasedOnOrigin, b.Size));
}
return newBounds;
}
_direction рассчитывается путем вычитания положения снаряда из целевого местоположения и нормализации. Я использую этот метод, чтобы определить, если снаряд сталкиваясь с другим объектом:
public bool ProjectileCollision(Entity e, Projectile entity2)
{
if (entity2.CanCollide)
{
foreach(GameObject.BoundingBox b in entity2.BoundingBox)
{
foreach(GameObject.BoundingBox b2 in e.BoundingBox)
{
if (b2.Intersect(b) && (entity2.IgnoredEntities.Contains(e.Type) == false))
{
entity2.IsActive = false;
e.Health -= entity2.Damage;
return true;
}
return false;
}
}
return false;
}
return false;
}
И это мой метод Ограничительной Box Пересечения:
public bool Intersect(BoundingBox intersected)
{
if ((_pos.Y < intersected.Pos.Y + intersected.Size.Y) && (_pos.Y + _size.Y > intersected.Pos.Y) && (_pos.X + _size.X > intersected.Pos.X) && (_pos.X < intersected.Pos.X + intersected.Size.X))
{ return true; }
return false;
}
EDIT: На дальнейших испытаниях, кажется, что снаряд будет всегда обнаруживайте попадание, если игрок попадает на верхний левый угол (что имеет смысл теперь, когда я смотрю на мой код пересечения). Есть ли другой способ переписать мой метод Intersect для использования чего-то более точного, чем левый верхний угол?
EDIT2: Я нарисовал хитбоксы для определенных объектов, и это один случай, когда я ловлю копье проходит через игрок:
игрок больший розовый квадрат. Хитбоксы не переводятся правильно, но это не должно просто перестать работать, для некоторых, а не для других, верно?
Это случалось со мной иногда. Является ли скорость снаряда большей, чем ширина цели? Если это так, он может «пропустить» во время цикла обновления. – Ares
Игрок hitbox равен 32x32, а скорость снаряда не более 15. – Charsmud
Я могу придумать несколько случаев, когда он прыгает на 15 пикселей, заставит его пропустить законный удар, просто не возглавьте, что объясняет, почему это поведение только происходит иногда. Моя непосредственная мысль состоит в том, чтобы разделить позицию, проверяемую на некоторое количество срезов (например, 10) старых и новых позиций, если две вещи сравниваются примерно друг с другом. Затем используйте _those-_, чтобы проверить, прошел ли снаряд через – Ares