Обнаружение столкновения в JS - PullRequest
4 голосов
/ 16 июля 2011

Я воссоздаю старую игру, похожую на Tron, в HTML5 canvas + JS. Основное различие заключается в том, что змеи не поворачиваются под прямым углом, они могут двигаться в кривых (имя Achtung Die Kurve).

Мне нужно обнаруживать столкновения, и я не знаю как. Правила действительно просты, и все, что я придумываю или читаю, выглядит излишне сложным. Столкновения происходят, когда:

  1. Змея врезается в тело другой змеи (или в свое собственное) голова-вперед (я подчеркиваю, потому что, в очень раннем эксперименте, головы моих змей раздавлены назад в их собственные "шеи" «как только они переехали: P).

  2. Змея врезается в стену (без внутренних стен).

Как мне поступить об этом? Я готов добавить любые данные, необходимые для моих объектов.

Ответы [ 5 ]

2 голосов
/ 16 июля 2011

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

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

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

1 голос
/ 16 июля 2011

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

Затем используйте snakeHead.style.display = 'none';

, чтобы временно скрыть голову змеи (Вы переделаете это снова перед рендерингом)

Затем document.elementFromPoint(x, y), чтобы проверить, какой элемент находится прямо под передней частью змеиной головы.Может быть, добавить класс с именем collidable или что-то еще для всех элементов, вызывающих столкновение, и протестировать

var class = ' '+document.elementFromPoint(x, y).className+' ';
if(class.indexOf(' collidable ') > -1){
    alert('Collision!');
}

Затем, конечно, заново показать голову змеи:

snakeHead.style.display = 'whatever is was before probably inline';

ПростоИдея.

elementFromPoint также имеет хорошую совместимость с браузерами: http://www.quirksmode.org/dom/w3c_cssom.html#documentview

Дайте мне знать, как это работает:)

0 голосов
/ 30 апреля 2014

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

0 голосов
/ 17 июля 2011

Прежде всего, спасибо всем за ваши ответы! Я прочитал то, что вы написали, прочитал немного больше, немного подумал и решил сделать следующее:

Я собираюсь сохранить байтовую карту, представляющую игровую область, и каждый раз, когда позиция занята, добавьте 1 к значению. Затем я собираюсь проверить 3 «внешних» угла 4 углов головы змеи («внутренний» угол сталкивается с остальной частью тела) для значений != 1.

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

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

0 голосов
/ 16 июля 2011

Хотите ли вы пиксельную проверку столкновения? Лучше всего обращаться с игровой областью как с сеткой (с любым разрешением, которое вам нужно, с точностью до пикселя или иным образом) и хранить список для каждой змеи, указывающий, какие позиции сетки занимает каждая змея. Затем сохраните местоположение головы змеи и вектор, представляющий ее направление, и проверьте местоположение + вектор со всеми местоположениями сетки, занятыми змеями. Вы можете сделать этот процесс эффективным, используя хэш-наборы, если вы хотите оптимизировать так много.

...