Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;游戏导弹碰撞检测_C++_Collision_Detection - Fatal编程技术网

C++ C++;游戏导弹碰撞检测

C++ C++;游戏导弹碰撞检测,c++,collision,detection,C++,Collision,Detection,我正在重新制作经典游戏《小行星》,但在正确进行碰撞检测方面遇到了一些问题。目前,下面的代码运行良好,但出于某种原因,它将只检测最后一枚发射的导弹上的碰撞。我的意思是,如果我在一个静止的小行星上发射3枚直线导弹,前两枚将穿过该小行星,而只有最后一枚将与它碰撞并按预期行动。我不太清楚为什么会发生这种情况,但我认为这与反复浏览导弹列表有关 以下是用于检测碰撞的部分工作函数: void checkMissileAsteroidCollision(struct particle *ast, struct

我正在重新制作经典游戏《小行星》,但在正确进行碰撞检测方面遇到了一些问题。目前,下面的代码运行良好,但出于某种原因,它将只检测最后一枚发射的导弹上的碰撞。我的意思是,如果我在一个静止的小行星上发射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;

            }
        }

    }
}
我在下面包含了两个链接,它们指向整个源文件及其头文件,这些代码是从那里来的,以防需要任何其他信息来找出发生这种情况的原因

gamestate.cpp:

gamestate.h:

这条线就是问题所在。此循环终止后,
ast
为空,但不会为外部
mis
循环的下一次迭代重置。这意味着只有
mis
循环的第一次迭代才能真正看到小行星

要更正此问题,请为此循环声明一个新变量:

for(struct particle *ast2 = ast ; ast2 ; ast2 = ast2->next)
(或者选择一个比
ast2
更好的名称)然后,显然,在循环体中将
ast
替换为
ast2

这条线就是问题所在。此循环终止后,
ast
为空,但不会为外部
mis
循环的下一次迭代重置。这意味着只有
mis
循环的第一次迭代才能真正看到小行星

要更正此问题,请为此循环声明一个新变量:

for(struct particle *ast2 = ast ; ast2 ; ast2 = ast2->next)

(或选择一个更好的名称而不是代码> AST2< /COD>),然后,显然,在循环体中用<代码> AST2替换<代码> AST/COM>。< /P> < P>这是一个更现代的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;
            }
        }
    }
}
//从结构中删除指针
void checkmissionleasteroid碰撞(标准::矢量和小行星,标准::矢量和导弹)
{
用于(自动和mis:导弹)
{
用于(自动和自动:小行星)
{
const auto missileX=mis.x;
const auto missley=mis.y;
常数x=ast.x;
常量自动小行星y=ast.y;
常量自动大小=ast.size;
如果(导弹<小行星X+小行星尺寸&&
missileX>Asternox&&
Misseley<小行星+小行星大小&&
Misseley>Asteroney&&mis.draw==1&&ast.draw==1)
{
碰撞计数器++;
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;
向量小行星{{0,0,0,0,0,0,0,0,10,true}; 矢量导弹{{5,5,0,0,0,0,0,10,true}; 检查导弹最小碰撞(小行星、导弹);
STD::CUT< P>这就是一个更现代的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;
            }
        }
    }
}
//从结构中删除指针
void checkmissionleasteroid碰撞(标准::矢量和小行星,标准::矢量和导弹)
{
用于(自动和mis:导弹)
{
用于(自动和自动:小行星)
{
const auto missileX=mis.x;
const auto missley=mis.y;
常数x=ast.x;
常量自动小行星y=ast.y;
常量自动大小=ast.size;
如果(导弹<小行星X+小行星尺寸&&
missileX>Asternox&&
Misseley<小行星+小行星大小&&
Misseley>Asteroney&&mis.draw==1&&ast.draw==1)
{
碰撞计数器++;
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;
向量小行星{{0,0,0,0,0,0,0,0,10,true}; 矢量导弹{{5,5,0,0,0,0,0,10,true}; 检查导弹最小碰撞(小行星、导弹);
STD::Cub这样的列表处理是C++中非常糟糕的实践。您应该使用标准容器,例如
std::vector
。作为助手引入的变量也应该是常量,并在首次赋值时声明,而不是在函数顶部。至于你的实际问题,这里没有足够的信息来重现。试着编写一个单元测试,通过一些示例数据并检查结果。@RonE可能需要超过一个注释所能容纳的范围,但是,随机顺序-它容易出错,难以读取(正如您刚才演示的那样),难以维护,难以使用(写入),并且它不是样式-它是生成的解决方案的基本功能和正确性。你也不能从任何现有的算法中受益。@RonE按顺序-那么你在这里肯定不是很活跃,不(这就是为什么你在阅读时失败了,这会有帮助-看我的答案),不(容器不是“高级的”),不。结构的界面混合了存储和数据模型的关注点,这是一个普遍可怕的界面。要说清楚——如果我们说的是C,我的回答和反应会完全不同。但是,鉴于现代C++工具集和目标,强制初学者使用这种原始方法是有害的。我目前正在维护一个遗留系统,其中自定义列表不是通用的,仅通过指针链接-这意味着调试工具更难用于检查数据,而且不同的自定义列表有多个不同版本-我想*多*(我似乎无法充分强调这个词)而是为那些数据结构使用标准容器!这样的列表处理是C++中非常糟糕的实践。您应该使用标准容器,例如
std::vector
。作为助手引入的变量也应该是常量,并在首次赋值时声明,而不是在函数顶部。至于你的实际问题,是的