C++ Raylib实现窗口边缘碰撞检测 解决小球出屏问题
Raylib 2D小球边界拦截失效修复
问题根源
- 渲染逻辑顺序违规:Raylib所有
Draw*开头的渲染API必须放在BeginDrawing()与EndDrawing()的配对区间内才能正常生效。原代码把文字绘制、小球绘制、边界判断全部写在了BeginDrawing()之前,逻辑执行顺序完全错乱,直接导致边界拦截规则不生效。 - 边界阈值计算错误:原代码绘制小球时将
ballPosition作为中心点,绘制时往左上角偏移50像素对齐纹理,说明小球实际半径为50像素。原边界判断直接以窗口宽高800、600作为阈值,就算逻辑顺序正确,也会出现小球一半穿出屏幕后才被拦截的问题。 - 资源加载逻辑错误:
LoadTexture("ball.png")放在主循环内部,会每帧重复加载同一份纹理资源,造成内存泄漏。
修正后可运行代码
#include <raylib.h> int main() { const int screenWidth = 800; const int screenHeight = 600; InitWindow(screenWidth, screenHeight, "My Game!"); const float ballRadius = 50.0f; Vector2 ballPosition = { screenWidth / 2.0f, screenHeight / 2.0f }; // 纹理仅在初始化阶段加载1次 Texture2D ball = LoadTexture("ball.png"); SetTargetFPS(60); while (!WindowShouldClose()) { // 第一步:处理按键移动逻辑 if (IsKeyDown(KEY_RIGHT)) ballPosition.x += 2.0f; if (IsKeyDown(KEY_LEFT)) ballPosition.x -= 2.0f; if (IsKeyDown(KEY_UP)) ballPosition.y -= 2.0f; if (IsKeyDown(KEY_DOWN)) ballPosition.y += 2.0f; // 第二步:边界判断修正坐标,必须在绘制前执行 if (ballPosition.x < ballRadius) ballPosition.x = ballRadius; if (ballPosition.x > screenWidth - ballRadius) ballPosition.x = screenWidth - ballRadius; if (ballPosition.y < ballRadius) ballPosition.y = ballRadius; if (ballPosition.y > screenHeight - ballRadius) ballPosition.y = screenHeight - ballRadius; // 第三步:所有渲染操作放在BeginDrawing/EndDrawing区间内 BeginDrawing(); ClearBackground(RAYWHITE); DrawText("move the ball with arrow keys", 10, 10, 20, DARKGRAY); DrawTexture(ball, ballPosition.x - ballRadius, ballPosition.y - ballRadius, WHITE); EndDrawing(); } // 释放资源后关闭窗口 UnloadTexture(ball); CloseWindow(); return 0; }
关键修改说明
- 调整了每帧的执行顺序:先处理输入更新坐标,再做边界修正,最后执行渲染,保证当前帧绘制的小球始终在合法区域内。
- 修正了边界阈值:结合小球50像素的半径,四个方向的拦截阈值分别预留出半径长度,保证小球刚好贴住窗口边缘,不会出现半身穿出屏幕的问题。
- 将纹理加载移到主循环外,仅初始化时加载一次,退出前调用
UnloadTexture释放资源,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Ralph Turner
相关产品推荐
相关产品推荐

