)
raygui 教程5 分钟给 C 游戏装上可拖拽的设置面板完整指南【免费下载链接】raylibA simple and easy-to-use library to enjoy videogames programming项目地址: https://gitcode.com/GitHub_Trending/ra/raylibraylib 是轻量跨平台的游戏库raygui 是它配套的单文件界面层能把滑块、复选框、下拉框直接画进游戏循环。这篇 raygui 教程面向会 C 语言、没写过 GUI 的你目标是一个能拖、能点、窗口缩放也不错位的设置面板全程只加一个头文件。 场景切入给 C 游戏加一个能拖能点的设置面板想让玩家在游戏里调音量、换难度、开关音乐最省事的路线是 raygui因为它把控件的矩形命中、悬停高亮、按下滑块这些活全包了。传统做法得自己画矩形、手动做鼠标碰撞、再画文字三个控件就要重复三遍悬停、按下这些状态全靠手写。raygui 把这些收进单个头文件你每帧把变量指针递进去它负责渲染并把用户操作后的新值写回。原理速览C 语言即时模式 GUI 在每帧做什么即时模式的控件是渲染函数不是对象——可以理解为每帧重填一张表单。你的主循环每跑一圈就按顺序调用一遍控件函数它在指定Rectangle位置画自己读取这一帧的鼠标状态用户动了它就通过指针写回新值。控件本身不存任何记忆上一帧画在哪程序根本不关心。所以你的普通变量float、int、bool才是唯一真相你改变量下一帧控件跟着动用户拖控件变量被改。这也回答了一个常见疑问——为什么没有创建、销毁控件的代码没有实例自然没有要释放的东西。60 FPS 下每帧重建一遍听着浪费但声明即渲染没有对象分配开销。跑通第一个 raygui 例子先看能直接编译的最小完整示例跑通之后逐段拆。#include raylib.h #define RAYGUI_IMPLEMENTATION // 全项目只在这一个 .c 里定义实现编进来 #include raygui.h int main(void) { InitWindow(720, 420, raygui 最小设置面板); float masterVol 0.6f; // 变量是唯一真相控件每帧读它、写它 bool showGrid true; int toggleCount 0; // 用返回值数被点中的帧 while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(RAYGRAY); // 文本参数先格式化再传左右标签各占一边 GuiSliderBar((Rectangle){ 50, 80, 260, 24 }, 主音量, TextFormat(%d%%, (int)(masterVol * 100)), masterVol, 0.0f, 1.0f); if (GuiCheckBox((Rectangle){ 50, 130, 22, 22 }, 显示网格, showGrid)) toggleCount; // 返回非 0 的帧 勾选/取消的瞬间 DrawText(TextFormat(切换次数%d, toggleCount), 50, 180, 20, RAYWHITE); EndDrawing(); } CloseWindow(); return 0; }编译跑起来后你会看到拖滑块时右侧百分比实时跳动点复选框计数加一全程没有任何创建控件的调用。拆四点都是坑位RAYGUI_IMPLEMENTATION为什么只写一次它在当前翻译单元展开全部实现多处定义会符号冲突其余.c直接#include raygui.h就行。每个控件第一个参数是自己的Rectangle位置和尺寸全由你定raygui 不管布局。递进去的是指针用户没动值不变动了那一帧被写回。返回值非 0 只在发生动作的那一帧出现拿它做一次性触发最稳别当持续状态用。 raygui 控件怎么选五种控件速查选控件只看一件事你要采集的输入是什么形状。连续浮点量给滑块布尔量给复选框或状态按钮离散整数给 spinner多选一的菜单项给下拉框。控件适用场景关键参数返回值含义GuiSliderBar连续浮点音量、半径、比例float *value 最小/最大值非 0 的帧 本帧被拖动或改值GuiCheckBox布尔开关显示/隐藏某样东西bool *checked非 0 的帧 勾选或取消的瞬间GuiToggle面板角落的开关带按压手感bool *active非 0 的帧 点击切换的瞬间GuiSpinner带步进的整数数量、层数int *value 上下限 editMode非 0 表示值被改过GuiDropdownBox多选一的离散项难度、画质int *active下标从 0 起editMode非 0 表示本帧有交互返回值都是int形态的GuiResultRESULT_NONE0表示这帧无事发生判断时只关心非 0就够了。下拉框第 4 个参数editMode是传值不传址传false走常规行为按住展开、松手收起想让列表常开做成菜单式就传true。选中项通过int *active回写。看个最小用法int quality 1; // 选中下标从 0 开始 // 选项用分号拼成一个字符串raygui 内部按 ; 切开 if (GuiDropdownBox((Rectangle){ 60, 210, 180, 30 }, 低;中;高, quality, false)) printf(画质切到%d\n, quality); // 只在这一帧打日志跑起来后你会看到按住不放列表才展开点中某项的那一帧才返回非 0。spinner 一行搞定整数步进GuiSpinner((Rectangle){ 300, 80, 150, 30 }, Slices, slices, 1, 12, false);末尾的 bool 为true时允许直接键入数值false时只能用两侧按钮加减。 动手搭建raygui 设置面板与窗口缩放跟随目标是做一个贴右缘的设置面板难度滑块、音乐复选框、全屏状态按钮、画质下拉框且窗口随便拉都不错位。先定布局策略别写死坐标每帧从当前窗口尺寸反推锚点。为什么不写死因为GetScreenWidth()返回的就是逻辑分辨率高分屏缩放已经算在内窗口一变它就变锚点自动跟着走。// 锚点每帧重算窗口一缩放panelX/panelY 下一帧就对齐新边界 int sw GetScreenWidth(), sh GetScreenHeight(); float panelX (float)(sw - 240 - 20); // 240 是面板宽20 是右边距 float panelY (float)(sh - 250 - 20); // 贴底缘避开主画面注意这些值已经是 DPI 缩放后的逻辑坐标别再乘缩放系数否则高分屏上整体漂移。控件全部挂在锚点的相对坐标上业务绘制主画面照旧// 控件只相对锚点排布窗口拉多宽它们都留在右缘 20px 内 GuiSliderBar((Rectangle){ panelX 20, panelY 40, 200, 22 }, 难度, TextFormat(%d, level), level, 1.0f, 5.0f); GuiCheckBox((Rectangle){ panelX 20, panelY 80, 20, 20 }, 背景音乐, musicOn); GuiToggle((Rectangle){ panelX 20, panelY 120, 120, 30 }, 全屏, fullscreen); // 下拉框按常规行为用按住展开选中下标从 0 开始回写 if (GuiDropdownBox((Rectangle){ panelX 20, panelY 170, 200, 30 }, 低;中;高, quality, false)) settingsDirty true; // 标记设置变了业务逻辑去读新值跑起来后你会看到把窗口从 1280x720 拖成 1920x1080面板始终钉在右下角滑块和复选框不抖。如果游戏里还有可拖拽实体编辑器控制点之类每帧拿GetMousePosition()去和控件 bounds 比对即可命中道理和上面一样。仓库 examples 里就有现成范本饼图示例右侧一整个 raygui 控制台——spinner 调切片数、复选框切显示模式、滑块控内环半径。它示范了即时模式 GUI 的分界线控件问参数业务自己画。 raygui 踩坑排查四个高频问题问题 1文字画到控件框外或被裁切原因控件height给得小20 左右默认字号相对偏大文本放不下。 解决控件加高到 26~30对齐不对时用GuiSetStyle(CHECKBOX, TEXT_ALIGNMENT, TEXT_ALIGN_LEFT)调一下。问题 2中文显示成方块原因内置默认字体不含 CJK 字形缺的码位画成占位方框。 解决启动时换一张带中文的字库GuiSetFont(LoadFontEx(fonts/cjk.ttf, 24, NULL, 0));字体文件放程序能找到的路径。问题 3同帧操作两个控件只有后声明的那个有反应原因两个控件的Rectangle重叠了后声明的优先吃到输入。 解决错开各控件的 bounds 保证不重叠列表里每行一个可编辑控件时用editMode之类的参数保证同一时刻只有一个处于可编辑状态。问题 4每帧调 TextFormat内存分配抖动明显原因每帧重新拼字符串分配器高频 malloc/free。 解决把格式化结果缓存到static char[32]一类的固定缓冲里值变了才重算。 接入你的项目raygui 的 3 步接入三步按顺序做就行克隆仓库git clone https://gitcode.com/GitHub_Trending/ra/raylib。raygui.h在 examples 各模块目录下都有如examples/shapes/raygui.h、examples/core/raygui.h拷一份到你项目的src/哪个都行。挑一个.c文件在#include raygui.h之前写#define RAYGUI_IMPLEMENTATION其余源文件只写 include、不写 define避免符号重复。编译时链接 raylib 本体例如gcc demo.c -lraylib -o demo其余构建方式与 raylib 官方 Makefile / CMake 流程完全一致。结尾raygui 之后值得玩的方向raygui 的全部约定就两条每帧声明控件、变量为准。控件不保存状态所以你可以放心删了重写界面代码因此异常好删、好改这也是它比重量级 UI 框架更适合 C 游戏的原因。值得继续折腾的三件事用GuiSetStyle换主题配色、字号与内边距试出一套和自己游戏画面配的风格GuiSetFont换成有设计感的字体注意同步调高控件尺寸把examples/shapes/下用 raygui 的样本饼图、希尔伯特曲线等逐个编译运行看别人怎么把布局撑满整块屏幕。【免费下载链接】raylibA simple and easy-to-use library to enjoy videogames programming项目地址: https://gitcode.com/GitHub_Trending/ra/raylib创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考