2016-07-21 3 views
1

Я написал систему обнаружения столкновений для игры, над которой я работаю, и я испытываю странный сбой, когда иногда снаряды будут проходить через игрока или стены, разбросанные по всему уровню. Поскольку снаряды можно стрелять под любым углом, я разложил ограничивающий прямоугольник каждого снаряда на несколько меньших ограничивающих прямоугольников, которые затем поворачиваю вокруг центра текстуры в соответствии с вращением снаряда в пространстве. По какой-то причине изредка снарядом 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: Я нарисовал хитбоксы для определенных объектов, и это один случай, когда я ловлю копье проходит через игрок:

http://imgur.com/a/fAxZw

игрок больший розовый квадрат. Хитбоксы не переводятся правильно, но это не должно просто перестать работать, для некоторых, а не для других, верно?

+0

Это случалось со мной иногда. Является ли скорость снаряда большей, чем ширина цели? Если это так, он может «пропустить» во время цикла обновления. – Ares

+0

Игрок hitbox равен 32x32, а скорость снаряда не более 15. – Charsmud

+0

Я могу придумать несколько случаев, когда он прыгает на 15 пикселей, заставит его пропустить законный удар, просто не возглавьте, что объясняет, почему это поведение только происходит иногда. Моя непосредственная мысль состоит в том, чтобы разделить позицию, проверяемую на некоторое количество срезов (например, 10) старых и новых позиций, если две вещи сравниваются примерно друг с другом. Затем используйте _those-_, чтобы проверить, прошел ли снаряд через – Ares

ответ

0

Это может произойти из-за высокой скорости и небольшого объекта, снаряд может пролететь через объект. Помимо проверки пересечения объектов, вы должны проверить, будет ли объект пересекаться, чтобы проверить, находится ли объект в линии огня. Вы могли бы достичь этого путем raycasting.

В таких случаях, как у меня была функция, проверяющая, находится ли объект рядом с другим. Простая проверка, если объект находится внутри некоторого радиуса другого объекта. Если да, то я проверял, идет ли объект к другому объекту и проверяет расстояние между ними. Когда расстояние действительно близко, произошло столкновение.

Смежные вопросы