You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

AABB碰撞检测中if(*yDepth>0)语句被编译器跳过问题求助

问题分析与解决方案

首先咱们来拆解你遇到的问题:明明测试时*yDepth的值大于0,却始终进不去if(*yDepth > 0)分支,甚至断点都提示无法命中。结合你的代码,我整理了几个核心原因和对应的修复方案:

1. 动态指针带来的优化/未初始化隐患

你给xDepthyDepthnormal都用了动态分配的指针,但这种局部变量完全没必要用堆内存——栈上的普通变量不仅更安全,还能避免编译器因"指针指向的值未被有效使用"而跳过分支的优化行为。

修复方案:替换指针为栈上普通变量

把代码里的动态指针全部改成栈变量,既简洁又能解决断点失效问题:

Vector2 normal;
Vector2 vFrom1to2(b->getX() - a->getX(), b->getY() - a->getY());
float xDepth = (a->getWidth()) + (b->getWidth()) - abs(vFrom1to2.x);
float yDepth = 0.0f;

if (xDepth > 0) {
    yDepth = (a->getHeight()) + (b->getHeight()) - abs(vFrom1to2.y);
    std::cout << "break";
    if (yDepth > 0) {
        // 现在这个分支应该能正常命中断点了
        if (xDepth < yDepth) {
            if (vFrom1to2.x < 0) {
                normal.x = -1;
                normal.y = 0;
            } else {
                normal.x = 1;
                normal.y = 0;
            }
        } else {
            if (vFrom1to2.y < 0) {
                normal.x = 0;
                normal.y = -1;
            } else {
                normal.x = 0;
                normal.y = 1;
            }
        }
    }
}

2. 隐藏的语法错误:把赋值写成了相等判断

虽然这不是分支被跳过的直接原因,但你的代码里有个致命逻辑错误:normal->x == -1相等比较,不是赋值!必须用单等号=替换双等号==,否则normal永远不会被正确设置。

3. 编译器优化导致断点失效

如果替换变量后还是有问题,大概率是Visual Studio的优化在搞鬼:

  • 打开项目属性,找到「C/C++」→「优化」,把优化级别改成「禁用优化(/Od)」
  • 确保当前调试配置是「Debug」而非「Release」(Release模式下编译器会做大量激进优化,很多断点会被跳过)

额外建议:更简洁的AABB碰撞检测实现

其实AABB碰撞检测可以写得更直观,避免复杂的depth计算逻辑,这里给你一个工业界常用的实现参考:

bool checkAABBCollision(const AABB* a, const AABB* b, Vector2& outNormal) {
    float left = b->getX() - (a->getX() + a->getWidth());
    float right = (b->getX() + b->getWidth()) - a->getX();
    float top = b->getY() - (a->getY() + a->getHeight());
    float bottom = (b->getY() + b->getHeight()) - a->getY();

    // 无碰撞情况
    if (left > 0 || right < 0 || top > 0 || bottom < 0) {
        return false;
    }

    // 找出最小穿透深度
    float minDepth = std::min({std::abs(left), std::abs(right), std::abs(top), std::abs(bottom)});

    // 设置碰撞法线
    if (minDepth == std::abs(left)) {
        outNormal = Vector2(-1, 0);
    } else if (minDepth == std::abs(right)) {
        outNormal = Vector2(1, 0);
    } else if (minDepth == std::abs(top)) {
        outNormal = Vector2(0, -1);
    } else {
        outNormal = Vector2(0, 1);
    }

    return true;
}

内容的提问来源于stack exchange,提问作者Cotchsloth

火山引擎 最新活动