c/c++游戏编程之Easyx图形库基础(一)
c/c++游戏编程之Easyx图形库基础(二)
我们从本节开始介绍图形化编程。Easyx图形库是开始学习Windows图形编程的极佳选择。
我们先到easyx官网(https://easyx.cn)下载easyx的安装程序。
运行安装程序:
点击安装,将easyx安装至已经检测出的开发平台即可(我用的是Visual Studio 2019,即Visual C++ 2019)。如果你用的是Dev-C++,CFree或其他平台,可能需要手动安装easyx文件并在项目设置里引用它们。学习游戏开发推荐使用较新版本的Visual C++平台(如Visual Studio 2022)。
安装教程到此结束。
Easyx文档(https://docs.easyx.cn/zh-cn/intro)
新建一个项目,在源文件里包含头文件 graphics.h,并在main函数里调用initgraph(640, 480, EW_SHOWCONSOLE),表示创建一个宽度为640像素, 高度为480像素的窗口,第三个参数表示绘图窗口的样式,值EW_SHOWCONSOLE表示显示控制台。
#include#include int main() { initgraph(640, 480, EW_SHOWCONSOLE); //初始化窗口 _getch(); closegraph(); //关闭窗口 return 0; }
运行结果:
使用setlinecolor函数设置画线颜色为:RGB(0, 0, 255),即蓝色。
使用circle函数在窗口坐标为(100, 100)处绘制一个半径为100像素的圆。
#include#include int main() { initgraph(640, 480, EW_SHOWCONSOLE); //初始化窗口 setlinecolor(RGB(0, 0, 255)); //设置画线颜色为蓝 circle(100, 100, 100); //画坐标为(100, 100)半径为100像素的圆 _getch(); closegraph(); //关闭窗口 return 0; }
运行结果:
easyx还有其他绘图函数,如:
(下列只是部分方法,想了解全部请查阅Easyx官方文档)
//画点 void putpixel( int x, //x坐标 int y, //y坐标 COLORREF color //颜色 ); //画直线 void line( int x1, //直线起点x坐标 int y1, //直线起点y坐标 int x2, //直线终点x坐标 int y2 //直线终点y坐标 ); //画无填充的矩形 void rectangle( int left, //矩形左边x坐标 int top, //矩形右边x坐标 int right, //矩形上边y坐标 int bottom //矩形下边y坐标 ); //画无填充的多边形 void polygon( const POINT *points, //多边形顶点数组地址 int num //顶点数量 );
使用上述方法绘制图形的代码:
#include#include int main() { initgraph(640, 480, EW_SHOWCONSOLE); //初始化窗口 setlinecolor(RGB(0, 0, 255)); //设置画线颜色为蓝 circle(100, 100, 100); //画坐标为(100, 100)半径为100像素的圆 //画5个红色的点 putpixel(500, 100, RGB(255, 0, 0)); putpixel(500, 102, RGB(255, 0, 0)); putpixel(500, 104, RGB(255, 0, 0)); putpixel(500, 106, RGB(255, 0, 0)); putpixel(500, 108, RGB(255, 0, 0)); line(202, 0, 402, 202); //画(202, 0) ----> (402, 202)的直线 rectangle(0, 200, 200, 400); //画矩形 POINT vertexs[6] = { { 300, 210 }, { 400, 210 }, { 450, 310 }, { 400, 410 }, { 300, 410 }, { 250, 310 } }; //顶点数组 polygon(vertexs, 6); //画有六个顶点的六边形 _getch(); closegraph(); //关闭窗口 return 0; }
运行结果:
好了,我们接下来学习绘制图片,请先在你的项目文件夹中新建一个名为images文件夹(如果你没有建项目,就直接在cpp文件所在的目录下创建即可),用来存放图片。
我在images文件夹里,放了一张图片:
为了使窗口看起来干净些,我们删除所有绘图相关的代码:
#include#include int main() { initgraph(640, 480, EW_SHOWCONSOLE); //初始化窗口 _getch(); closegraph(); //关闭窗口 return 0; }
创建一个IMAGE对象,用来表示图像并存储图像相关数据:
IMAGE img; //创建图像对象
easyx加载图像的方法loadimage:
// 从图片文件获取图像(bmp/gif/jpg/png/tif/emf/wmf/ico) void loadimage( IMAGE* pDstImg, // 保存图像的 IMAGE 对象指针 LPCTSTR pImgFile, // 图片文件名 int nWidth = 0, // 图片的拉伸宽度 int nHeight = 0, // 图片的拉伸高度 bool bResize = false // 是否调整 IMAGE 的大小以适应图片 );
加载图像(由于我的项目使用了Unicode字符集,所以类型LPCTSTR会被定义为LPCWSTR,所以字符串字面值前要加L或者无论字符集,直接使用宏_T进行转换):
loadimage(&img, L"images/zombie.png"); //加载图像
//loadimage(&img, _T("images/zombie.png")); //无论Unicode字符集还是多字节字符集,此种写法通用
easyx绘制图像的方法putimage(这个函数有两个重载,我们使用第一个即可):
// 绘制图像 void putimage( int dstX, // 绘制位置的 x 坐标 int dstY, // 绘制位置的 y 坐标 IMAGE *pSrcImg, // 要绘制的 IMAGE 对象指针 DWORD dwRop = SRCCOPY // 三元光栅操作码 ); // 绘制图像(指定宽高和起始位置) void putimage( int dstX, // 绘制位置的 x 坐标 int dstY, // 绘制位置的 y 坐标 int dstWidth, // 绘制的宽度 int dstHeight, // 绘制的高度 IMAGE *pSrcImg, // 要绘制的 IMAGE 对象指针 int srcX, // 绘制内容在 IMAGE 对象中的左上角 x 坐标 int srcY, // 绘制内容在 IMAGE 对象中的左上角 y 坐标 DWORD dwRop = SRCCOPY // 三元光栅操作码 );
绘制图像:
putimage(0, 0, &img); //在起始坐标为(0, 0)的位置绘制图像img
全部代码:
#include#include int main() { initgraph(640, 480, EW_SHOWCONSOLE); //初始化窗口 IMAGE img; //创建图像对象 loadimage(&img, L"images/zombie.png"); //加载图像 putimage(0, 0, &img); //在起始坐标为(0, 0)的位置绘制图像img _getch(); closegraph(); //关闭窗口 return 0; }
运行代码,如图,图片被绘制了出来:
也可以多次调用putimage函数绘制(这里使用IMAGE类的getWidth和getHeight方法获取图像的宽高):
#include#include int main() { initgraph(640, 480, EW_SHOWCONSOLE); //初始化窗口 IMAGE img; //创建图像对象 loadimage(&img, _T("images/zombie.png")); //加载图像 putimage(0, 0, &img); //在起始坐标为(0, 0)的位置绘制图像img putimage(img.getwidth(), 0, &img); putimage(img.getwidth(), img.getheight(), &img); _getch(); closegraph(); //关闭窗口 return 0; }
easyx使用setbkcolor函数设置背景色:
void setbkcolor(COLORREF color);
easyx使用cleardevice函数来使用当前背景色清空绘图设备,即使用当前背景色清空窗口内容:
void cleardevice();
我们使用Windows API GetAsyncKeyState函数来获取键盘上下左右键的按键状态:
SHORT GetAsyncKeyState(int virtual_key);
全部代码:
#include#include #include int g_imgPosx = 0; //图像x坐标 int g_imgPosy = 0; //图像y坐标 //获取并处理键盘输入 void GetKeyInput(); int main() { initgraph(640, 480, EW_SHOWCONSOLE); //初始化窗口 IMAGE img; //创建图像对象 loadimage(&img, _T("images/zombie.png")); //加载图像 while (1) { GetKeyInput(); putimage(g_imgPosx, g_imgPosy, &img); //在起始坐标为(0, 0)的位置绘制图像img Sleep(16); //程序休眠16毫秒 cleardevice(); //16毫秒后清空窗口中的内容 } _getch(); closegraph(); //关闭窗口 return 0; } void GetKeyInput() { if (GetAsyncKeyState(VK_LEFT) & 0x8000) { g_imgPosx--; } if (GetAsyncKeyState(VK_RIGHT) & 0x8000) { g_imgPosx++; } if (GetAsyncKeyState(VK_UP) & 0x8000) { g_imgPosy--; } if (GetAsyncKeyState(VK_DOWN) & 0x8000) { g_imgPosy++; } }
你如果不太理解代码中 GetAsyncKeyState(VK_LEFT) & 0x8000,为什么要 & 0x8000 ?
可以阅读我的另一篇文章: Windows编程之使用GetAsyncKeyState()函数为什么要(& 0x8000)?
运行上述代码,我们可以发现使用键盘上的上下左右键可以控制图片的移动。
如果不使用cleardevice函数清除每一帧画面,那么以前的画面就会留下来,就像这样造成拖尾:
加大每次移动的坐标的偏移量使效果更加明显:
细心的你有没有发现,程序在运行画面会出现“闪烁”现象。本节内容到此为止,下节内容里我将介绍如何使用easyx中的双缓冲技术消除这种现象。
参考文献:Easyx文档
文章持续更新中!
求点赞、收藏!欢迎在评论区留言,有问必答!
作者水平有限,如果有误,欢迎指正!
编译环境:Visual Studio 2019、Easyx_20220116



