c/c++游戏编程之Easyx图形库基础(一) EasyX基础
c/c++游戏编程之Easyx图形库基础(二) 绘制图片
c/c++游戏编程之Easyx图形库基础(三) 用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