Я работал над обнаружением столкновения между объектом в моей игре.Прямо сейчас все идет вертикально, но хотелось бы оставить возможность для другого движения открытой.Это классический двухмерный вертикальный космический шутер.
Сейчас я зацикливаюсь на каждом объекте, проверяя наличие столкновений:
for(std::list<Object*>::iterator iter = mObjectList.begin(); iter != mObjectList.end();) {
Object *m = (*iter);
for(std::list<Object*>::iterator innerIter = ++iter; innerIter != mObjectList.end(); innerIter++ ) {
Object *s = (*innerIter);
if(m->getType() == s->getType()) {
break;
}
if(m->checkCollision(s)) {
m->onCollision(s);
s->onCollision(m);
}
}
}
Вот как я проверяю столкновение:
bool checkCollision(Object *other) {
float radius = mDiameter / 2.f;
float theirRadius = other->getDiameter() / 2.f;
Vector<float> ourMidPoint = getAbsoluteMidPoint();
Vector<float> theirMidPoint = other->getAbsoluteMidPoint();
// If the other object is in between our path on the y axis
if(std::min(getAbsoluteMidPoint().y - radius, getPreviousAbsoluteMidPoint().y - radius) <= theirMidPoint.y &&
theirMidPoint.y <= std::max(getAbsoluteMidPoint().y + radius, getPreviousAbsoluteMidPoint().y + radius)) {
// Get the distance between the midpoints on the x axis
float xd = abs(ourMidPoint.x - theirMidPoint.x);
// If the distance between the two midpoints
// is greater than both of their radii together
// then they are too far away to collide
if(xd > radius+theirRadius) {
return false;
} else {
return true;
}
}
return false;
}
Проблема в том, что он случайным образом правильно обнаруживает столкновения, но в других случаях он вообще не обнаруживается.Это не оператор if, выходящий из цикла объектов, потому что объекты имеют разные типы.Чем ближе объект находится к верхней части экрана, тем выше вероятность того, что столкновение будет правильно обнаружено.Чем ближе к нижней части экрана, тем меньше у него шансов на то, чтобы его правильно или вообще не обнаружили.Однако такие ситуации не всегда случаются.Диаметр объектов огромен (10 и 20), чтобы понять, в этом ли проблема, но это мало помогает.
РЕДАКТИРОВАТЬ - Обновлен код
bool checkCollision(Object *other) {
float radius = mDiameter / 2.f;
float theirRadius = other->getDiameter() / 2.f;
Vector<float> ourMidPoint = getAbsoluteMidPoint();
Vector<float> theirMidPoint = other->getAbsoluteMidPoint();
// Find the distance between the two points from the center of the object
float a = theirMidPoint.x - ourMidPoint.x;
float b = theirMidPoint.y - ourMidPoint.y;
// Find the hypotenues
double c = (a*a)+(b*b);
double radii = pow(radius+theirRadius, 2.f);
// If the distance between the points is less than or equal to the radius
// then the circles intersect
if(c <= radii*radii) {
return true;
} else {
return false;
}
}