Обнаружение столкновений в Java-игре? - PullRequest
3 голосов
/ 15 марта 2010

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

Ответы [ 6 ]

14 голосов
/ 15 марта 2010

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

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

     X            00000100000
  XXXXXXX         00111111100
 X       X        01111111110
X         X       11111111111
 X       X        01111111110
  XXXXXXX         00111111100
    XXX           00001110000

Изображение - это то, что отображается на экране, а маска - это то, что используется для обнаружения столкновений. Вы заметите, что цифры в маске - это, в основном, контур и содержание изображения.

Способ обнаружения столкновения:

  • проверить, перекрываются ли прямоугольники. Если нет, то вероятность столкновения не будет.
  • В противном случае создайте прямоугольник объекта № 1, состоящий из его маски.
  • Создайте еще один прямоугольник объекта 2, состоящий из его маски.
  • Поразрядно-И перекрывающаяся часть прямоугольника 2 с прямоугольником 1.
  • Если в прямоугольнике 1 остались какие-либо 1-биты, то возникает коллизия.

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

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

....xx....
..xx..xx..
.x......x.
.x......x.
x........x
x........x
.x......x.
.x......x.
..xx..xx..
....xx.**y.....
       .y......
       yyyyyyyy
       .y......
       ..y.....

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


И @kyoryu поднимает интересный момент в своем комментарии. Некоторые игры хорошо адаптируются к объектам, составленным из меньших прямоугольников, и вы можете упростить обнаружение столкновений на основе прямоугольных компонентов (не беспокоясь о совершенстве пикселей). Например, наш старый друг космический захватчик (на самом деле защитник против космических захватчиков в этой игре) может состоять из двух прямоугольников, X и Y, а ракеты сделаны из Z:

    YYYY                .Z.
    YYYY                .Z.
XXXXXXXXXXXX            .Z.
XXXXXXXXXXXX            ZZZ
XXXXXXXXXXXX            .Z.
XXXXXXXXXXXX

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

1 голос
/ 15 марта 2010

Довольно легко столкнуться с ящиками.Если вы посмотрите только на ось x, есть три возможных варианта размещения двух блоков:

  1. Перекрытие
  2. Первый блок находится слева от второго
  3. Первое поле находится справа от второго.

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

first.right < second.left

Если первый блок находится справа от второго, его крайняя левая точка должна находиться справа от крайней правой точки второго блока.

first.left > second.right

Если ни одно из этих утверждений не соответствует действительности, то блоки перекрываются по оси X.

Затем можно повторить это для плоскости y (заменяя верхнюю и нижнюю части на левую и правую), чтобы выяснить, перекрываются ли эти поляна оси у - если они делают, они сталкиваются!И это действительно все, что вам нужно сделать для простых столкновений в двумерной игре.

Может возникнуть более серьезная проблема в зависимости от того, сколько у вас различных объектов, поскольку наивной реализацией обнаружения столкновений является O (N ^2) алгоритм.

1 голос
/ 15 марта 2010

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

c^2 = a^2 + b^2

Мы можем обнаружить столкновение между двумя кругами, зная, что если расстояние между центрами меньше, чем объединенный радиус, они должны сталкиваться, верно? Затем вы можете выполнить проверку столкновения следующим образом:

distX ^ 2 + distY ^ 2 <= (radius1 + radious2) ^ 2 == COLLISION!

distX и distY - это расстояние между центрами двух окружностей, и радиус радиус1 + радиус2 может быть рассчитан заранее, если размеры окружностей не меняются.

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

0 голосов
/ 19 мая 2018

Вы можете использовать встроенные в Java пересечения прямоугольников. Это работает даже для повернутых прямоугольников.

  1. Создайте прямоугольник и убедитесь, что он следует за вращением и положением объекта.

  2. Вызовите метод rectangle.intersects(Rectangle) для каждого кадра, чтобы выяснить, пересекается ли он.

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

0 голосов
/ 19 мая 2018

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

Лично я им пользуюсь все время. Мне было немного трудно начать использовать, но как только вы начинаете запоминать, как сделать объект, это становится очень легко.

Вы можете скачать его здесь .

Здесь также есть несколько видео по основам здесь . Библиотека, которую он использует, немного «простовата», но вы легко можете понять основы.

0 голосов
/ 15 марта 2010

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

|-------
|   |
|   |
|   |
|_______|

`    |
    |
    |
    |
comming down



      |---------|
      |     |
      |     |
      |     |
      |---------|
Minus width and height to find out correct x and y


...