raylib raygui 即时模式 GUI10 行滑块到参数面板再到滚动列表【免费下载链接】raylibA simple and easy-to-use library to enjoy videogames programming项目地址: https://gitcode.com/GitHub_Trending/ra/raylib你在写个小游戏想加个面板让用户实时调参数。传统 GUI 框架要你维护状态树、挂回调、管事件队列。raylib 自带的 raygui 换个思路每帧把控件当普通函数调用直接传变量指针画完就算完。这篇文章从 10 行代码开始给你三条能落地的用法。30 秒跑通这段代码创建窗口放一个滑块控制一个圆点的位置#define RAYGUI_IMPLEMENTATION #include raygui.h #include raylib.h int main(void) { InitWindow(320, 160, raygui 最小示例); float value 0.5f; while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(RAYWHITE); GuiSliderBar((Rectangle){ 20, 20, 280, 20 }, 参数, TextFormat(%.2f, value), value, 0.0f, 1.0f); DrawCircle(20 280 * value, 100, 15, RED); EndDrawing(); } CloseWindow(); return 0; }上面发生了什么#define RAYGUI_IMPLEMENTATION让头文件自带实现不用单独链接库。滑块绑上value你拖动它value就跟着变下面那行DrawCircle直接拿它当横坐标。没有控件树没有回调就是一个浮点数的变化。机制拆解为什么每帧都要调一遍控件即时模式和保留模式的区别保留模式 GUI 里按钮是对象你创建它、它自己记按下状态、事件触发时调你的回调。即时模式反过来按钮每帧都是一次普通的函数调用。调用发生在BeginDrawing()到EndDrawing()之间raygui 在绘制控件的同时读鼠标键盘状态完成高亮、焦点、取值这些交互逻辑。返回值代表本帧有没有被点击变量指针负责同步值。// 返回值当点击事件用不存控件对象 if (GuiButton((Rectangle){ 100, 300, 120, 36 }, 重置)) { value 0.5f; }好处是状态天然没有滞后你改完value下一帧滑块自动画到新位置不存在UI 没刷新这种 bug。代价也明摆着你每帧都得调一次不调它就不存在。场景一用滑块控制游戏对象先做最简单的联动滑块值直接驱动绘制。InitWindow(800, 450, raygui 场景一滑块联动); float progress 0.0f; while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(RAYWHITE); // 滑块绑 progress圆点位置跟着它走 GuiSliderBar((Rectangle){ 40, 40, 300, 24 }, 进度, TextFormat(%.2f, progress), progress, 0.0f, 1.0f); DrawCircle(40 300 * progress, 200, 20, SKYBLUE); EndDrawing(); } CloseWindow();注意第三参textRight传TextFormat出来的字符串滑块右端会实时显示当前值。想留白就传NULL。场景二做一个参数面板把滑块、复选框、下拉框、按钮装进一个GuiGroupBox圆角矩形跟着参数实时变。InitWindow(640, 400, raygui 场景二参数面板); float width 200.0f, corner 0.1f; bool rounded true; int colorIndex 0; while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(RAYWHITE); GuiGroupBox((Rectangle){ 10, 10, 300, 340 }, 圆角矩形参数); GuiSliderBar((Rectangle){ 30, 44, 260, 24 }, 宽度, TextFormat(%.0f, width), width, 50.0f, 320.0f); GuiSliderBar((Rectangle){ 30, 84, 260, 24 }, 圆角, TextFormat(%.2f, corner), corner, 0.0f, 0.5f); // 下拉框带 editModefalse 时点击直接展开 GuiDropdownBox((Rectangle){ 30, 124, 260, 30 }, 红色;蓝色;绿色, colorIndex, false); GuiToggle((Rectangle){ 30, 168, 120, 32 }, 启用圆角, rounded); if (GuiButton((Rectangle){ 30, 214, 260, 32 }, 随机参数)) { width 50.0f 270.0f * (float)GetRandomValue(0, 100) / 100.0f; corner 0.1f 0.3f * (float)GetRandomValue(0, 100) / 100.0f; } Color colors[3] { RED, BLUE, GREEN }; Rectangle target { 340, 120, width, 200 }; // rounded 为 false 时退化成普通矩形体现复选框作用 if (rounded) DrawRectangleRounded(target, corner, 8, colors[colorIndex]); else DrawRectangleRec(target, colors[colorIndex]); EndDrawing(); } CloseWindow();面板控件全绑在普通变量上if (GuiButton(...))里改变量下一帧画布自动跟上。这就是即时模式的日常节奏。场景三画一张可滚动的实时列表参数一多就放不下用GuiScrollPanel加剪贴区处理。仓库里的examples/shapes/shapes_pie_chart.c就是这个路子下面给一个缩小的等价版。InitWindow(640, 480, raygui 场景三滚动面板); #define PARAM_COUNT 12 float params[PARAM_COUNT]; bool editing[PARAM_COUNT] { false }; char number[32] { 0 };滚动面板每帧算出可见区域滑块的偏移量存进contentOffset可见框存进viewRectangle panel { 20, 20, 600, 440 }; Rectangle content { 0, 0, 600.0f, (float)PARAM_COUNT * 40 }; Vector2 contentOffset { 0, 0 }; Rectangle view { 0 }; GuiScrollPanel(panel, NULL, content, contentOffset, view);BeginScissorMode把绘制裁进可见框滑出界的行画了也看不见。每行一个滑块加一个数值输入框两种操作改同一个数BeginScissorMode((int)view.x, (int)view.y, (int)view.width, (int)view.height); for (int i 0; i PARAM_COUNT; i) { int rowY (int)(view.y contentOffset.y i * 40); DrawText(TextFormat(P%02d, i 1), (int)(view.x 10), rowY 8, 20, BLACK); GuiSliderBar((Rectangle){ view.x 60, (float)rowY, 300, 28 }, NULL, NULL, params[i], 0.0f, 100.0f); // 返回值 true 表示这帧该框被点中翻转 editing 状态 if (GuiTextBox((Rectangle){ view.x 380, (float)rowY, 120, 28 }, number, 32, editing[i])) editing[i] !editing[i]; if (editing[i]) { params[i] (float)Atoi(number); snprintf(number, 32, %.0f, params[i]); } } EndScissorMode();列表、编辑器、属性面板套路都一样滚轮管滚动剪贴管越界变量管数据。踩坑速查整个界面突然全都不响应某处调了GuiDisable()它管到GuiEnable()为止是全局状态。修法把GuiEnable()写在if外面保证一定执行。中文或 emoji 显示成方块raygui 默认用 raylib 内置字体只有 ASCII 码点。修法LoadFontEx一个含目标字符集的字体再GuiSetFont(f)。控件贴着窗口边缘一放大就切掉坐标写死了 800x450 时代的值。修法用GetScreenWidth() - 面板宽 - 边距这类相对算法定位置。下拉框传了四个参数报错GuiDropdownBox比GuiComboBox多一个editMode布尔参数false 表示点击直接展开。程序直接崩溃GuiSliderBar第五参是float*你塞了int*进去。修法给滑块配一个float变量展示时再强转。接入清单拿源码git clone https://gitcode.com/GitHub_Trending/ra/raylib把examples/shapes/raygui.h复制到你工程目录和raylib.h放一起。在你要用控件的那个 .c 文件里#define RAYGUI_IMPLEMENTATION #include raygui.h编译时把它当普通源文件参与编译。控件每帧重画不需要额外的 UI 初始化步骤。写完了想接着学去翻examples/shapes/shapes_pie_chart.c和examples/audio/audio_amp_envelope.c一个练滚动面板加剪贴区一个练滑块调音效参数的完整闭环。【免费下载链接】raylibA simple and easy-to-use library to enjoy videogames programming项目地址: https://gitcode.com/GitHub_Trending/ra/raylib创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
