raylib绘图库--瞿华 2022.7.1 知乎 1、raylib绘图库简介 知乎 2、raylib 2d动画/游戏教程(1)动画基本原理 知乎 3、raylib 2d动画/游戏教程(2)坐标系与颜色系统 知乎 4、raylib 2d动画/游戏教程(3)图像文件与图层 知乎 5、raylib 2d动画/游戏教程(4)raylib-drawing库 知乎 6、raylib 2d动画/游戏教程(5)键盘与鼠标输入 知乎 7、raylib 2d动画/游戏教程(6)游戏手柄输入 知乎 8、raylib 2d动画/游戏教程(7)音乐和音效 知乎 9、raylib绘制中文内容 知乎 10、使用raygui绘制控件 知乎 11、raylib 3d绘图基础教程(1)坐标系和摄像机 知乎 12、raylib 3d绘图基础教程(2)网格(Mesh) 知乎 13、raylib 3d绘图基础教程(3)几何变换 知乎 14、raylib 3d绘图基础教程(4)3d模型的载入与绘制 使用raygui绘制控件 1 raygui简介 raygui是基于raylib开发的实时UI库,可以配合raylib使用,为动画/游戏提供交互界面。它提供了按钮、下拉框、输入框等多种组件。从1.1.2版本开始,小熊猫C++在发行版自带的编译器中集成了raygui。 注意: 对于小熊猫C++1.1.4版本以前自带的raygui,请使用#include 由于raylib字体占用显存的问题,raygui的文本框不太适合用于接收中文输入内容。 raygui.h是一个只有头文件的库,通过RAYGUI_IMPLEMENTATION宏来控制raygui.h是否同时包含函数的实现。如果一个项目中有多个文件包含raygui.h,则必须保证有且仅有一个文件在包含raygui.h前定义了RAYGUI_IMPLEMENTATION宏。否则,要么会在链接时出现函数重复实现的错误(多个文件定义了RAYGUI_IMPLEMENTATION宏);要么会在链接时出现找不到相关函数实现的错误(没有文件定义RAYGUI_IMPLEMENTATION)。 raygui控件的实际绘制在EndDrawing()时完成,因此BeginDrawing()/EndDrawing()内的绘制的内容会显示在控件后面。 2 按钮示例 下面的例子演示了raygui按钮的使用方法,以及如何让raygui的控件显示中文提示。 注意,因为控件上的文字内容很少且基本不变,所以我们直接在绘制循环外载入字体,以方便处理。#include #include //raygui的函数实现也都在raygui.h文件中,如果一个项目中有多个文件 //包含raygui.h,那么只能有一个文件定义RAYGUI_IMPLEMENTATION,否则 //会导致链接时出错。 #define RAYGUI_IMPLEMENTATION #include int main() { InitWindow(800,600,"RAYGUI示例"); SetTraceLogLevel(LOG_WARNING); SetTargetFPS(30); //读取字体文件 char sWordNeed[]="太阳月亮您选择了:!"; //将字符串中的字符逐一转换成Unicode码点,得到码点表 int nCode; int *pCodeNeed=LoadCodepoints(sWordNeed,&nCode); //读取仅含码点表中各字符的字体 Font fontNeed = LoadFontEx("simhei.ttf",64,pCodeNeed,nCode); //释放码点表 UnloadCodepoints(pCodeNeed); //设置GUI控件的字体和大小 GuiSetFont(fontNeed); GuiSetStyle(DEFAULT,TEXT_SIZE,20); int btnClick = 0; while(!WindowShouldClose()) { if (btnClick==0) { if (GuiButton((Rectangle){ 120, 150, 150, 30 },"太阳"))btnClick = 1; if (GuiButton((Rectangle){ 120, 250,150,30},"月亮"))btnClick = 2; } BeginDrawing(); ClearBackground(WHITE); if (btnClick==0){EndDrawing();continue;} switch(btnClick) { case 1: DrawTextEx(fontNeed,"您选择了太阳!",Vector2{200,200},64,1,RED); break; case 2: DrawTextEx(fontNeed,"您选择了月亮!",Vector2{200,200},64,1,RED); break; } EndDrawing(); } //释放字体 UnloadFont(fontNeed); CloseWindow(); } ![]()
3 外旋螺线示例 下面这个例子演示了raygui的按钮、调节钮、颜色选择等控件的使用。注意本例中使用了rdrawing.h用于绘制2d图形。
#include #include #include //raygui的函数实现也都在raygui.h文件中,如果一个项目中有多个文件 //包含raygui.h,那么只能有一个文件定义RAYGUI_IMPLEMENTATION,否则 //会导致链接时出错。 #define RAYGUI_IMPLEMENTATION #include #define SCREEN_W 1000 #define SCREEN_H 700 void updateRadius(int baseL, int outerL, int pointL, int *pBaseR, int *pOuterR, int *pPointR) {//计算外旋轮、基圆和动点的实际半径,以保证不超出图像范围 int totalL=baseL+outerL; if (pointL>outerL)totalL+=pointL; else totalL+=outerL; int totalR = SCREEN_H/2; int remainder = totalR % totalL; if (remainder!=0) { if (remainder < totalL / 2)totalR -= remainder; else totalR += ( totalL - remainder); } *pBaseR = (totalR) / totalL * baseL; *pOuterR = (totalR) / totalL * outerL; *pPointR = (totalR) / totalL * pointL; } int main() { int baseL=1;//内圆半径 int outerL=3;//外圆半径 int pointL=2;//动点半径 int baseR,outerR,pointR; int cx=SCREEN_H/2,cy=SCREEN_H/2; int speed = 1; Color trackColor = BLUE; //计算外旋轮、基圆和动点的实际半径,以保证不超出图像范围 updateRadius(baseL, outerL, pointL, &baseR, &outerR, & pointR); InitWindow(SCREEN_W,SCREEN_H,"外旋螺线"); SetTraceLogLevel(LOG_WARNING); SetTargetFPS(60); //读取字体文件 char sWordNeed[]="外旋轮基圆动点半径速度颜色清除: 0123456789x"; //将字符串中的字符逐一转换成Unicode码点,得到码点表 int nCode; int *pCodeNeed=LoadCodepoints(sWordNeed,&nCode); //读取仅含码点表中各字符的字体 Font fontNeed = LoadFontEx("simhei.ttf",20,pCodeNeed,nCode); //释放码点表 UnloadCodepoints(pCodeNeed); //设置GUI控件的字体和大小 GuiSetFont(fontNeed); GuiSetStyle(DEFAULT,TEXT_SIZE,20); Image trackImage=GenImageColor(SCREEN_W-100,SCREEN_W-100,WHITE); //border ImageFillRectangleEx(&trackImage,0,0,SCREEN_W-100,SCREEN_W-100,LIGHTGRAY); ImageFillRectangleEx(&trackImage,5,5,SCREEN_W-110,SCREEN_W-110,WHITE); Image circlesImage = GenImageColor(SCREEN_W-100,SCREEN_W-100,BLANK); float r=0; int lastx,lasty; lasty=cy; lastx=cx+(baseR+outerR-pointR); int frameCount = 0; #define BAR_W 50 #define BAR_H 30 while(!WindowShouldClose()) { int newOuterL = GuiSliderBar((Rectangle){ 120, 20,BAR_W,BAR_H },"外旋轮半径",TextFormat("%i", (int)outerL), outerL, 1, 50); int newBaseL = GuiSliderBar((Rectangle){ 120, 60,BAR_W,BAR_H },"基圆半径",TextFormat("%i", (int)baseL), baseL, 1, 50); int newPointL = GuiSliderBar((Rectangle){ 120, 100,BAR_W,BAR_H },"动点半径",TextFormat("%i", (int)pointL), pointL, 1, 50); speed = GuiSliderBar((Rectangle){ 120, 150,BAR_W,BAR_H },"速度",TextFormat("%i", (int)speed), speed, 1, 50); GuiLabel((Rectangle){ 20, 220,BAR_W,BAR_H },TextFormat("颜色: 0x%X%X%X ",(int)(trackColor.r), (int)(trackColor.g),(int)(trackColor.b))); trackColor= GuiColorPicker((Rectangle){ 50, 250, BAR_W*2,BAR_H*2 }, NULL, trackColor); int doClear = GuiButton((Rectangle){ 120, SCREEN_H-100, BAR_W,BAR_H },"清除"); if (newOuterL!=outerL || newBaseL!=baseL || newPointL!=pointL) { if (newOuterL!=outerL)pointL=newOuterL; else pointL=newPointL; outerL=newOuterL; baseL=newBaseL; //重新计算外旋轮、基圆和动点的实际半径,以保证不超出图像范围 updateRadius(baseL, outerL, pointL, &baseR, &outerR, & pointR); lasty=cy; lastx=cx+(baseR+outerR-pointR); r=0; ImageClearBackground(&trackImage,WHITE); ImageFillRectangleEx(&trackImage,0,0,SCREEN_W-100,SCREEN_W-100,LIGHTGRAY); ImageFillRectangleEx(&trackImage,5,5,SCREEN_W-110,SCREEN_W-110,WHITE); } else if (doClear) { ImageClearBackground(&trackImage,WHITE); ImageFillRectangleEx(&trackImage,0,0,SCREEN_W-100,SCREEN_W-100,LIGHTGRAY); ImageFillRectangleEx(&trackImage,5,5,SCREEN_W-110,SCREEN_W-110,WHITE); } //更新外旋轮和动点的位置 r+=0.01; float outerCX=cx+ (baseR+outerR)*cos(r); float outerCY=cy+ (baseR+outerR)*sin(r); float theta = r * (baseL+outerL) / outerL; int x=round(outerCX - pointR * cos(theta)); int y=round(outerCY - pointR * sin(theta)); //update image (in CPU) //ImageClearBackground(&trackImage,WHITE); ImageDrawLineEx(&trackImage,lastx,lasty,x,y,3,trackColor); frameCount++; if (frameCount>=speed) { ImageClearBackground(&circlesImage,BLANK); //base circle ImageDrawCircleEx(&circlesImage,cx,cy,baseR,1,LIGHTRED); ImageDrawCircleEx(&circlesImage,outerCX,outerCY,outerR,1,LIGHTSLATEGRAY); ImageDrawLineEx(&circlesImage,cx,cy,outerCX,outerCY,1,LIGHTRED); ImageDrawLineEx(&circlesImage,x,y,outerCX,outerCY,1,LIGHTSLATEGRAY); ImageDrawPointEx(&circlesImage,x,y,7,RED); //Drawing in GPU Texture trackTexture = LoadTextureFromImage(trackImage); Texture circlesTexture = LoadTextureFromImage(circlesImage); BeginDrawing(); ClearBackground(WHITE); DrawTexture(trackTexture,200,0,WHITE); DrawTexture(circlesTexture,200,0,WHITE); EndDrawing(); UnloadTexture(circlesTexture); UnloadTexture(trackTexture); frameCount=0; } lastx=x; lasty=y; } //Clean up UnloadImage(circlesImage); UnloadImage(trackImage); //释放字体 UnloadFont(fontNeed); CloseWindow(); }