You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Raylib沙盒游戏屏幕边界碰撞检测不准问题求解

问题根源

你代码的三个异常全部来自逻辑设计错误,核心问题如下:

  • 边界空隙:边界判断只检测方块左上角坐标,没有计入方块自身的宽高尺寸;且越界后执行坐标取反是反弹逻辑,不是停止逻辑,固定步长下落会让方块越过边界后才触发判断,反弹后自然和边界留空隙。
  • 方块闪烁:你把位置更新逻辑写在了绘制函数DrawMat()里,每帧先绘制方块再修改坐标,加上越界后坐标反复跳变,必然出现闪烁;同时没有用帧时间(deltaTime)适配帧率,不同刷新率下移动速度不稳定,会加重跳变感。另外你的主循环漏写了EndDrawing(),也会导致渲染异常。
  • X轴不对齐:X轴越界后直接坐标取反的逻辑会让方块左右来回反弹,根本不会静止,自然无法对齐。
  • 额外冗余问题:你定义的SpeedX/SpeedY/Gravity等物理参数完全没有被使用,下落位移直接写死加9.81,不符合物理运动计算逻辑。
修复方案

核心调整原则:物理更新和绘制逻辑拆分,边界判断计入方块尺寸,越界后直接钳制坐标并标记停止,用帧时间保证运动速度和帧率无关。

1. 重写Mat结构体

把更新和绘制逻辑拆开,新增停止状态标记:

struct Mat
{
    Vector2 pos;
    Vector2 size;
    Color color;
    float fallSpeed;
    bool isStopped;

    // 仅负责物理状态更新,不做绘制
    void Update(float deltaTime) {
        if (isStopped) return;

        // 按帧时间计算下落位移,保证不同帧率下速度一致
        pos.y += fallSpeed * deltaTime;

        // 底部边界检测:计入方块高度,触底后直接贴边并标记停止
        float screenH = GetScreenHeight();
        if (pos.y + size.y >= screenH) {
            pos.y = screenH - size.y;
            isStopped = true;
        }

        // 左右边界钳制,防止方块超出屏幕
        float screenW = GetScreenWidth();
        pos.x = Clamp(pos.x, 0, screenW - size.x);
    }

    // 仅负责绘制,不修改任何状态
    void Draw() {
        DrawRectangleV(pos, size, color);
    }
};

2. 修正主循环逻辑

调整执行顺序为「处理输入→更新物理→统一绘制」,补上缺失的渲染接口调用:

int main() {
    InitWindow(800, 600, "Sandbox Simulator");
    SetWindowState(FLAG_VSYNC_HINT);

    Mat Sand;
    Sand.size = {5, 5};
    Sand.color = YELLOW;
    Sand.fallSpeed = 300.0f; // 下落速度可自行调整
    Sand.isStopped = false;

    int Numof = 0;
    std::vector<Mat> positions = {};

    while (!WindowShouldClose())
    {
        float deltaTime = GetFrameTime();

        // 输入处理
        if (IsKeyPressed(KEY_ONE)) {
            Numof = 1;
        }

        if (Numof == 1 && IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
        {
            Sand.pos = GetMousePosition();
            Sand.isStopped = false; // 新生成的方块为运动状态
            positions.push_back(Sand);
        }

        // 批量更新所有方块物理状态
        for (size_t i = 0; i < positions.size(); i++)
        {
            positions[i].Update(deltaTime);
        }

        // 统一绘制
        BeginDrawing();
        ClearBackground(BLACK);
        for (size_t i = 0; i < positions.size(); i++)
        {
            positions[i].Draw();
        }
        EndDrawing(); // 必须补上,否则会出现渲染异常
    }

    CloseWindow();
    return 0;
}
修复效果
  • 方块触底时会完全贴齐屏幕下边缘,不存在空隙
  • 物理更新和绘制顺序正确,帧率适配后运动平滑,无闪烁问题
  • 方块下落过程X坐标保持点击时的数值不变,停止后同列方块完全对齐

问题效果参考图

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:51:18