7

Я разрабатываю игру, допустим, игрок помещает бомбу в место x = 100, y = 100, а радиус взрыва - 100 единиц ... Мне очень легко найти все «предметы» в игра была поражена взрывом бомбы (просто нужно проверить, что их расстояние от бомбы ниже 100).Как рассчитать площадь взрыва бомбы?

Но теперь я хочу принять во внимание препятствия, которые у меня есть в игре, препятствия - квадраты, всегда 64 * 64 пикселя, всегда выровнены по оси (не вращаются). Я хочу знать, был ли элемент «скрытый» за препятствием, чтобы знать, что он не попал ...

что-то вроде этого:

enter image description here

чувак на правой не попал, но чувак на дне был ударил, я заполнил серый участок хита, а в зеленой области, которая скрыта ...

Моя мысль: 1. Найдите все предметы в сцене, чтобы их расстояние от бомбы было ниже 100. 2. Найдите все препятствия на сцене, чтобы их расстояние от бомбы было ниже 100. 3 рассчитать линии от предметов до центра бомбы .. затем проверить, пересекаются ли линии с любым препятствием, если нет .. вы попали.

Окончание, вопросы 1. Есть ли у кого-то лучшее представление? 2. Есть ли свободные механизмы с открытым кодом C#, которые могут мне помочь? Box2d может помочь мне здесь?

Благодаря

+0

Человеку-бомбардировщику не нужны сложные вычисления. – cgatian

+1

Ваш подход хорош. Это вопрос только о количестве предметов и препятствий, с которыми вы имеете дело. Если число велико (для одного или обоих), полезно использовать разметку пространства для поиска элементов и/или препятствий в диапазоне времени регистрации. – Ante

+0

Подумайте «коэффициент просмотра» - прочитайте любой текст о теплопередаче излучения. Я предполагаю, что вы не справитесь с этим, но так вы сделали бы это, если бы это была проблема радиационного переноса тепла. – duffymo

ответ

1

Это довольно просто, и, как Jongware упомянуть в комментариях, вы должны использовать две линии видимости.

Вы должны вычислять линии видимости с каждой «стороны» элементов на картинке. Происхождение каждой линии видимости можно аппроксимировать вычислением линии от центра бомбы и получить направление, нормальное к этому вектору. Затем ваши две точки видимости располагаются на одном радиусе от центра элемента в нормальном и отрицательном нормальном направлении. Это приближение круга может не очень хорошо представлять все возможные формы, но, как правило, достаточно хорошее приближение для простых игр (и ваши предметы выглядят круговыми на чертеже).

Java-Isch псевдокод с использованием 2D-векторов:

// bombCenter and itemCenter are 2D-vectors 
bombDirectionVector = bombCenter.minus(itemCenter); 
normal = bombDirectionVector.getNormal() // normal vector of length 1 
viewPoint1 = itemCenter.plus(normal.times(itemRadius)); 
viewPoint2 = itemCenter.minus(normal.times(itemRadius)); 
// Check obstacle intersection with the lines from viewPoint{1,2} to bombCenter 
// ... 

Линии видимости будет идти от точки на сторонах каждого элемента до центра взрыва. Таким образом, для каждого элемента вы проверяете, пересекаются ли две линии видимости либо с одним препятствием, либо с двумя связанными препятствиями.

Нет свободных открытых C# -совместимых двигателей с открытым исходным кодом. Я знаю, что это делает, но единственная часть, которая может быть немного сложной, - это проверка пересечения препятствий. Поэтому, если вы просто найдете что-то, что поможет вам с проверкой пересечения, то остальное должно быть очень простым в реализации.

Надеюсь, это поможет, и дайте мне знать, если что-то неясно, и я поясню ответ соответственно.

0

Вот хороший демо/записи на эту тему: http://www.redblobgames.com/articles/visibility/

Если это плитка основана игра, и вы знаете координаты плитки всех объектов, вы можете использовать Bresenham по линии Алгоритм: http://roguebasin.roguelikedevelopment.org/index.php?title=Bresenham%27s_Line_Algorithm.Вот выдержка:

// Author: Jason Morley (Source: http://www.morleydev.co.uk/blog/2010/11/18/generic-bresenhams-line-algorithm-in-visual-basic-net/) 
using System; 

namespace Bresenhams 
{ 
    /// <summary> 
    /// The Bresenham algorithm collection 
    /// </summary> 
    public static class Algorithms 
    { 
     private static void Swap<T>(ref T lhs, ref T rhs) { T temp; temp = lhs; lhs = rhs; rhs = temp; } 

     /// <summary> 
     /// The plot function delegate 
     /// </summary> 
     /// <param name="x">The x co-ord being plotted</param> 
     /// <param name="y">The y co-ord being plotted</param> 
     /// <returns>True to continue, false to stop the algorithm</returns> 
     public delegate bool PlotFunction(int x, int y); 

     /// <summary> 
     /// Plot the line from (x0, y0) to (x1, y10 
     /// </summary> 
     /// <param name="x0">The start x</param> 
     /// <param name="y0">The start y</param> 
     /// <param name="x1">The end x</param> 
     /// <param name="y1">The end y</param> 
     /// <param name="plot">The plotting function (if this returns false, the algorithm stops early)</param> 
     public static void Line(int x0, int y0, int x1, int y1, PlotFunction plot) 
     { 
      bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0); 
      if (steep) { Swap<int>(ref x0, ref y0); Swap<int>(ref x1, ref y1); } 
      if (x0 > x1) { Swap<int>(ref x0, ref x1); Swap<int>(ref y0, ref y1); } 
      int dX = (x1 - x0), dY = Math.Abs(y1 - y0), err = (dX/2), ystep = (y0 < y1 ? 1 : -1), y = y0; 

      for (int x = x0; x <= x1; ++x) 
      { 
       if (!(steep ? plot(y, x) : plot(x, y))) return; 
       err = err - dY; 
       if (err < 0) { y += ystep; err += dX; } 
      } 
     } 
    } 
} 
Смежные вопросы