文章目录
一、安装EasyX库
二、图形窗口显示
三、基本绘图函数
四、图片显示
五、键盘交互
六、鼠标交互
七、双缓冲区解决闪屏
一、安装EasyX库
已经有兄弟写得很清楚了,见EasyX | 安装教程(详细图文)。
二、图形窗口显示
1. 包含的头文件:
- graphics.h:包含已经被淘汰的函数
- easyx.h:只包含最新的函数
2. 窗口创建及关闭:
- 创建:initgraph(int x, int y, int style); 其中x和y代表窗口的大小,style为0表示不显示控制台,为1表示显示控制台。
- 关闭:closegraph();
3. 图形化界面坐标:
- 原点位于左上角,x轴往右为正半轴,y轴往下为正半轴。
4. 设置窗口属性:
- 背景颜色:setbkcolor(颜色); 其中颜色可以使用RGB(i, j, k)或者RED等常量。
- 刷新窗口:cleardevice(); 不刷新窗口不会更新显示内容。
5. 代码示例:
#define _CRT_SECURE_NO_WARNINGS #include
#include using namespace std; int main() { //创建800*600的窗口 initgraph(800, 600, 0); //设置背景颜色为绿色 setbkcolor(RGB(0, 255, 0)); //刷新窗口 cleardevice(); //避免直接结束程序 while (1) {} //关闭窗口 closegraph(); return 0; }
三、基本绘图函数
1. 绘制线段:
- line(int x, int y, int xx, int yy);
- x和y表示起始点坐标,xx和yy表示终点坐标。
-
//绘制一条从(0,0)到(800,600)的线段 line(0, 0, 800, 600);
2. 绘制圆:
- 线条圆:circle(int x, int y, int r); 其中x和y为圆心坐标,r为半径。
- 填充有线圆:fillcircle(int x, int y, int r); 绘制出的圆有边框线且内部有填充。
- 填充无线圆:solidcircle(int x, int y, int r); 绘制的圆无边框线且内部有填充。
- 填充颜色:setfillcolor(颜色);
-
//线条圆 circle(100, 100, 50); //设置填充颜色为红色 setfillcolor(RED); //填充有线圆 fillcircle(200, 500, 20); //填充无线圆 solidcircle(500, 200, 50);
3. 绘制矩形:
- 线条矩形:rectangle(int x, int y, int xx, int yy);其中x和y为矩形左上角坐标,xx和yy为右下角坐标。
- 填充有线矩形:fillrectangle(int x, int y, int xx, int yy);
- 填充无线矩形:solidrectangle(int x, int y, int xx, int yy);
-
//线条矩形 rectangle(400, 300, 500, 500); //填充有线矩形 fillrectangle(300, 400, 500, 500); //填充无线矩形 solidrectangle(150, 200, 300, 300);
四、图片显示
1. 原样显示:
- ①创建IMAGE类型变量。例如IMAGE image;
- ②加载图片,调用函数loadimage(IMAGE* image, 图片路径, int x, int y); 其中image是步骤一创建的变量的地址,x和y是图片大小(可省略)。
- ③显示图片,调用函数putimage(int x, int y, IMAGE* image); 其中x和y是图片左上角的坐标。
- 注意:若出现错误,需要修改属性--->高级中的字符集为多字节字符集,右击的是解决方案下面那一行!
-
IMAGE wsl; loadimage(&wsl, "./wsl.jpg", 800, 600);//图片长800宽600 putimage(400, 300, &wsl);//从(400,300)开始显示
2. 透明贴图:去除图片背景。
- ①制作掩码图和核心图,可以利用ps等工具(在线ps工具:www.uupoop.com/#/)。如下图所示,左图为掩码图,右图为核心图。
- ②利用原样显示的方式将两张图同时显示。
-
IMAGE dog[2]; loadimage(dog, "./dog.png", 150, 150); loadimage(dog + 1, "./dogbk.png", 150, 150); putimage(200, 200, dog, SRCAND); //掩码图 putimage(200, 200, dog + 1, SRCPAINT); //核心图
五、键盘交互
1. 阻塞式获取键盘输入(不常用):
- ①添加头文件
。 - ②使用_getch()函数获取键盘输入。不同于cin等需要回车的机制,该函数可以实时获取键盘输入,更适合与用户交互。但是,若只使用_getch()则会使系统阻塞至这条语句,直至用户输入。因此,通常和_kbhit()联合使用,当_kbhit()检测到键盘输入时才会进行相关操作。
- ③使用_kbhit()函数检测键盘是否有输入。
2. 非阻塞式获取键盘输入(常用):
- 调用GetAsyncKeyState(按键常量值)函数。
- 这种方式不需要按键检测,而且支持斜方向移动(按住左键和下键可以往斜下方移动)。
3. 代码示例:在图形化窗口中绘制两个球,一个球自动移动并且碰到边缘自动弹射,另一个球由用户控制其移动。
#define _CRT_SECURE_NO_WARNINGS #include
#include #include #include #include using namespace std; class Ball { private: int x;//x坐标 int y;//y坐标 int r;//半径 int dx;//x方向移动增量 int dy;//y方向移动增量 int status = 4;//球自动移动的模式:1.左上移动 2.左下移动 3.右下移动 4.右上移动 public: Ball(int x, int y, int r, int dx, int dy) :x(x), y(y), r(r), dx(dx), dy(dy) {} //函数:在窗口中绘制球 void drawBall() { setfillcolor(LIGHTBLUE); solidcircle(x, y, r); } //函数:球自动移动 void moveBall() { //碰壁检测,改变移动模式 if (x + r >= 800) {//碰到右墙 status = 1; } else if (y <= r) {//碰到上墙 status = 2; } else if (x <= r) {//碰到左墙 status = 3; } else if (y + r >= 800) {//碰到下墙 status = 4; } //根据模式来移动 switch (status) { case 1: x -= dx; y -= dy; break; case 2: x -= dx; y += dy; break; case 3: x += dx; y += dy; break; case 4: x += dx; y -= dy; break; } } //函数:键盘控制球移动 void inputMove() { //阻塞式交互 /*char keyNumber = _getch(); switch (keyNumber) { case 'w': y -= dy; break; case 's': y += dy; break; case 'a': x -= dx; break; case 'd': x += dx; break; }*/ //非阻塞式交互 if (GetAsyncKeyState(VK_UP)) { y -= dy; } if (GetAsyncKeyState(VK_DOWN)) { y += dy; } if (GetAsyncKeyState(VK_LEFT)) { x -= dx; } if (GetAsyncKeyState(VK_RIGHT)) { x += dx; } } }; int main() { //创建窗口,设置背景色 initgraph(800, 800, 0); setbkcolor(WHITE); //创建两个球对象,b自动来回弹,键盘控制moveball Ball b(500, 500, 20, 5, 5); Ball moveball(400, 400, 20, 5, 5); //绘制两个球,并显示运动轨迹 while (1) { BeginBatchDraw(); cleardevice(); b.drawBall(); b.moveBall(); moveball.drawBall(); //按键检测(阻塞式交互才需要) /*if (_kbhit()) { moveball.inputMove(); }*/ moveball.inputMove(); //延迟1毫秒 this_thread::sleep_for(chrono::milliseconds(1)); FlushBatchDraw(); } //关闭窗口 closegraph(); return 0; }
六、鼠标交互
(1) 一般处理流程:
- ①创建变量存储鼠标信息:ExMessage mouse;
- ②调用peekmessage(&mouse)函数检测是否有鼠标点击。
- ③若存在鼠标点击,处理点击信息。
(2) 注意:一般使用switch-case的结构来判定点击信息。还可以使用mouse.x和mouse.y来获取当前鼠标点击的位置。
(3) 代码示例:鼠标点击左键时画圆,右键画矩形。
#define _CRT_SECURE_NO_WARNINGS #include
#include using namespace std; int main() { initgraph(800, 600, 0); ExMessage mouse; while (1) { //鼠标交互 if (peekmessage(&mouse)) { switch (mouse.message) { case WM_LBUTTONDOWN://鼠标左键按下画圆 circle(mouse.x, mouse.y, 5); break; case WM_RBUTTONDOWN://鼠标右键按下画矩形 rectangle(mouse.x - 5, mouse.y - 5, mouse.x + 5, mouse.y + 5); break; } } } closegraph(); return 0; }
七、双缓冲区解决闪屏
当绘制的图形过多时,就会出现闪屏现象,影响视觉体验。因此,可以使用双缓冲机制来解决闪屏,调用如下函数即可,可以参考easyx图形库-----贴图技巧之双缓冲消除闪屏。
BeginBatchDraw(); cleardevice(); //绘制图形 FlushBatchDraw();//也可以用EndBatchDraw();
- ①添加头文件
- ①制作掩码图和核心图,可以利用ps等工具(在线ps工具:www.uupoop.com/#/)。如下图所示,左图为掩码图,右图为核心图。
- 原点位于左上角,x轴往右为正半轴,y轴往下为正半轴。
还没有评论,来说两句吧...