ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

raygui 从 0 到 1:给 C 语言游戏装上一块能拖能点的设置面板

raygui 从 0 到 1:给 C 语言游戏装上一块能拖能点的设置面板 raygui 从 0 到 1给 C 语言游戏装上一块能拖能点的设置面板【免费下载链接】raylibA simple and easy-to-use library to enjoy videogames programming项目地址: https://gitcode.com/GitHub_Trending/ra/raylibC 游戏缺什么最影响观感答案通常是音量、画质、难度这些设置而 raylib 附带的单文件即时模式 GUI 模块 raygui 就是补上这块的 C 语言 GUI 控件方案一个头文件拷进项目十几行代码就能画出一个滑块加一个开关。这篇 raygui 教程按接入 → 跑通 → 排错 → 进阶的顺序走一遍所有 API 签名均已对照仓库内的raygui.hv5.0源码核实。给 C 游戏装面板raygui 为什么合适先说结论你要的状态全在自己变量里raygui 只负责每帧把变量画出来、再读一次输入写回去。把 raygui 想成点餐小票厨房不记单每来一单都重打一张照着做。即时模式 GUI 同理——控件没有实例不注册、不销毁、不维护 ID声明它的代码跑过去的那一刻它就被画出来了。上一帧的控件和这一帧的控件是两个不同的人唯一连续存在的是你传给它的那几个变量。这套模型带来两个直接好处不用管理控件生命周期删除界面上的一块区域删掉对应的声明即可布局没有自动排版raygui.h头注释里明确写了 No auto-layout mechanism每个控件的位置尺寸都要你自己算换来的是完全可控。从仓库把 raygui.h 接进项目raylib 仓库里raygui.h放在examples/的各模块目录下每个模块各有一份内容相同的副本实际用时拷一份到自己项目即可。// panel.c —— 整个工程里只有这一处定义宏 #define RAYGUI_IMPLEMENTATION // 把 raygui 的实现编译进本翻译单元 #include raygui.h宏RAYGUI_IMPLEMENTATION必须在有且仅有一个.c文件里写实现代码就从这个宏后面展开其他源文件只写#include raygui.h拿到的是声明。编译时照常链接 raylib例如gcc demo.c panel.c -lraylib -o demo。仓库地址是 https://gitcode.com/GitHub_Trending/ra/raylib clone 下来即可。第一条滑块最小可运行示例单文件、能直接跑的版本长这样#include raylib.h #define RAYGUI_IMPLEMENTATION #include raygui.h int main(void) { InitWindow(520, 300, raygui demo); float g_vol 0.35f; // 0~1 音量 bool g_speakerOn true; // 喇叭开关 while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(LIGHTGRAY); int pct (int)(g_vol * 100); GuiSliderBar((Rectangle){ 48, 64, 240, 26 }, VOL, TextFormat(%d%%, pct), g_vol, 0.0f, 1.0f); GuiCheckBox((Rectangle){ 48, 118, 24, 24 }, SPEAKER, g_speakerOn); EndDrawing(); } CloseWindow(); return 0; }GuiSliderBar的四个参数依次是位置尺寸Rectangle、左端标签、右端文本、数值指针加取值区间返回值非 0 表示这一帧滑块被碰过。GuiCheckBox更简单指针指向那个bool复选框的勾选状态就存在变量里。跑起来后拖一下滑块变量在变画面就跟着变没有其他任何同步代码。控件隔帧就失忆即时模式的记账规则很多人第一次接触即时模式 GUI 时的疑问是控件不存状态那它凭什么记得我上次拖到哪答案是它不记也不需要记你每帧把变量的当前值递过去画出来的就是这个值。这也解释了三个容易踩的点想让下拉框展开、让文本框处于编辑态开合状态得由你自己用一个bool存着、每帧回传界面上任何记住上一步的效果实现方式都是上一帧把结果写进变量这一帧变量再画出来控件返回的永远是本帧发生了什么不是一段持续的历史想触发一次性动作就用它的返回值判断。按交互目的选控件一张速查表选型只看一件事用户要做哪种动作。四种最常用的 C 语言 GUI 控件用法如下均摘自各控件的函数签名交互目的控件一行调用连续数值0~1 音量、半径滑块GuiSliderBar(rec, VOL, TextFormat(%d%%, pct), g_vol, 0.0f, 1.0f);开 / 关切换复选框GuiCheckBox(rec, SPEAKER, g_speakerOn);按钮形态的开关适合面板角落开关按钮GuiToggle(rec, MUTE, g_mute);有限选项三选一下拉框GuiDropdownBox(rec, LOW;MID;HIGH, g_quality, false);整数加减速1~10 切片数步进器GuiSpinner(rec, SLICES, g_slices, 1, 10, false);两个细节值得留意滑块右端的数字显示不会自动生成传NULL就不画传文本就显示下拉框的选项是用分号连起来的一个字符串选中项是int下标从 0 开始。返回值语义各控件略有差别但思路一致。GuiCheckBox在用户真正勾选/取消的那一帧才返回 1所以if (GuiCheckBox(...)) PlaySoundClick();这种写法天然是点击瞬间触发一次。而GuiDropdownBox的第四参editMode语义不同——传false时它自己管理开合点击展开、松开收起调用方只管读指针里的选中项传true则强制保持展开配合手动翻转的bool可以做常驻展开的列表头。实战样本饼图示例右侧的整块控制台仓库examples/shapes/shapes_pie_chart.c是 raygui 用法的集大成示例右侧 270 像素宽的面板里GuiSpinner调切片数、三个GuiCheckBox切换数值/百分比/环形显示、GuiSliderBar控制内环半径下方GuiScrollPanel里每行还嵌了一个文本框加一个滑块。读这个文件最大的收获是看清职责边界切片扇形是用DrawCircleSector自己算角度画的raygui 只管面板上那些问用户要参数的控件而shapes_splines_drawing.c则展示了另一种混排——样条控制点靠GetMousePosition()自己做命中检测和下拉框、滑块和平共处。记住这条线输入与控件渲染归 raygui业务绘制归你。每行一个编辑器的列表滚动面板加剪切区控件多到放不下时仓库示例给出了标准答案GuiScrollPanel给出可视区BeginScissorMode裁掉滚出屏幕的内容内容按滚动偏移量平移int scroll 0; // 当前滚动偏移 int h rows * 34; // 内容总高 GuiScrollPanel((Rectangle){ 20, 40, 220, 200 }, NULL, (Rectangle){ 0, 0, 210, (float)h }, scroll, view); BeginScissorMode((int)view.x, (int)view.y, (int)view.width, (int)view.height); for (int i 0; i rows; i) { int y (int)(view.y 5 i * 34 scroll); if (y view.y y view.y view.height) GuiSliderBar((Rectangle){ view.x 10, (float)y, 190, 26 }, NULL, NULL, values[i], 0.0f, 1.0f); } EndScissorMode();view是可视区在内容坐标下的窗口scroll每帧由滚动条写回行循环里那句if是滚动列表的通用优化滚出视野的行直接跳过声明反正即时模式没有不画就不存在的成本跳过就是省。这套模式可以原样搬到参数编辑器、音量混音台这类一行一个值的界面上。窗口拉大后控件不跟手的解法硬编码坐标的面板一拉窗口就错位。修法是把面板锚在哪条边写成每帧重算的表达式int winW GetScreenWidth(), winH GetScreenHeight(); const int panelW 240; float ax winW - panelW - 14; // 右缘锚点 float ay winH - 170 - 14; // 底缘锚点 GuiSliderBar((Rectangle){ ax 18, ay, (float)(panelW - 36), 24 }, LV, TextFormat(%d, g_level), g_level, 1.0f, 5.0f);两个要点所有控件坐标都从ax/ay派生窗口尺寸一变下一帧自动落回正确位置开了高分屏缩放的平台上GetScreenWidth/Height返回的已经是逻辑分辨率别再手动乘 DPI 系数。如果面板外还有可拖拽的自定义实体每帧拿GetMousePosition()减去实体自己的包围矩形做命中检测即可raygui 不会挡住你自己写的输入逻辑。文字超框、中文变方块、分配抖动三个高频 raygui 踩坑这三个坑几乎人人会遇到对应的修复都是一行级文字贴边或画出框外 → 默认字号配 20 像素高的控件确实挤GuiSetStyle(DEFAULT, DEFAULT_TEXT_ALIGNMENT, TEXT_ALIGN_CENTER)调对齐或把控件高度加大几像素中文显示成方块 → 内置默认字体不含 CJK 字形GuiSetFont(LoadFontEx(cjk.ttf, 22, 0, 256));换一张带中文的字库全局生效每帧TextFormat导致堆分配频繁 → 把结果缓存进静态char数组只在数值真正变化时重算面板帧率立刻稳下来。收尾变量为准然后去改一套主题raygui 的设计哲学一句话控件不保存状态每帧声明、变量为准——布局、主题、开合状态全部写在你自己的代码里删了重写没有任何心理负担。接下来值得花一个下午的事把GuiSetStyle的三个参数翻一遍给滑块、复选框、下拉框各换一组颜色与字号或者照着饼图示例的滚动列表给自己的游戏做一个参数编辑器。【免费下载链接】raylibA simple and easy-to-use library to enjoy videogames programming项目地址: https://gitcode.com/GitHub_Trending/ra/raylib创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表