我正在重建经典游戏小行星,我在使碰撞检测正常工作方面遇到了一些问题。目前,下面的代码运行良好,但由于某种原因,它只会检测最后一枚已经发射的导弹上的碰撞。我的意思是如果我在一颗静止的小行星上直线发射3枚导弹,前两颗将穿过小行星,而只有最后一颗将与它碰撞并按预期行动。我不太清楚为什么会这样,但我认为这与迭代导弹列表有关。
这是用于检测碰撞的部分工作函数:
void checkMissileAsteroidCollision(struct particle *ast, struct particle *mis)
{
float missileX = 0;
float missileY = 0;
float asteroidX = 0;
float asteroidY = 0;
float asteroidSize = 0;
for( ; mis ; mis = mis->next )
{
missileX = mis->x;
missileY = mis->y;
for( ; ast ; ast = ast->next)
{
asteroidX = ast->x;
asteroidY = ast->y;
asteroidSize = ast->size;
if(missileX < asteroidX + asteroidSize &&
missileX > asteroidX &&
missileY < asteroidY + asteroidSize &&
missileY > asteroidY && mis->draw == 1 && ast->draw == 1)
{
collisionCounter++;
ast->draw = 0;
mis->draw = 0;
}
}
}
}
粒子结构;
typedef struct particle{
float x;
float y;
float vx;
float vy;
float heading;
float dur;
int size;
int draw;
struct particle *next;
} node_t;
我已经在下面链接了两个链接,指向整个源文件及其代码来自的标题,以防需要任何其他信息来弄清楚为什么会发生这种情况。
gamestate.cpp:https://gist.github.com/Jakemangan/d286ef1f9159e6682778ec2e0daf516c
gamestate.h:https://gist.github.com/Jakemangan/6c3788a46825a86cd0e2642864fcad68
答案 0 :(得分:5)
for( ; ast ; ast = ast->next)
这一行是问题所在。在此循环终止后,ast
为空,但不会为外部mis
循环的下一次迭代重置。这意味着只有mis
循环的第一次迭代才会实际看到任何小行星。
要纠正此问题,请为此循环声明一个新变量:
for(struct particle *ast2 = ast ; ast2 ; ast2 = ast2->next)
(或选择比ast2
更好的名称。)然后,显然,在循环体中将ast
替换为ast2
。
答案 1 :(得分:1)
这是更现代的C ++版本的样子:
// drop the pointer from the struct
void checkMissileAsteroidCollision(std::vector<particle>& asteroids, std::vector<particle>& missiles)
{
for(auto & mis : missiles)
{
for(auto & ast : asteroids)
{
const auto missileX = mis.x;
const auto missileY = mis.y;
const auto asteroidX = ast.x;
const auto asteroidY = ast.y;
const auto asteroidSize = ast.size;
if(missileX < asteroidX + asteroidSize &&
missileX > asteroidX &&
missileY < asteroidY + asteroidSize &&
missileY > asteroidY && mis.draw == 1 && ast.draw == 1)
{
collisionCounter++;
ast.draw = false;
mis.draw = false;
}
}
}
}
然后创建和使用示例:
std::vector<particle> asteroids { { 0, 0, 0, 0, 0, 0, 10, true } };
std::vector<particle> missiles { { 5, 5, 0, 0, 0, 0, 10, true } };
checkMissileAsteroidCollision(asteroids, missiles);
std::cout << std::boolalpha << asteroids[0].draw;
这里有更多的改进(在类中封装,不使参数变异,不使用draw
作为碰撞标志),但我相信这些属于Code Review,我鼓励你发布你的一旦你开始工作就可以解决问题。