gpt4 book ai didi

c++ - 零星碰撞检测

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:57:28 25 4
gpt4 key购买 nike

我一直致力于检测游戏中对象之间的碰撞。现在一切都是垂直的,但希望保持其他运动的选择。这是经典的 2d 垂直空间射击游戏。

现在我遍历每个对象,检查碰撞:

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;
}
}

最佳答案

当两个圆形物体的中心距离足够小时,它们就会发生碰撞。您可以使用以下代码进行检查:

double distanceSquared =
pow(ourMidPoint.x - theirMidPoint.x, 2.0) +
pow(ourMidPoint.x - theirMidPoint.x, 2.0);
bool haveCollided = (distanceSquared <= pow(radius + theirRadius, 2.0));

为了检查两个时间点之间是否存在碰撞,您可以在时间间隔的开始和结束时检查碰撞;但是,如果物体移动得非常快,碰撞检测可能会失败(我猜你遇到过这个问题,因为物体在屏幕底部以最快的速度坠落)。

以下内容可能会使碰撞检测更加可靠(尽管仍不完美)。假设物体以恒定速度运动;然后,他们的位置是时间的线性函数:

our_x(t) = our_x0 + our_vx * t;
our_y(t) = our_y0 + our_vy * t;
their_x(t) = their_x0 + their_vx * t;
their_y(t) = their_y0 + their_vy * t;

现在您可以将它们之间的(平方)距离定义为时间的二次函数。找出它在什么时候取最小值(即它的导数为 0);如果这个时间属于当前时间间隔,则计算最小值并检查是否有碰撞。

这必须足以几乎完美地检测到碰撞;如果您的应用程序大量使用自由落体物体,您可能希望将运动函数细化为二次函数:

our_x(t) = our_x0 + our_v0x * t;
our_y(t) = our_y0 + our_v0y * t + g/2 * t^2;

关于c++ - 零星碰撞检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5413822/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com