그래서 분리 축 정리를 사용하여 충돌 감지를 구현하는 데 도움이 필요, 내가 찾은 SAT를 사용하여 충돌을 감지의 기본 과정입니다 :는 인터넷 검색과 독서의 시간 후,
for each edge of poly A
project A and B onto the normal for this edge
if intervals do not overlap, return false
end for
for each edge of poly B
project A and B onto the normal for this edge
if intervals do not overlap, return false
end for
그러나, 많은 방법으로 코드에서 구현하려고하면 충돌을 감지 할 수 없습니다. 다음 나의 현재 코드 :
for (unsigned int i = 0; i < asteroids.size(); i++) {
if (asteroids.valid(i)) {
asteroids[i]->Update();
// Player-Asteroid collision detection
bool collision = true;
SDL_Rect asteroidBox = asteroids[i]->boundingBox;
// Bullet-Asteroid collision detection
for (unsigned int j = 0; j < player.bullets.size(); j++) {
if (player.bullets.valid(j)) {
Bullet b = player.bullets[j];
collision = true;
if (b.x + (b.w/2.0f) < asteroidBox.x - (asteroidBox.w/2.0f)) collision = false;
if (b.x - (b.w/2.0f) > asteroidBox.x + (asteroidBox.w/2.0f)) collision = false;
if (b.y - (b.h/2.0f) > asteroidBox.y + (asteroidBox.h/2.0f)) collision = false;
if (b.y + (b.h/2.0f) < asteroidBox.y - (asteroidBox.h/2.0f)) collision = false;
if (collision) {
bool realCollision = false;
float min1, max1, min2, max2;
// Create a list of vertices for the bullet
CrissCross::Data::LList<Vector2D *> bullVerts;
bullVerts.insert(new Vector2D(b.x - b.w/2.0f, b.y + b.h/2.0f));
bullVerts.insert(new Vector2D(b.x - b.w/2.0f, b.y - b.h/2.0f));
bullVerts.insert(new Vector2D(b.x + b.w/2.0f, b.y - b.h/2.0f));
bullVerts.insert(new Vector2D(b.x + b.w/2.0f, b.y + b.h/2.0f));
// Create a list of vectors of the edges of the bullet and the asteroid
CrissCross::Data::LList<Vector2D *> bullEdges;
CrissCross::Data::LList<Vector2D *> asteroidEdges;
for (int k = 0; k < 4; k++) {
int n = (k == 3) ? 0 : k + 1;
bullEdges.insert(new Vector2D(bullVerts[k]->x - bullVerts[n]->x,
bullVerts[k]->y - bullVerts[n]->y));
asteroidEdges.insert(new Vector2D(asteroids[i]->vertices[k]->x - asteroids[i]->vertices[n]->x,
asteroids[i]->vertices[k]->y - asteroids[i]->vertices[n]->y));
}
Vector2D *vectOffset = new Vector2D(asteroids[i]->center.x - b.x, asteroids[i]->center.y - b.y);
for (unsigned int k = 0; k < asteroidEdges.size(); k++) {
Vector2D *axis = asteroidEdges[k]->getPerpendicular();
axis->normalize();
min1 = max1 = axis->dotProduct(asteroids[i]->vertices[0]);
for (unsigned int l = 1; l < asteroids[i]->vertices.size(); l++) {
float test = axis->dotProduct(asteroids[i]->vertices[l]);
min1 = (test < min1) ? test : min1;
max1 = (test > max1) ? test : max1;
}
min2 = max2 = axis->dotProduct(bullVerts[0]);
for (unsigned int l = 1; l < bullVerts.size(); l++) {
float test = axis->dotProduct(bullVerts[l]);
min2 = (test < min2) ? test : min2;
max2 = (test > max2) ? test : max2;
}
float offset = axis->dotProduct(vectOffset);
min1 += offset;
max1 += offset;
delete axis; axis = NULL;
float d0 = min1 - max2;
float d1 = min2 - max1;
if (d0 > 0 || d1 > 0) {
realCollision = false;
break;
} else {
realCollision = true;
}
}
if (realCollision) {
for (unsigned int k = 0; k < bullEdges.size(); k++) {
Vector2D *axis = bullEdges[k]->getPerpendicular();
axis->normalize();
min1 = max1 = axis->dotProduct(asteroids[i]->vertices[0]);
for (unsigned int l = 1; l < asteroids[i]->vertices.size(); l++) {
float test = axis->dotProduct(asteroids[i]->vertices[l]);
min1 = (test < min1) ? test : min1;
max1 = (test > max1) ? test : max1;
}
min2 = max2 = axis->dotProduct(bullVerts[0]);
for (unsigned int l = 1; l < bullVerts.size(); l++) {
float test = axis->dotProduct(bullVerts[l]);
min2 = (test < min2) ? test : min2;
max2 = (test > max2) ? test : max2;
}
float offset = axis->dotProduct(vectOffset);
min1 += offset;
max1 += offset;
delete axis; axis = NULL;
float d0 = min1 - max2;
float d1 = min2 - max1;
if (d0 > 0 || d1 > 0) {
realCollision = false;
break;
} else {
realCollision = true;
}
}
}
if (realCollision) {
player.bullets.remove(j);
int numAsteroids;
float newDegree;
srand (j + asteroidBox.x);
if (asteroids[i]->degree == 90.0f) {
if (rand() % 2 == 1) {
numAsteroids = 3;
newDegree = 30.0f;
} else {
numAsteroids = 2;
newDegree = 45.0f;
}
for (int k = 0; k < numAsteroids; k++)
asteroids.insert(new Asteroid(asteroidBox.x + (10 * k), asteroidBox.y + (10 * k), newDegree));
}
delete asteroids[i];
asteroids.remove(i);
}
while (bullVerts.size()) {
delete bullVerts[0];
bullVerts.remove(0);
}
while (bullEdges.size()) {
delete bullEdges[0];
bullEdges.remove(0);
}
while (asteroidEdges.size()) {
delete asteroidEdges[0];
asteroidEdges.remove(0);
}
delete vectOffset; vectOffset = NULL;
}
}
}
}
}
bullEdges
가 asteroidEdges 유사하다 총알의 에지 벡터의리스트이며, bullVerts 소행성 [I] .vertices는 분명히 각 정점의 벡터리스트 각각의 총알이나 소행성에 대해.솔직히 말하면, 나는 코드 보정을 찾고 있지 않으며, 눈이 신선합니다.
정확히 무엇이 문제입니까? realCollision은 항상 거짓으로 나오고 있습니까? 테두리 상자 테스트가 작동합니까? 나는 명백한 것을 보지 못합니다, 당신은 단위 테스트를 할 수 있도록 별도의 방법으로 충돌 탐지를 분리해야합니다. –
경계 상자 충돌은 작동하지만 realCollision은 거의 항상 거짓으로 끝납니다. – Eddie
최신 코드로 업데이트하고 다른 기사를 읽고 포인트까지 따라갔습니다. – Eddie