HTML5 Canvas Collision Detection "globalCompositeOperation" производительность - PullRequest
2 голосов
/ 13 января 2012

Утро

За последние несколько месяцев я работал с HTML5 Canvas API и получал от этого массу удовольствия.

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

Но у меня только что была мозговая волна (вполне вероятно, что кто-то еще подумал об этом, и я далеко внизу поля, но я гуглил это и ничего не нашел) .... так что идем ....

Можно ли использовать / использовать функцию globalCompositeOperation холста. Сначала я хотел установить для его метода значение «xor», а затем проверить все пиксели на холсте на прозрачность, если пиксель найден, должно быть столкновение. Правильно? Очевидно, что в этот момент вам нужно выяснить, какими объектами занят рассматриваемый пиксель и как реагировать, но вам придется сделать это для других других методов.

Сказать, что холст уже делает это обнаружение столкновения за кулисами, чтобы определить, когда фигуры перекрываются? Можно ли продолжить на этом?

Есть идеи?

Gary

Ответы [ 3 ]

2 голосов
/ 13 января 2012

холст не делает этого автоматически (вероятно, он все еще находится в зачаточном состоянии). easeljs использует этот подход для событий входа / выхода мыши, и он крайне неэффективен.Я использую алгоритмический подход к определению границ.Затем я использую это, чтобы увидеть, находится ли мышь внутри или снаружи фигуры.Теоретически, чтобы реализовать обнаружение попадания таким образом, все, что вам нужно сделать, это взять все точки обеих фигур и посмотреть, находятся ли они когда-либо в другой форме.Если вы хотите увидеть мой код, просто дайте мне знать

Однако я скажу, что, хотя ваш путь очень неэффективен, он применим ко всем формам.

1 голос
/ 02 мая 2014

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

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

enter image description here

Так что используйте эту смешанную стратегию:
-выполните проверку ограничивающих рамок ваших объектов.
- если между 2 BBoxами возникло столкновение, выполните проверку внутренней ограничивающей рамки: мы уверены, что произойдет столкновение, если внутренние блоки b спрайта перекрываются.
- тогда высохраняйте пиксель-идеальный тест только для действительно проблемных случаев, и вам нужно только нарисовать оба спрайта на временном холсте, размер которого больше, чем у спрайта.Вы сможете выполнять намного быстрее getImageData.На этом шаге вы знаете, какие объекты участвуют в столкновении.

enter image description here

Обратите внимание, что вы можете рисовать спрайты со шкалой на меньшем холсте, чтобы быстрее получить getImageData настоимость более низкого разрешения.
Обязательно отключите сглаживание, и я думаю, что уже достаточно холста 8X8 (на самом деле это зависит от средней скорости спрайтов. Если ваши спрайты медленные, увеличьте разрешение).
Таким образом, данные имеют размер 8 X 8 X 4 = 256 байт, и вы можете поддерживать хорошую частоту кадров.

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

1 голос
/ 02 мая 2014

Я сделал демонстрацию на codepen, которая выполняет обнаружение столкновений, используя неэкранный холст с globalCompositeOperation, установленным на xor, как вы упомянули.Код является коротким и простым, и должен иметь нормальную производительность с небольшими «полотнами столкновений».

http://codepen.io/sakri/pen/nIiBq

...