методология обнаружения столкновений

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

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

#include <iostream>
#include <vector>class point
{
public:
point (int a, int b): x(a), y(b) {};
~point () {};

int getX() {return x;}
int getY() {return y;}

private:
int x;
int y;
};class side
{
public:
side(point f, point s): first(f), second(s) {};
~side() {};
point getFirst() {return first;}
point getSecond() {return second;}

private:
point first;
point second;
};class boundingBox
{
public:
boundingBox(std::vector <point> p);
~boundingBox() {};

std::vector <side> getSides() {return boundingSides;}

private:
std::vector <point> boundingPoints;
std::vector <side> boundingSides;
};boundingBox::boundingBox(std::vector <point> p)
{
boundingPoints = p;

// in the constructor, create a vector of sides from the points
for (std::vector <point>::iterator i = boundingPoints.begin(); i != boundingPoints.end()-1; i++)
{
boundingSides.push_back( side(*i, *(i+1)) );
}

boundingSides.push_back( side (*(boundingPoints.end()-1), *(boundingPoints.begin()) ) );
}

bool collisionCheck(std::vector <side> s, point p)
{
std::vector <side> nodeSides;

int toleft = 0;
int toright = 0;

for (std::vector <side>::iterator i = s.begin(); i != s.end(); i++)
{
//if the Y value of the point being tested is between the Y values of a side, add a node
if (p.getY() > (*i).getFirst().getY() && p.getY() < (*i).getSecond().getY() ||
p.getY() < (*i).getFirst().getY() && p.getY() > (*i).getSecond().getY() )
{
nodeSides.push_back( side ( (*i).getFirst(), (*i).getSecond() ) );
}// if the Y value of the point being tested is also the Y of the second point of the side...
if (p.getY() == (*i).getSecond().getY())
{
//if it isn't the last side, and this side and the next strattle that y value, add a node
if (i != s.end()-1)
{
if ((*i).getFirst().getY() < p.getY() && (*(i+1)).getSecond().getY() > p.getY() ||
(*i).getFirst().getY() > p.getY() && (*(i+1)).getSecond().getY() < p.getY() )
{
nodeSides.push_back( side ( (*i).getFirst(), (*i).getSecond() ) );
}
}

//if it is the last side, and this side and the first side strattle that y value, add a node
else if ((*i).getFirst().getY() < p.getY() && s.front().getSecond().getY() > p.getY() ||
(*i).getFirst().getY() > p.getY() && s.front().getSecond().getY() < p.getY() )
{
nodeSides.push_back( side ( (*i).getFirst(), (*i).getSecond() ) );
}
}
}

for (std::vector <side>::iterator i = nodeSides.begin(); i != nodeSides.end(); i++)
{
double deltaY = (*i).getSecond().getY() - (*i).getFirst().getY();
double deltaX = (*i).getSecond().getX() - (*i).getFirst().getX();

double slope = deltaX - deltaY;

double x = ( p.getY() - (*i).getSecond().getY() + (slope * (*i).getSecond().getX()) ) / slope;

if (x < p.getX())
{
toleft++;
}

else
{
toright++;
}
}std::cout << "Analysis: " << toleft << " nodes to the left, " << toright << " nodes to the right." << std::endl;

if (toleft % 2 == 0)
{
std::cout << "return false, does not hit" << std::endl;
return false;
}

else
{
std::cout << "return true, hits" << std::endl;
return true;
}
}

int main ()
{
std::vector <point> points;

points.push_back(point(3, 5));
points.push_back(point(1, 13));
points.push_back(point(7, 16));
points.push_back(point(14, 14));
points.push_back(point(8, 13));
points.push_back(point(9, 11));
points.push_back(point(17, 13));
points.push_back(point(16, 18));
points.push_back(point(21, 15));
points.push_back(point(17, 9));
points.push_back(point(9, 7));
points.push_back(point(12, 5));
points.push_back(point(14, 7));
points.push_back(point(15, 2));
points.push_back(point(6, 3));

boundingBox enemy(points);

point hitSimp(13, 4);
point hitComp(19, 15);
point missNear(10, 12);
point missFar(100,100);

collisionCheck(enemy.getSides(), hitSimp);

collisionCheck(enemy.getSides(), hitComp);

collisionCheck(enemy.getSides(), missNear);

collisionCheck(enemy.getSides(), missFar);

return 0;
}

1

Решение

Если ваша программа будет связана проверкой слишком большого количества коллизий, изучите Quad Trees

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

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]