SFML包围盒碰撞检测

3
我正在尝试编写我第一个SFML项目的一个非常基础的游戏。它是一个有关机器人的,它带有一个有关节的臂,只能用手弹气球。我的问题是,当检查钳子精灵是否与气球精灵相交时,无论气球或机器人钳子的放置位置如何,它始终返回true。我使用变换来放置机器人手臂的各个部分,这就是我认为导致问题的原因,但我不知道为什么。我已经在另一个程序中尝试了边界框碰撞,在那里未使用变换并且它完美地工作了。转换和检测代码如下。如果有人能解释一下这个问题,我将不胜感激。对于SFML我是全新的,所以请原谅我的无知!
    sf::Transform trBody;
    trBody.translate(sBodyPos);
    /////////////////////////////////////////////////

    sf::Transform trArm1;
    trArm1.translate(sArm1Pos);

    sf::Transform rotArm1;
    rotArm1.rotate(sArm1Rot);

    sf::Transform TR1 = trBody*trArm1*rotArm1;
    /////////////////////////////////////////////////

    sf::Transform trArm2;
    trArm2.translate(sArm2Pos);

    sf::Transform rotArm2;
    rotArm2.rotate(sArm2Rot);

    sf::Transform TR2 = TR1*trArm2*rotArm2;
    /////////////////////////////////////////////////

    sf::Transform trPincer1;
    trPincer1.translate(sPincer1Pos);

    sf::Transform TR3 = TR2*trPincer1;
    /////////////////////////////////////////////////

    sf::Transform trPincer2;
    trPincer2.translate(sPincer2Pos);

    sf::Transform TR4 = TR2*trPincer2;
    /////////////////////////////////////////////////
    sf::Transform trBalloon1;
    trBalloon1.translate(sBalloon1Pos);

    if (sPincer1.getGlobalBounds().intersects(sBalloon1.getGlobalBounds())){

        cout << "Bang" << endl;
        ballOneHit = true;

    }

    // Clear screen
    app.clear();
    app.draw(sArm2, TR2);
    app.draw(sPincer1, TR3);
    app.draw(sPincer2, TR4);
    app.draw(sArm1, TR1);
    app.draw(sBody, trBody);

    if (ballOneHit == false){

        app.draw(sBalloon1, trBalloon1);

    }

    // Update the window
    app.display();
1个回答

5
我猜测,旋转物体是罪魁祸首,因为旋转会不幸地扩大物体的范围。旋转后的边界矩形仍在屏幕确定的x-y平面内,但包含了旋转后的物体。作为说明,请看这张图片中文本的全局边界框:

bounding box rotation

请注意,这个框围绕着对象,但并不是您可能期望获得的原始边界框的旋转版本。用图形变换教程的话来说:
SFML实体可以提供其边界框。边界框是包含实体的最小矩形,其边缘与X和Y轴对齐。
为了解决这个问题,您可以尝试创建一个矩形,它将始终完全包含在对象的可见部分内,然后使用该矩形进行命中检测,而不是对象的边界框。

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Rob EatsEverything Delaney
@RobEatsEverythingDelaney 通常在对对象进行变换时,你应该坚持使用 sf::Transformable 类提供的函数,这样在长期运行中会更加干净整洁。请记住,实现 sf::Transformablesf::Drawable(例如 sf::Sprite)的类将跟踪由 sf::Transformable 中的函数创建的变换,并在不需要指定的情况下正确地绘制自己(你只需使用 window.draw(sprite); 即可)。 - Conduit
实现了 sf::Transformablesf::Drawable 的内置类。 - Conduit
@RobEatsEverythingDelaney,那个评论有帮助吗?如果是的话,我想把它移到我的回答正文中。 - Conduit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接