100 行把 UI 接进 raylib:raygui 即时模式控件实战

发布时间:2026/9/2 14:18:53
100 行把 UI 接进 raylib:raygui 即时模式控件实战 100 行把 UI 接进 raylibraygui 即时模式控件实战【免费下载链接】raylibA simple and easy-to-use library to enjoy videogames programming项目地址: https://gitcode.com/GitHub_Trending/ra/raylibraylib 项目里画 2D、3D 场景的人很多但要做个设置页、调试面板就卡住了——不想为界面单独引入 Qt 这种重型依赖。raygui 是仓库自带的即时模式 GUIIMGUI每帧直接重绘全部控件、不缓存控件状态单头文件、零额外构建配置放进行程循环里调用函数就出界面。这篇文章从 20 行可编译的最小例子开始走到 3D 相机调试面板最后聊几个真实会踩的坑。先让一个按钮亮起来最小目标是窗口里出现一个按钮点一下界面上的计数跟着变。整份代码可以编译运行#include raylib.h #define RAYGUI_IMPLEMENTATION // 展开 raygui 实现必须写在 include 之前 #include raygui.h int main(void) { InitWindow(800, 450, raygui 最小示例); int clicks 0; // 即时模式状态就是普通变量没有控件对象 while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(RAYWHITE); // 点击的那一帧返回值非 0无需注册回调 if (GuiButton((Rectangle){ 10, 10, 140, 40 }, 点我)) clicks; DrawText(TextFormat(已点击 %d 次, clicks), 10, 70, 20, BLACK); EndDrawing(); } CloseWindow(); return 0; }和保留模式 UI 的本质区别在这里raygui 的控件没有生命周期clicks这种状态完全由你自己声明、自己更新控件函数只是画出来 本帧检测输入。为什么这样反而省心因为不存在控件销毁时忘删回调、状态对象泄漏这类问题UI 状态和游戏状态是同一批变量。注意#define RAYGUI_IMPLEMENTATION必须出现在#include raygui.h之前且整个工程只允许有一个 .c 文件这样写否则会重复定义。3 行让滑块跟手想让玩家或你自己实时调参数核心就是把变量的地址传给控件控件替你处理鼠标拖动逻辑float width 200.0f, roundness 0.2f; bool fill true; // 每帧循环内 GuiSliderBar((Rectangle){ 600, 40, 150, 20 }, Width, TextFormat(%.0f, width), width, 50, 500); GuiSliderBar((Rectangle){ 600, 70, 150, 20 }, Roundness, TextFormat(%.2f, roundness), roundness, 0, 1); GuiCheckBox((Rectangle){ 600, 110, 20, 20 }, Filled, fill); if (fill) DrawRectangleRounded((Rectangle){ 100, 150, width, 150 }, roundness, 20, RAYBLUE);GuiSliderBar要求float *所以width、roundness用 float如果参数是整数换GuiValueBox可键盘输入或GuiSpinner带上下箭头更合适。右边第三个参数是给滑块尾部显示的文字传NULL就只留左侧标签。官方圆角矩形绘制示例就是这个套路右侧一排滑块加复选框实时控制左侧图形的宽、高、圆角和线宽完整效果长这样把调试面板塞进 3D 场景相机调试面板是 3D 开发里最高频的需求。注意当前仓库的Camera就是Camera3D字段是position / target / up / fovy / projection没有旧版文档里的rotation代码要对准这些字段void DrawDebugPanel(Camera *cam) { GuiGroupBox((Rectangle){ 10, 10, 260, 180 }, Camera); GuiSliderBar((Rectangle){ 30, 50, 200, 20 }, FovY, TextFormat(%.0f, cam-fovy), cam-fovy, 20, 90); GuiSliderBar((Rectangle){ 30, 80, 200, 20 }, Height, NULL, cam-position.y, 0, 100); GuiSliderBar((Rectangle){ 30, 110, 200, 20 }, Dist, NULL, cam-position.z, -50, 50); // projection 是 int 枚举用独立 bool 桥接一下 static bool ortho false; if (GuiCheckBox((Rectangle){ 30, 145, 20, 20 }, Ortho, ortho)) cam-projection ortho ? CAMERA_ORTHOGRAPHIC : CAMERA_PERSPECTIVE; }GuiGroupBox只画一个带标题的边框真正的控件坐标你自己摆在它内部。GuiCheckBox要bool *而projection是 int这里用局部 bool 捕获勾选动作发生的返回值再同步进相机比强转指针干净。面板函数放进每帧循环和场景一起绘制即可——2D 面板画在 3D 场景之后坐标就是屏幕坐标不需要投影变换。2 行改掉控件配色 默认灰白风格想换成自己的美术风格用GuiSetStyle按控件 属性逐条覆盖颜色直接传 raylib 的 Color 数值// 只改按钮的正常态底色和文字色 GuiSetStyle(BUTTON, BASE_COLOR_NORMAL, GREEN); GuiSetStyle(BUTTON, TEXT_COLOR_NORMAL, RAYWHITE); GuiButton((Rectangle){ 10, 10, 120, 30 }, 自定义样式);属性枚举BASE_COLOR_NORMAL、TEXT_COLOR_PRESSED等和控件枚举BUTTON、SLIDER、DEFAULT……都定义在 raygui.h 里DEFAULT控件改的是全局默认值适合开局统一刷一遍圆角、间距、描边宽度。想要一整套主题可以用官方样式工具生成.rbg样式文件后用GuiLoadStyle(style.rbg)加载比手写几十条GuiSetStyle省事得多。三个容易翻车的坑 ️下拉框选项是分号字符串。5.0 版GuiDropdownBox的第二个参数是Easy;Normal;Hard这种分号分隔串不再是旧教程里的字符串数组传错类型编译就会报错int active 0; // 当前选中项索引 GuiDropdownBox((Rectangle){ 250, 10, 140, 30 }, Easy;Normal;Hard, active, false);中文会显示成方块。raygui 默认内置字体只有拉丁字形界面要出中文先用LoadFont加载一份覆盖中文字形的 ttf 再应用到 raygui别指望改样式能解决。控件别出屏。GetScreenHeight()是窗口内边高把面板写在窗口高度范围内窗口动态缩放时把硬编码坐标换成GetScreenWidth() - 面板宽 - 边距这类相对算式参考圆角矩形示例里滑块坐标的写法。延伸资源想往下走直接看仓库里这些文件每份都带可运行代码和效果图raygui.h单头文件实现所有控件的签名和枚举都在这shapes_rounded_rectangle_drawing.c滑块 复选框调参数的完整范例core_3d_camera_free.c3D 相机操作配合上面的调试面板用examples/examples_list.txt全部示例清单按目录找带 GUI 的例子projects/CMake/CMake 工程模板照抄可编译结构跑通最小按钮只是起点——把参数面板、滚动列表GuiScrollPanel、颜色选择器GuiColorPicker组合起来游戏内的配置界面基本就齐了。【免费下载链接】raylibA simple and easy-to-use library to enjoy videogames programming项目地址: https://gitcode.com/GitHub_Trending/ra/raylib创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考