В этой статье я рассмотрю такие приемы как:
И рассмотрим пример реализации механики игры «Астероиды».
Практически любой объект/спрайт можно вписать в прямоугольник, длина и ширина которого являются габаритами исходного объекта. Нахождение пересечения габаритов — первый этап к определению столкновения. Данная операция не требует много ресурсов, поэтому чаще всего данную функция используют для нахождения пары объектов у которых нужно определить столкновение.
Как видно из исходного кода в основе определения столкновение идет определение пересечения проекций прямоугольников на осях X и Y. При пересечении функция возвращает true, иначе false.
Давайте представим, что мы делаем такую игру как «Астероиды». Каждый астероид представляет собой неправильный многоугольник (полигон). Пуля игрока — круг. Учитывая соотношения масштабов астероида и пули, можно пренебречь размером пули, сократив до центральной точки круга. Таким образом нахождение столкновения сводится к определению принадлежности точки полигону.
В качестве входных параметров функции — массив из вершин полигона и координаты точки. Описание работы данной функции описано на английском языке тут.
Таким образом мы с легкостью можем определить столкновение пули с астероидом. Чтобы сократить кол-во вычислений изначально будем использовать нахождение пересечение габаритов, затем вхождение точки в полигон.
Пример:
То что получилось, можно скачать тут, а рабочий пример тут. Управление WSAD+пробел, клик по карте — добавление астеройда.
UPDATE: Скриншот того, что в итоге получилось в качестве примера.
- Пересечение габаритов объектов
- Принадлежность точки полигону
И рассмотрим пример реализации механики игры «Астероиды».
Пересечение габаритов объектов
Практически любой объект/спрайт можно вписать в прямоугольник, длина и ширина которого являются габаритами исходного объекта. Нахождение пересечения габаритов — первый этап к определению столкновения. Данная операция не требует много ресурсов, поэтому чаще всего данную функция используют для нахождения пары объектов у которых нужно определить столкновение.
function MacroCollision(obj1,obj2){
var XColl=false;
var YColl=false;
if ((obj1.x + obj1.width >= obj2.x) && (obj1.x <= obj2.x + obj2.width)) XColl = true;
if ((obj1.y + obj1.height >= obj2.y) && (obj1.y <= obj2.y + obj2.height)) YColl = true;
if (XColl&YColl){return true;}
return false;
}
Как видно из исходного кода в основе определения столкновение идет определение пересечения проекций прямоугольников на осях X и Y. При пересечении функция возвращает true, иначе false.
Принадлежность точки полигону
Давайте представим, что мы делаем такую игру как «Астероиды». Каждый астероид представляет собой неправильный многоугольник (полигон). Пуля игрока — круг. Учитывая соотношения масштабов астероида и пули, можно пренебречь размером пули, сократив до центральной точки круга. Таким образом нахождение столкновения сводится к определению принадлежности точки полигону.
function pointInPoly(polyCords, pointX, pointY)
{
var i, j, c = 0;
for (i = 0, j = polyCords.length - 1; i < polyCords.length; j = i++)
{
if (((polyCords[i][1] > pointY) != (polyCords[j][1] > pointY)) && (pointX < (polyCords[j][0] - polyCords[i][0]) * (pointY - polyCords[i][1]) / (polyCords[j][1] - polyCords[i][1]) + polyCords[i][0]))
{
c = !c;
}
}
return c;
}
В качестве входных параметров функции — массив из вершин полигона и координаты точки. Описание работы данной функции описано на английском языке тут.
Таким образом мы с легкостью можем определить столкновение пули с астероидом. Чтобы сократить кол-во вычислений изначально будем использовать нахождение пересечение габаритов, затем вхождение точки в полигон.
Пример:
Bullet = function(x,y)
{
//Координаты
this.x=x;
this.y=y;
//Габариты
this.width=10;
this.height=10;
this.tick = function (){
//Перебираем астеройды
for (var i=0; i<Asteroids.length; i++){
if (MacroCollision(this,Asteroids[i])){
if (pointInPoly(Asteroids[i].shapeXY, this.x+5, this.y+5))
{
…
//Столкновение
…
}
}
}
}
…
}
То что получилось, можно скачать тут, а рабочий пример тут. Управление WSAD+пробел, клик по карте — добавление астеройда.
UPDATE: Скриншот того, что в итоге получилось в качестве примера.