【发布时间】:2017-09-24 04:18:09
【问题描述】:
我正在重新创建经典游戏 Asteroids,但在让碰撞检测正常工作方面遇到了一些问题。目前,下面的代码运行良好,但由于某种原因,它只会检测到最后发射的导弹上的碰撞。我的意思是,如果我向静止的小行星直线发射 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
【问题讨论】:
-
这样的列表处理在 C++ 中是一种非常糟糕的做法。您应该改用标准容器,例如
std::vector。您作为助手引入的变量也应该是 const 并在首次分配时声明,而不是在函数顶部。至于您的实际问题,这里没有足够的信息来重现它。尝试编写一个单元测试来传递一些示例数据并检查结果。 -
@RonE 这需要的不仅仅是一条评论,但是,按照随机顺序 - 它容易出错,难以阅读(正如您刚刚演示的那样),难以维护,难以使用(写),它不是样式 - 它是生成的解决方案的基本功能和正确性。您也无法从任何现有算法中受益。
-
@RonE 按顺序排列-那么您在这里一定不是很活跃,不(这就是您阅读失败的原因,这会有所帮助-请参阅我的回答),不(容器不是“高级”),不。结构体的接口混合了存储和数据模型的关注点是普遍可怕的。
-
并且说清楚 - 如果我们在谈论 C,我的答案和反应会完全不同。但鉴于现代 C++ 工具集和目标,将这种原始方法强加给初学者是非常有害的。
-
@RonE 我也可以投诉!我目前正在维护一个遗留系统,其中自定义列表不是通用的,只能通过指针链接 - 这意味着调试工具更难用于检查数据,并且不同自定义列表有多个不同版本 - 我*MUCH*(我似乎无法足够强调这个词)宁愿为这些数据结构提供标准容器!