☰
raygui 实战:三个任务搭出 C 语言游戏参数调试面板
2026/10/4 2:09:41 网站建设 项目流程

raygui 实战:三个任务搭出 C 语言游戏参数调试面板

【免费下载链接】raylibA simple and easy-to-use library to enjoy videogames programming项目地址: https://gitcode.com/GitHub_Trending/ra/raylib

一个 2D 小游戏跑起来了,但想调调形状的半径、填充开关,就得改代码、编译、再运行。这篇文章从这个场景出发:用 raylib 跨平台游戏库和它自带的 raygui 模块,给游戏加上一个运行中就能用鼠标调参的调试面板。raylib 是 C 语言游戏库,raygui 是它附带的即时模式 GUI 模块——控件每帧重画,每个控件的值保存在你自己的普通变量里,没有控件状态树,也没有事件回调要维护。

1. 🧩 三步接入 raygui:单头文件加一个宏

raygui 是单头文件库,仓库的官方示例里每个模块都自带一份拷贝,比如 shapes 示例的 raygui.h。接入分三步:

第一步,把raygui.h拷到你的工程目录;第二步,在某一个.c 文件里先定义RAYGUI_IMPLEMENTATION宏再 include,这样 raygui 的全部实现代码就生成了到这个编译单元,和其他 .c 文件共享;第三步,不需要任何链接配置——它是纯 C 头文件库,不产生额外的 .a 或 .lib。

#include "raylib.h" // 只在主程序这一个文件里定义该宏, // raygui 的实现代码就会编译进当前编译单元,无需额外链接 #define RAYGUI_IMPLEMENTATION #include "raygui.h" int main(void) { InitWindow(800, 450, "参数调试面板"); SetTargetFPS(60); while (!WindowShouldClose()) { BeginDrawing(); ClearBackground(BLACK); // 控件和图形都画在这里 EndDrawing(); } CloseWindow(); return 0; }

到这里窗口已经能跑,后面两个任务都只往BeginDrawing()里加代码。官方示例 examples/shapes/shapes_rounded_rectangle_drawing.c 就是这个写法,可以对照着看。

2. 滑块、复选框、下拉框与画布参数实时联动

先明确即时模式和保留模式的差别:raygui 的每个GuiXxx()调用都是"重画这个控件并检查本帧输入",它把你传进去的指针指向的变量直接当作控件状态。滑块拖动时 raygui 帮你把变量改掉,你下一帧读到的就是新值——这就是联动的全部机制,不需要任何注册、绑定或刷新通知。

声明三个普通变量,然后每帧调用控件函数:

float radius = 80.0f; bool filled = true; int shapeMode = 0; // 0: 圆形 1: 方形 2: 圆环 GuiSliderBar((Rectangle){20, 20, 200, 20}, "半径", TextFormat("%.0f", radius), &radius, 10, 150); GuiCheckBox((Rectangle){20, 60, 20, 20}, "填充", &filled); GuiDropdownBox((Rectangle){20, 100, 140, 30}, "圆形;方形;圆环", &shapeMode, false); // GuiButton 返回值非零表示"本帧被按下",适合触发一次性动作 if (GuiButton((Rectangle){20, 150, 120, 30}, "重置参数")) { radius = 80.0f; filled = true; shapeMode = 0; }

图形侧只是在绘制区读这些变量,每帧都会拿到最新值:

int cx = GetScreenWidth() / 2, cy = GetScreenHeight() / 2; Color color = filled ? RED : LIGHTGRAY; if (shapeMode == 0) { DrawCircle(cx, cy, radius, color); } else if (shapeMode == 1) { DrawRectangleRec((Rectangle){cx - (int)radius, cy - (int)radius, radius * 2, radius * 2}, color); } else { DrawRing(cx, cy, radius * 0.5f, radius, 32, 16, color); }

官方示例 shapes_pie_chart.c 用同样的方式做了个更复杂的面板:切分数、内环半径、每片颜色,全部滑块驱动。

3. 🔧 两个最高频的坑:布局错位与中文乱码

用相对坐标解决分辨率变化后控件被裁掉

800x450 下写死的x = 640,窗口放大后控件会贴到左边空着,缩小时直接被裁掉。做法是所有坐标从GetScreenWidth()/GetScreenHeight()推导,面板整体先定位,内部控件相对面板原点偏移:

int panelW = 220; // 面板固定在屏幕右侧,随窗口宽度移动 Rectangle panel = { (float)(GetScreenWidth() - panelW - 20), 20.0f, (float)panelW, 360.0f }; GuiGroupBox(panel, "控制面板"); // 控件坐标基于 panel 原点累加,而不是窗口绝对值 GuiSliderBar((Rectangle){panel.x + 20, panel.y + 40, panel.width - 40, 20}, "半径", TextFormat("%.0f", radius), &radius, 10, 150); GuiCheckBox((Rectangle){panel.x + 20, panel.y + 80, 20, 20}, "填充", &filled);

再往上堆控件时一律panel.y + 偏移量,窗口怎么缩放面板都贴右缘。

raygui 中文乱码的两种解法

raylib 默认字体只包含基本 ASCII 码点,raygui 全局字体默认就是它,所以中文控件文本会显示成方块。两种处理方式:

解法一,加载一份覆盖 CJK 码点的字体,然后切给 raygui,全局生效:

// 第三个参数为起始字符传 0 表示加载全部字形 Font cnFont = LoadFontEx("NotoSansSC.ttf", 24, 0, 0); GuiSetFont(cnFont); // 全局字体,从下一帧起所有控件生效

解法二,部署包有体积限制时不带上完整 CJK 字体:把界面实际用到的几十个汉字单独导出成子集字体(只有几 KB),按需加载;或者控件文本保持英文,仅在需要中文的画布绘制处单独SetFont加载。子集字体和回退英文二选一,取决于你的发布约束。

接下来可以做什么

  • 自定义控件主题:raygui 用一张全局样式数组管理所有控件的圆角、配色,GuiSetStyle()改一个属性值即可整体换风格
  • 扩展成多面板或标签页结构,用GuiTabBar()收纳"图形/声音/性能"几组参数
  • 多语言支持:控件文本抽到资源表,切换语言时同时换文本和字体
  • 把同一套接法搬去画 FPS、帧耗时,做一个迷你 profiler 面板

【免费下载链接】raylibA simple and easy-to-use library to enjoy videogames programming项目地址: https://gitcode.com/GitHub_Trending/ra/raylib

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询