Я пытаюсь реализовать обнаружение коллизий SAT в моем клоне flappybird, используя DirectX Tk. Все компилируется и работает без ошибок, но просто не работает должным образом. Я пытаюсь настроить его так, чтобы каждая труба в паре проверялась отдельно, а каждая пара проверялась одинаково (с большим количеством циклов for
). Трубы работают в массиве из 6 труб. (Когда вы покидаете экран слева, он сбрасывается вправо). Трубы - это каждый прямоугольник, а птица - пятиугольник. Вот код:
Vector2* Bird::getPipePoints(Vector2* points, int index, int top)
{
Pipe* pipe = pipes[index];
//upper pipe
if (top == 0)
{
points[0] = Vector2(pipe->getX(), 0);
points[1] = Vector2(pipe->getX() + pipe->getW(), 0);
points[2] = Vector2(pipe->getX() + pipe->getW(), pipe->getGapH() - pipe->getGapSize() / 2);
points[3] = Vector2(pipe->getX(), pipe->getGapH() - pipe->getGapSize() / 2);
}
else if (top == 1)
{
points[0] = Vector2(pipe->getX(), pipe->getGapH() + pipe->getGapSize() / 2);
points[1] = Vector2(pipe->getX() + pipe->getW(), pipe->getGapH() + pipe->getGapSize() / 2);
points[2] = Vector2(pipe->getX() + pipe->getW(), screenHeight);
points[3] = Vector2(pipe->getX(), screenHeight);
}
return points;
}
Vector2* Bird::getBirdPoints(Vector2* points)
{
points[0] = Vector2(36+screenPos.x,0+screenPos.y);
points[1] = Vector2(68+screenPos.x, 0+screenPos.y);
points[2] = Vector2(100+screenPos.x, 44+screenPos.y);
points[3] = Vector2(57+screenPos.x, 70+screenPos.y);
points[4] = Vector2(0+screenPos.x, 32+screenPos.y);
return points;
}
bool Bird::collisionDetection(Vector2* birdPoints, Vector2* pipePoints)
{
Vector2* axes = new Vector2[9];
//create array of axes for bird
for (int i = 0; i < 5; i++)
{
Vector2 p1 = birdPoints[i];
Vector2 p2 = birdPoints[i + 1 == 5 ? 0 : i + 1];
Vector2 edge = p1 - p2;//Vector2(p1.x - p2.x, p1.y - p2.y);
Vector2 normal = Vector2(-edge.y, edge.x);
axes[i] = normal;
}
//create array of axes for pipe
for (int i = 0; i < 4; i++)
{
Vector2 p1 = pipePoints[i];
Vector2 p2 = pipePoints[i + 1 == 5 ? 0 : i + 1];
Vector2 edge = p1 - p2;//Vector2(p1.x - p2.x, p1.y - p2.y);
Vector2 normal = Vector2(-edge.y, edge.x);
axes[i] = normal;
}
//loop through every axis
for (int i = 0; i < 9; i++)
{
double minBird = axes[0].Dot(birdPoints[0]);
double maxBird = minBird;
double minPipe = axes[0].Dot(pipePoints[0]);
double maxPipe = minPipe;
//projects every bird vertex to get min and max
for (int j = 1; j < 5; j++)
{
double p = axes[i].Dot(birdPoints[j]);
if (p < minBird) {
minBird = p;
}
else if (p > maxBird) {
maxBird = p;
}
}
//projects every pipe vertex to get min and max
for (int j = 1; j < 4; j++)
{
double p = axes[i].Dot(pipePoints[j]);
if (p < minPipe) {
minPipe = p;
}
else if (p > maxPipe) {
maxPipe = p;
}
}
//check overlap
if ((minBird < maxPipe && minBird > minPipe)
||
(minPipe < maxBird && minPipe > minBird))
{
continue;
}
else
{//if no everlap, no collsion
delete[] axes;
return false;
}
}
delete[] axes;
//There is collision
return true;
}
И код, который вызывает функцию из функции обновления:
//check each pipe
for (int i = 0; i < 6; i++)
{
//check both upper and lower pipe
for (int j = 0; j < 1; j++)
{
Vector2 pipePointsArr[4];
Vector2* pipePoints = getPipePoints(pipePointsArr, i, j);
if (collisionDetection(birdPoints, pipePoints))
{
OutputDebugStringA("DEAD");
dead = true;
}
}
}
Если вам нужны какие-либо разъяснения, пожалуйста, спросите. Заранее спасибо.