JavaScript обнаружение столкновения для прямоугольника и набора граничных координат? - PullRequest
1 голос
/ 18 октября 2011

Я смотрел на похожие вопросы, размещенные в SO (и в других местах), но они, кажется, либо имеют дело только с прямоугольниками, с которыми я хорошо справляюсь в данный момент, либо являются более сложными, чем я могу в настоящее время обернуть голову.

Я перемещаю спрайт по экрану с помощью событий mousedown и хочу, чтобы он не двигался «за пределы». Границы могут быть такими простыми, как эта комната:

Где зеленый цвет - это подвижное пространство, а красный ограничен. Мне лучше разбить это на что-то вроде 1 длинного прямоугольника и 2 треугольников (или групп квадратов, чтобы представить треугольник с неровными краями), или есть базовая концепция, к которой я должен стремиться, чтобы определить координаты «зоны прохождения» и убедитесь, что пользователь всегда "в пределах границ"?

Я кодирую это в JavaScript и сильно полагаюсь на jQuery.

Редактировать: Учитывая, что мне потенциально нужно иметь неограниченные точки (если в комнате было больше 4 точек), было бы лучше использовать что-то вроде A * для генерации путей?

Ответы [ 4 ]

4 голосов
/ 18 октября 2011

Попробуйте немного разобрать вашу проблему.С этой простой формой у вас есть прямоугольник, который должен иметь x-координаты между двумя уклонами и y-координаты между двумя плоскими линиями.

Примерно так должно работать:

function outOfBounds(point, boundary) {
    return point.y > boundary.top
        || point.y < boundary.bottom
        || point.x < boundary.getLeftBoundAt(point.y)
        || point.x > boundary.getRightBoundAt(point.y);
}

Напомним, что наклонные линии могут быть определены как mx + b, но в этом случае x-координата вашего наклона изменяется по отношению к координате y.В любом случае, getLeftBoundAt () будет выглядеть примерно так:

function getLeftBoundAt(y) {
    return this.slope * y + this.base;
}

РЕДАКТИРОВАТЬ:

В связи с тем, что высота меняется также по левому и правому краям, вам потребуется немного большекомплексное решение, где border.top заменяется вызовом такой функции:

function getTopBoundAt(x) {
    var segment = this.topSegmentAt(x);
    return segment.origin.y + segment.slope * (x - segment.origin.x);
}
1 голос
/ 03 января 2013

Наиболее распространенными решениями этого являются либо деконструкция деталей на треугольники с последующим тестированием с перекрытием, либо визуализация его в виде точечного растрового изображения и сравнение по пикселям за раз.

Первыйназывается тесселяцией или триангуляцией многоугольника:

http://en.wikipedia.org/wiki/Polygon_triangulation

И имеет преимущество в том, что лучше, чем O (n ^ 2).Для этого существует ряд алгоритмов, в основном потому, что движкам 3-D необходимо сформировать списки треугольников для передачи аппаратному обеспечению графического ускорителя, которое часто принимает информацию в виде тройки координат [x, y].

последнее, к сожалению, O (n ^ 2), но позволяет вам делать такие вещи, как проверка альфа-изображения растрового изображения, чтобы "четкие" на изображении (альфа-ноль или некоторые обрезки) не учитывались.Таким образом, вы делаете интересные вещи, например, определяете, сочетаются ли два перекрывающихся пикселя достаточно «сплошными» для столкновения, и, таким образом, имеют «нечеткие» частичные альфа-битовые карты, летающие вокруг.Этот пример не распространяется на альфа-версию и предназначен для Android, но пример в целом справедлив:

https://gamedev.stackexchange.com/questions/23603/how-to-handle-pixel-perfect-collision-detection-with-rotation

Некоторую дополнительную информацию можно найти здесь:

Простой алгоритм пересечения многоугольников

https://gamedev.stackexchange.com/questions/33553/what-algorithms-exist-for-generating-collision-geometry-from-an-image

Примечание. Если вы хотите использовать прямоугольники, включая пучки прямоугольников, сложенных в приблизительные формы, в качестве границы для столкновения,затем (полное раскрытие) я сделал для этого плагин jQuery.Так как вы сказали, что сильно полагаетесь на jQuery:

https://sourceforge.net/projects/jquerycollision/

1 голос
/ 18 октября 2011

Еще одна возможность для простых смежных допустимых областей состоит в том, что вы можете просто включить карту с низким разрешением, аналогичную той, которая указана в вашем вопросе, и конвертировать координаты x / y в координаты изображения.Если пиксель в соответствующей точке местоположения имеет зеленый цвет, все в порядке.Это потенциально может быть очень быстрым, а также простым в реализации.

Это что-то вроде хака?Может быть, да ... но я думаю, что это тоже довольно забавное решение.

0 голосов
/ 08 января 2012

Я пометил ответ YourPalAl как правильный выше, но я хотел оставить свое окончательное решение как ответ, если кто-то еще наткнется на это.

Я сейчас использую jQuery SVG (http://keith -wood.name/svg.html) для вставки координат многоугольника SVG по мере необходимости, которые определяют границы, и проверки объектов «следующий пункт назначения» в пределах диапазона допуска 5 пикселей.Если следующий пункт назначения попадет на многоугольник, я не позволю объекту двигаться дальше.

...