【C++】<图形库> EasyX基础使用

【C++】<图形库> EasyX基础使用

码农世界 2024-05-27 前端 80 次浏览 0个评论

文章目录

     一、安装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();

转载请注明来自码农世界,本文标题:《【C++】<图形库> EasyX基础使用》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,80人围观)参与讨论

还没有评论,来说两句吧...

Top