ARTICLE DETAIL

资讯详情

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

EGE图形库入门:环境配置、坐标体系与绘图函数实操

EGE图形库入门:环境配置、坐标体系与绘图函数实操 1. 为什么要用EGE学图形编程而不是直接上OpenGL先聊点实在的。EGE全称Easy Graphics Engine是国内开发者维护的一个轻量级C/C图形库核心用途是在Windows下用极低的门槛画出点、线、面、图片和文字写出属于自己的小游戏或可视化工具。我在带新人和做小项目时经常推荐EGE原因很简单你想从控制台黑框跨进图形界面如果一上来就啃OpenGL、DirectX或SDL光环境配置、窗口创建、消息循环这些前置知识就能劝退一大半人。EGE只要一个graphics.h头文件加几个库文件几分钟就能把第一个窗口跑出来。这一篇是整个EGE系列的基础篇不聊复杂算法不碰高级渲染只解决几个必须吃透的问题EGE到底能做什么、环境怎么配、绘图窗口的坐标系和颜色体系长什么样、常用绘图函数怎么用。你会发现这些知识点一旦打通后续学动画、鼠标交互、图片处理和游戏逻辑就只是在“地基”上添砖加瓦而已。适合谁看你已经会C语言的基本语法变量、函数、循环、数组但从来没有写过图形程序或者你正在准备课程设计、参加竞赛需要一个上手快、能出成果的图形库又或者你只是想给枯燥的控制台程序加点视觉效果。这篇文章都能帮你迈过第一道坎。我不会给你堆官方文档式的函数列表而是用一套从零到能画出小作品的实操思路把最常用的内容讲透顺带把我自己踩过的坑也一并填上。2. 环境准备EGE下载、安装与编译器配置附坑点2.1 下载EGE并了解文件结构EGE的官方下载渠道是GitHub上的开源仓库或者国内一些镜像站。下载完成后解压得到的文件夹里通常包含include、lib、doc、example等目录。include里是头文件lib里是不同编译环境对应的库文件doc是文档example是官方示例。这里你需要先明确一个概念EGE不是绿色软件它没有一个安装.exe让你点两下就完事它本质上是给编译器用的“外部库”。所以下载解压只是第一步真正关键的是让编译器能找到头文件和库文件。很多人卡在这一步就是因为只解压了没有配置编译器。我习惯的做法是把EGE整个文件夹放到一个稳定路径比如D:\lib\EGE或者丢到编译器自身的目录下面方便统一管理。2.2 常见编译器的配置方法不同编译器写法不一样但底层思路完全一致告诉编译器graphics.h在哪里、库文件在哪里。我实际用过的两种主力方案是Visual Studio和Dev-C这里都列出来。Visual Studio的配置以VS2019/2022为例打开你的C空项目在菜单栏找到“项目 - 属性”。在左侧找到“VC目录”然后“包含目录”里添加EGE的include文件夹路径例如D:\lib\EGE\include。“库目录”里添加EGE的lib文件夹路径例如D:\lib\EGE\lib\vs2022具体子目录看压缩包里给的是什么有的分vc15、vc32、vc64。在“链接器 - 输入 - 附加依赖项”里加上EGE对应的库文件名称一般叫graphics.lib或libgraphics.a对应的MSVC版本。如果不确定看官方文档或示例项目一般会写明。Dev-C的配置Dev-C用的是MinGW编译器配置稍微有点不同。在“工具 - 编译器选项 - 目录”里分别把include路径填到“包含文件”栏把lib路径填到“库文件”栏。然后在项目里通过“项目 - 参数”在“链接库”里填入EGE库名例如-lgraphics。注意是-l开头后面跟库文件名去掉扩展名的部分。提示不管用哪个编译器配好后最好新建一个空项目写一个最简单的initgraph(640, 480)程序编译一次。配置没问题的标志是编译通过、不报“cannot open include file graphics.h”或“undefined reference”这类错误。2.3 最容易翻车的三个环境坑坑一32位与64位混淆。EGE编译出来的库文件通常分32位和64位两个版本。如果你的编译器项目默认是x86却链接了x64的库编译时会出现模块不匹配的错误。解决办法是检查项目平台Dev-C默认通常是32位Visual Studio则要自己在“解决方案平台”里选x86还是x64保持项目和库版本一致即可。坑二多个编译器共用一套EGE文件。EGE的库文件会针对不同编译器细分为MSVC版、MinGW版、CBuilder版等。如果你之前用VS配好了路径换到Dev-C还是指到同一个lib目录很可能会因为库格式不匹配导致找不到符号。建议每个编译器单独下载一份对应版本的EGE路径分开互不干扰。坑三中文路径或空格。我见过有人把EGE放在C:\Users\张三\下载\EGE 1.2这种带空格和中文的路径下结果编译器找不到头文件。虽然现在很多编译器对路径支持变好了但图形库项目这种“老派”的东西路径里保持纯英文、不带空格是最稳的。3. 必须吃透的两个底层概念坐标系和RGB颜色3.1 窗口绘图坐标系左上角是原点y轴向下EGE遵循的是BGIBorland Graphics Interface体系的坐标系统和数学课上用的直角坐标系有区别。EGE窗口的左上角是坐标原点(0, 0)x轴正方向向右y轴正方向向下。也就是说y值越大位置越靠下而不是越靠上。这个细节看似无关痛痒写代码时却能坑死你。比如你想在画面下方画一条横线第一反应可能是让y等于很大的值比如480结果如果窗口高度只有400这条线就画到窗口外面去了。正确做法是先想清楚窗口尺寸再推算坐标。以initgraph(640, 480)为例左上角是(0,0)右下角是(639, 479)水平中心坐标是319或320垂直中心坐标是239或240。EGE的坐标边界是[0, width-1]也是很多人忽略的细节画满屏矩形时如果右下角写成(640, 480)实际边缘就少画了一列和一行像素。再提醒一点EGE没有“负坐标”的概念所有坐标值必须是整数。坐标超出窗口范围时EGE不会报错但图形会被裁掉。初学阶段画图形经常“消失”九成不是代码逻辑有问题而是坐标跑出窗口了。3.2 颜色体系从RGB到EGE的颜色宏EGE的颜色本质是一个无符号整型内部按RGB方式存储即红、绿、蓝三个分量每个分量取值范围0到255。混合三种分量可以得到任意颜色。下面这几个基础色我建议你直接背下来颜色RGB值黑RGB(0, 0, 0)白RGB(255, 255, 255)红RGB(255, 0, 0)绿RGB(0, 255, 0)蓝RGB(0, 0, 255)黄RGB(255, 255, 0)青RGB(0, 255, 255)紫RGB(255, 0, 255)如果三个分量值全相同得到的就是灰色系列数值越大越偏白数值越小越偏黑比如RGB(128, 128, 128)是中灰色。EGE为了兼容老BGI的写法也预定义了一些颜色常量比如RED、GREEN、BLUE、YELLOW、WHITE、BLACK在graphics.h里可以直接使用。我个人建议初学阶段直接用RGB()宏因为直观且不受限于预定义颜色比如RGB(100, 200, 150)这种薄荷绿预定义常量里可没有。还有一点容易混淆EGE里有“当前绘制颜色”和“当前填充颜色”两个独立概念。绘制颜色用setcolor()设置负责线条、边框、文字等填充颜色用setfillcolor()设置负责封闭图形内部的上色。很多新手只设置了填充色没设置线条色或者反过来导致图形出现“填充想要的颜色、边框却是默认白色”的情况。4. 初识绘图API从画一条线到一个完整窗口程序4.1 核心函数清单与作用绘图库的函数多到能写一本书但基础篇只需要先吃透十个左右。我把它们分成四组方便记忆第一组是窗口生命周期函数包括initgraph()创建窗口和closegraph()关闭窗口。这两个函数必须成对出现窗口程序结束前一定要调用closegraph()释放资源否则极端情况下会出现句柄泄漏。第二组是绘图状态设置函数包括setbkcolor()设置背景色、setcolor()设置绘制颜色、setfillcolor()设置填充颜色、cleardevice()用背景色清空整个窗口。第三组是基本图形函数包括line()画直线、circle()画空心圆、rectangle()画空心矩形、fillcircle()画实心圆、fillrectangle()画实心矩形、bar()画填充矩形但不画边框。第四组是文字和交互函数基础篇先说outtextxy()输出文本和getch()等待按键输入。注意getch()不是EGE的函数而是conio.h里的EGE环境通常会兼容它用来让窗口挂起等待按键。4.2 第一个完整窗口程序逐行拆解先看代码再逐行解释#include graphics.h #include conio.h int main() { initgraph(640, 480); setbkcolor(WHITE); cleardevice(); setcolor(RED); line(50, 100, 400, 100); setfillcolor(BLUE); fillcircle(200, 250, 60); getch(); closegraph(); return 0; }#include graphics.h引入EGE图形函数声明这是所有EGE项目必须的第一行。initgraph(640, 480)创建一个宽640像素、高480像素的绘图窗口。EGE源码里第三个参数是显示模式默认0就行不需要改。setbkcolor(WHITE)和cleardevice()必须连用。很多人以为设置背景色后窗口自动变白其实setbkcolor()只是修改“背景色变量”真正让窗口变成这个颜色得靠cleardevice()用背景色刷一遍屏。如果只调用setbkcolor()不调用cleardevice()窗口背景还是默认黑色。setcolor(RED)设成红色再调用line(50, 100, 400, 100)就是以红色画一条从(50, 100)到(400, 100)的水平线。注意line函数用的是当前绘制颜色。setfillcolor(BLUE)设成蓝色fillcircle(200, 250, 60)则是以(200,250)为圆心、半径60画一个实心蓝色圆。圆形的边界线条颜色使用当前绘制色如果没改当前绘制色边界会是红色或默认颜色。getch()让程序停在这里等待键盘按键否则窗口会在瞬间创建又关闭你根本看不见任何图形。closegraph()关闭EGE窗口释放资源。这个例子涵盖了一组完整的流程建窗口、设置背景、画线、画填充圆、等待、销毁。把它跑通你就算真正进入EGE的世界了。4.3 填充图形与空心图形的区别在EGE里空心图形和实心图形是两套函数。以圆为例circle()画空心圆fillcircle()画实心圆矩形则更复杂一点rectangle()画空心矩形fillrectangle()画填充矩形同时带边框bar()画填充矩形但“不画边框”。bar()和fillrectangle()的区别容易被忽略。你画一排bar()它们之间不会有边框分隔视觉上是连续色块但如果用fillrectangle()每个矩形会有边框矩形之间会出现线条。做柱状图时用bar()会更干净做棋盘格时用fillrectangle()反而能自带边框效果。如果是空心图形只要设置好绘制色即可如果是实心图形至少要把填充色设置对否则默认填充色是白色。白色填充在白色背景上会把整个图形“隐形”这又是一个经典的新手陷阱。5. 综合实操用EGE画出第一幅小作品5.1 素材构思与坐标规划前面讲了理论这一步咱们动手画一个完整作品。我选一个经典又可爱的笑脸黄色大圆脸、两个黑色眼睛、一只红色半圆弧嘴巴。别小看它这里面同时涉及坐标规划、空心圆、实心圆、圆弧、颜色设置等多个知识点。窗口大小我定为640x480。脸的中心放在(320, 240)这个位置刚好是窗口中心偏右上一格像素的位置严格来说(320, 240)是水平向右第320个像素、垂直向下第240个像素视觉上就是中心。脸半径设为120。眼睛中心是(270, 210)和(370, 210)半径12。为什么眼睛的y坐标比脸的圆心小30因为在窗口坐标系里y值越小越靠上眼睛要长在脸上半部分所以y坐标必须小于240。嘴巴用arc()画圆弧以(320, 250)为圆心半径45从180度画到360度。EGE的角度单位是度而不是弧度0度默认朝正右方向逆时针增加所以180到360正好是下半圈。5.2 完整代码与实现过程#include graphics.h #include conio.h int main() { initgraph(640, 480); setbkcolor(RGB(135, 206, 250)); // 天空蓝背景 cleardevice(); // 画脸黄色实心圆 setcolor(BLACK); setfillcolor(YELLOW); fillcircle(320, 240, 120); // 画眼睛黑色实心小圆 setcolor(BLACK); setfillcolor(BLACK); fillcircle(270, 210, 12); fillcircle(370, 210, 12); // 画嘴巴红色上半段圆弧 setcolor(RED); arc(320, 250, 180, 360, 45); getch(); closegraph(); return 0; }跑一下这段代码你会看到一个浅蓝色背景上有个标准笑脸。整个过程先后做了这些事设置画线颜色和填充颜色。画脸的fillcircle()需要黄色填充所以先setfillcolor(YELLOW)脸的边框也讲究一点设成BLACK让黄脸有清晰轮廓。注意眼睛的绘制顺序。在同一个程序里我先画了黄脸再画黑眼睛黑色实心圆直接覆盖在黄色大圆上这是图形库的“后画覆盖先画”规则不需要额外处理背景色填充。这个“覆盖顺序”思维要建立起来后续绘制游戏场景时先画远处背景、再画近处物体本质上就是靠调用顺序。arc()的参数是圆心坐标、起始角度、终止角度、半径。我前面强调过EGE用角度制这里的180和360直接就是度数。如果写的是弧度制的π那画出来的形状完全不是想要的效果。5.3 实操心得为什么建议你亲手调一遍参数看完代码和解释后我强烈建议你亲手把几个关键数字改一改再编译运行。比如把脸半径从120改成100观察眼睛是否超出了脸的范围把嘴巴圆弧的起始角度从180改成120看半圆弧变成什么样把眼睛y坐标从210改成280看表情从“正常笑脸”变成“惊悚脸”。这种“改一个数字、看一个效果”的练习方式比我干讲一百个函数还有用。因为你只有亲手感受到数字和图形之间的映射关系才真正建立了“图形坐标感”。这也是我练EGE时觉得最扎实的方法没有之一。6. 新手最容易踩的5个坑实测整理6.1 窗口一闪而过根本看不到图形原因很简单程序从上往下执行initgraph()打开窗口画完图形后立刻执行closegraph()把窗口关掉了整个过程可能不到0.01秒。解决办法是在closegraph()前加一个getch()程序会挂起等待键盘输入你按下任意键窗口才关闭。也可以在循环里轮询判断按键这是后续进阶的写法基础篇用getch()完全够。6.2 设置了背景色窗口还是黑的很多人写setbkcolor(WHITE)后发现窗口背景依然是黑色原因前面提过setbkcolor()只是告诉EGE“背景色我应该设为白色”真正执行刷屏操作的是cleardevice()。两者必须配合使用缺一不可。这个逻辑说白了就是“配置颜色”和“应用颜色”两件事EGE把这两步拆开了。6.3 画出来的图形“消失”了先检查坐标值是否在窗口范围内。窗口是640x480时x必须落在0到639y必须落在0到479。新手最容易犯的错是把y坐标写成“高度减去某个值”比如想让图形离底部50像素y写成480-50430但实际上正确写法是initgraph高度是480那么y 480 - 50 - 1才能保证图形边缘不贴到底部之外。还有一种可能是填充色和背景色一样比如背景是白色、填充色也是白色图形被“隐身”了。解决办法是换一种填充色或改背景色。6.4 中文字符显示乱码或方块EGE的outtextxy()直接输出中文字符串时如果当前字体不兼容中文会出现乱码方块。解决办法是用setfont()设置一个中文字体比如setfont(20, 0, 宋体); outtextxy(100, 100, 你好EGE);注意setfont()三个参数的含义是高度、宽度自适应值、字体名称。宽度填0表示根据高度自动计算。这个函数在入门阶段可以不细究但迟早会用到。6.5 图形有严重的闪烁感如果你写动画循环比如让圆连续移动会发现画面闪得厉害。原因是每次画新帧之前要清除旧画面而清除和重绘之间存在间隔人眼就产生了闪烁。EGE支持双缓冲机制但怎么正确配置涉及渲染模式和批处理函数属于进阶内容。我在后续篇章里会详细展开基础篇你只需要知道“有这个问题存在且能用双缓冲解决”即可。6.6 常见问题速查表表现可能原因解决办法窗口一闪而过没有挂起等待在closegraph()前加getch()背景色没变缺少cleardevice()设完setbkcolor()立即调用cleardevice()图形画不出来坐标越界或颜色与背景相同检查坐标值修改填充色中文乱码字体设置不对用setfont()指定中文字体画面闪烁没有使用双缓冲后续进阶篇章学习缓冲机制链接报错库版本和编译器不匹配确认32位/64位、MSVC还是MinGW这些坑我全踩过一遍尤其闪烁问题当年被折磨得够呛。如果这篇文章对你有帮助建议把示例代码亲手敲一遍把每个函数的参数都改着玩一玩。图形编程和学车一样光看别人开永远学不会只有自己握方向盘撞几次路沿才能真正记住路该怎么走。后续我会继续更新EGE的进阶内容包括鼠标交互、动画、图片处理和碰撞检测基础打牢了这些东西学起来会非常快。
返回列表