首页 > 其他分享 >EasyX图形库使用教程

EasyX图形库使用教程

时间:2024-08-09 22:24:06浏览次数:17  
标签:教程 窗口 函数 int IMAGE EasyX msg 图形库 鼠标

文章目录

EasyX图形库基础使用教程(快速上手)

前言:本文简单详细的介绍了EasyX图形库的常用函数和操作,帮助EasyX的快速上手

1、绘制简单的图形窗口

1.1头文件

graphics.h :包含已经被淘汰的函数

easyx.h: 只包含最新的函数

1.2创建图形化窗口

initgraphy函数

initgraph函数

HWND initgraph(
	int width,		//绘图窗口的宽度
	int height,		//绘图窗口的高度
    int flag=NULL	//绘图窗口的样式,默认为NULL,
);

flag的值还可以为:

含义
EX_DBLCLKS在绘图窗口中支持鼠标双击事件。
EX_NOCLOSE禁用绘图窗口的关闭按钮。
EX_NOMINIMIZE禁用绘图窗口的最小化按钮。
EX_SHOWCONSOLE显示控制台窗口。

简单句两个例子,其他同理:

创建一个尺寸为 640x480 的绘图窗口:

initgraph(640, 480);

创建一个禁用绘图窗口的关闭按钮并且尺寸为 640x480 的绘图窗口:

initgraph(640, 480,EX_NOCLOSE);

closegraph函数

closegraph函数

用于关闭绘图窗口void closegraph();

1.3窗口坐标

坐标轴及原点可按如图理解:

2、设置图形窗口属性

2.1颜色设置

setbkcolo

setbkcolor函数

void setbkcolo(COLORREF color);

注:在设置背景颜色后并不会改变现有的背景色,只是改变了背景色的值,之后再执行绘图语句,例如outtextxy,才会使用新设置的背景色值。

函数()中的值就是各种颜色对应的英文,在VS中可以右键—跳转到定义查看,以setbkcolo(RED)为例,右键RED跳转,可以看到各种颜色的值。

RGB

RGB函数

COLORREF RGB(
	BYTE byRed,		// 颜色的红色部分
	BYTE byGreen,	// 颜色的绿色部分
	BYTE byBlue		// 颜色的蓝色部分
);

使用三原色进行调光,原理同画图中的调色板,可以找到喜欢的颜色把三原色的数字输入,注意使用RGB时也要在外面加setbkcolor(),例:

setbkcolor(RGB(200,100,100));
cleardevice 刷新

cleardevice函数

void cleardevice();

使用当前别景色清空绘图设备,刷新颜色。

3、使用EasyX实现基本绘图功能

3.1 line 画线

line函数

void line(
	int x1,	 int y1,  int x2,  int y2,
);

在(x1,y1)和(x2,y2)两点间画一条线段。

3.1 circle 画圆

circle函数

void circle(
	int x,	int y,	int radius
);

以坐标(x,y)为圆心,画一个半径为radius的圆

3.2 rectangle 画矩形

rectangle函数

void rectangle(
	int left,	int top,	int right,	int bottom
);

确定举行的左上角和右下角坐标,画一个矩形

3.3 setfillcolor 填充颜色

setfillcolor函数

void setfillcolor(COLORREF color);

填充圆

  • 带线: fillcircle(int x, int y, int r);
  • 不带线: solidcircle(int x, int y, int r);

填充矩形

  • 带线: fillrectangle(int x1, int y1, int x2, int y2);

  • 不带线: solidrectangle(int x1, int y1, int x2, int y2);

代码举例:

int main()
{
	initgraph(700, 550);		//初始化图形界面尺寸
	setfillcolor(LIGHTBLUE);	//设置填充颜色
	fillcircle(150, 150, 50);	//画一个带线的圆
	solidcircle(300, 150, 50);	//画一个不带线的圆

	fillrectangle(150, 300, 280, 450);	//画一个带线的矩形
	solidrectangle(150, 300, 280, 450);	//画一个不带线的矩形

	while (1);		//防止图形化窗口一闪而过
	closegraph();	//关闭窗口
	return 0;
}

效果如图:

4、使用EasyX实现贴图功能

4.1 原样贴图

putimage 绘制图像

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图像,结合下文更清晰。

loadimage 加载图像

loadimage函数

loadimage(IMAGE* img,URL);//IMAGE是一种图像对象

其中,IMAGE是一种图像对象,可以参考IMAGE,URL是想要贴上的图片的相对位置,注意将图片放到源文件的路径下,如下代码中,"./Source/1.jpg"就是源文件同路径下的Source文件夹下的文件名叫做1.jpg的图片。

代码实例:

int main()
{
	initgraph(700, 600);
	int a = 1;
	IMAGE img;
	loadimage(&img, "./Source/1.jpg");
	putimage(0, 0, &img);
	while (1);
	closegraph();
	return 0;
}

效果如下:

但是使用上述方法贴图效果无法做到合适窗口的尺寸,因此有下面的方法来进行缩放

loadimage(IMAGE* img,URL,int width,int height);

代码实例(将上面的代码中的loading函数增加两个参数即可,其余不变)

int main()
{
	initgraph(700, 600);
	int a = 1;
	IMAGE img;
	loadimage(&img, "./Source/1.jpg",700,600);
	putimage(0, 0, &img);
	while (1);
	closegraph();
	return 0;
}

效果如下:

4.2 透明贴图

  • 通过图像的二进制运算达到去背景的效果

  • 认识素材

    • 掩码图
    • 背景图
  • 三元光栅操作码(仅介绍用得上的其中两个,其余可以参考putimageTernary raster operations

    • SRCAND 目标图像 = 目标图像 AND 源图像 贴掩码图
    • SRCPAINT 目标图像 = 目标图像 OR 源图像 贴背景图
  • 实例:

    int main()
    {
    	initgraph(800, 600);
    	int a = 1;
    	IMAGE img;
    	loadimage(&img, "./Source/1.jpg",1000,600);
    	putimage(0, 0, &img);
    
    	IMAGE pic[2];//创建一个IMAGE类型的数组
    	loadimage(&pic[0], "./Source/掩码图.png",400,400);
    	loadimage(&pic[1], "./Source/背景图.png", 400, 400);
    	putimage(150, 50, &pic[0],SRCAND);    //先贴掩码图
    	putimage(150, 50, &pic[1],SRCPAINT);  //再贴背景图
    
    	while (1);
    	closegraph();
    	return 0;
    }
    

4.3双缓冲贴图

BeginBatchDraw 开始双缓冲

BeginBatchDraw函数

void BeginBatchDraw();

在一个图形化的物体移动过程中,如果直接打印,会出现明显的闪烁,如以下代码(可以实现一个圆从左到右的移动):

#include <graphics.h>

int main()
{
	initgraph(640,480);
	setlinecolor(WHITE);
	setfillcolor(RED);

	for(int i=50; i<600; i++)
	{
		cleardevice();
		circle(i, 100, 40);
		floodfill(i, 100, WHITE);
		Sleep(10);
	}
	closegraph();
}

要解决这个问题就可以使用双缓冲贴图,简单来说,开始双缓冲后,绘画操作会暂时不输出到绘画窗口上,知道执行FlusBatchDraw函数或EndBatchDraw函数才将之前的绘图输出,这两个函数见下文。

EndBatchDraw 结束双缓冲

EndBatchDraw函数

void EndBatchDraw();

当需要结束双缓存贴图并执行指定区域内未完成的绘制任务时,可参照以下:

void EndBatchDraw(
	int left,	//指定区域左边的x坐标
	int top,	//指定区域上边的y左边
	int right,	//指定区域右边的x坐标
	int bottom	//指定区域下边的y坐标
);
FlushBatchDraw 显示一帧

FlushBatchDraw函数

void FlushBatchDraw();

当需要执行指定区域内未完成的绘制任务时,可参考以下:

void FlushBatchDraw(
	int left,	//指定区域左边的x坐标
	int top,	//指定区域上边的y左边
	int right,	//指定区域右边的x坐标
	int bottom	//指定区域下边的y坐标
);

使用以上的三个函数再将上面的圆的移动的代码进行优化,如下:

#include <graphics.h>

int main()
{
	initgraph(640,480);
	BeginBatchDraw();				//开始双缓冲贴图

	setlinecolor(WHITE);
	setfillcolor(RED);

	for(int i=50; i<600; i++)
	{
		cleardevice();
		circle(i, 100, 40);
		floodfill(i, 100, WHITE);
		FlushBatchDraw();			//绘画出当前帧的图案
		Sleep(10);
	}

	EndBatchDraw();					//双缓冲贴图结束
	closegraph();
}

5、实现EasyX按键件交互功能

阻塞按键交互

简单理解就是在程序运行过程中有输入等交互环节的,会在中途暂停程序直到输入完成互动再继续

比如在一个小程序中有一个可以通过上下左右控制运动的小球,按下→键,小球向右动了一下停下,等待下面的指令,直到再按下一个按键才继续,这就是一个阻塞。

非阻塞按键交互

简单理解是在一个程序中按键输入等交互动作不中断程序的运行

我们可以使用conic.h头文件下的getch()函数来读取键盘的内容,getch()函数(详情可见getch() 函数的简单使用

通过使用getch()和EasyX再加上打印图形的配合使用,可以达到一个通过键盘输入值控制窗口物体移动的效果。除了使用getch()函数,还可以使用Win 32 API下的GetAsyncKeyState函数来获取键盘键值达到键盘控制的效果,详情可以参考贪吃蛇小游戏中二、10下的内容。

6、在EasyX中进行鼠标操作

ExMessage 保存鼠标信息

ExMessage结构体

ExMessage是一个结构体,用来保存鼠标信息,定义如下:

struct ExMessage
{
	USHORT message;					// 消息标识
	union
	{
		// 鼠标消息的数据
		struct
		{
			bool ctrl		:1;		// Ctrl 键是否按下
			bool shift		:1;		// Shift 键是否按下
			bool lbutton	:1;		// 鼠标左键是否按下
			bool mbutton	:1;		// 鼠标中键是否按下
			bool rbutton	:1;		// 鼠标右键
			short x;				// 鼠标的 x 坐标
			short y;				// 鼠标的 y 坐标
			short wheel;			// 鼠标滚轮滚动值,为 120 的倍数
		};

		// 按键消息的数据
		struct
		{
			BYTE vkcode;			// 按键的虚拟键码
			BYTE scancode;			// 按键的扫描码(依赖于 OEM)
			bool extended	:1;		// 按键是否是扩展键
			bool prevdown	:1;		// 按键的前一个状态是否按下
		};

		// 字符消息的数据
		TCHAR ch;

		// 窗口消息的数据
		struct
		{
			WPARAM wParam;
			LPARAM lParam;
		};
	};
};

PeekMessage 获取鼠标信息

peekmessage函数

bool peekmessage(ExMessage *msg, BYTE filter = -1, bool removemsg = true);
  • msg是指向ExMessage的指针,用来保存获取到的信息

  • filter指定获取的信息范围,默认-1获取所有类别的消息,还可以用以下值:

    标志描述
    EX_MOUSE鼠标消息。
    EX_KEY按键消息。
    EX_CHAR字符消息。
    EX_WINDOW窗口消息。
  • removemsg:在peekmessage处理完消息后,是否将其从消息队列中移除

如果获取到了消息,则返回true,否则返回false

案例:

#include <graphics.h>
int main()
{
	initgraph(800, 800);
	ExMessage msg;
	while (1) {
		while (peekmessage(&msg)) {
			switch (msg.message) {
			case WM_LBUTTONDOWN: {
				circle(msg.x, msg.y, 10);
				break;
			}
				//按下左键,在鼠标按下的位置画圆
			case WM_RBUTTONDOWN: {
				rectangle(msg.x - 5, msg.y - 5, msg.x + 5, msg.y + 5);
				break;
				//按下右键,在鼠标按下的位置画方
			}
			}
		}
	}
	return 0;
}

OW | 窗口消息。 |

  • removemsg:在peekmessage处理完消息后,是否将其从消息队列中移除

如果获取到了消息,则返回true,否则返回false

案例:

#include <graphics.h>
int main()
{
	initgraph(800, 800);
	ExMessage msg;
	while (1) {
		while (peekmessage(&msg)) {
			switch (msg.message) {
			case WM_LBUTTONDOWN: {
				circle(msg.x, msg.y, 10);
				break;
			}
				//按下左键,在鼠标按下的位置画圆
			case WM_RBUTTONDOWN: {
				rectangle(msg.x - 5, msg.y - 5, msg.x + 5, msg.y + 5);
				break;
				//按下右键,在鼠标按下的位置画方
			}
			}
		}
	}
	return 0;
}

标签:教程,窗口,函数,int,IMAGE,EasyX,msg,图形库,鼠标
From: https://blog.csdn.net/TTKunn/article/details/141072177

相关文章

  • [软件工具]随机地址生成工具极速版使用教程
    【极速版随机地址生成器】——您的便捷生活小助手!在快节奏的生活中,无论是填写问卷、注册账号还是保护个人隐私,一个安全、快速的地址生成工具都是不可或缺的。我们精心打造的“极速版随机地址生成器”,一键快速生成随机地址,支持导出TXT或者excel格式,可以方便后续处理和二次加工......
  • Python教程(十三):常用内置模块详解
    目录专栏列表1.`os`模块2.`sys`模块3.`re`模块4.`json`模块5.`datetime`模块6.`math`模块7.`random`模块8.`collections`模块9.`itertools`模块10.`threading`模块总结专栏列表Python教程(十):面向对象编程(OOP)Python教程(十一):单元测试与异常捕获Py......
  • 黑马Java零基础视频教程精华部分_15_基本查找/顺序查找、二分查找/折半查找、插值查找
    系列文章目录文章目录系列文章目录一、基本查找/顺序查找核心思想:从0索引开始挨个往后查找代码:练习:定义一个方法利用基本查找,查询某个元素在数组中的索引,数组包含重复数据。二、二分查找/折半查找核心思想:属于有序查找算法。用给定值先与中间结点比较,每次排除一半的......
  • 搭建Java集成开发环境教程
            对于Java开发,‌IntelliJIDEA是一个广泛使用的集成开发环境。‌它提供了卓越的代码自动补全、‌动态语法检测、‌重构功能,‌以及对各种主流框架和前沿技术的深度支持。‌IntelliJIDEA有Ultimate版和CommunityEdition版,‌Ultimate版功能全面但收费,‌而Communi......
  • 高德地图 JS API2.0(入门级使用教程)
    高德地图JSAPI2.0入门使用教程准备工作注册高德地图开发者账号进入高德开放平台首页使用手机号注册,然后完成身份认证。创建应用[应用管理]-->[创建新的应用]–>[填写应用名称以及应用类型]-->[添加],然后获取到安全密钥和key即可。过程如下图:阅读参考文档......
  • Git和GitHub:开启你的开源之旅(入门级干货教程)
    Git及GitHub使用教程Git部分Git概述Git是一个免费的开源的分布式版本控制系统。版本控制系统版本控制系统是一种记录文件历史修改记录,以便将来查阅特定版本修订情况的系统。集中式版本控制工具VS分布式版本控制工具集中式版本控制工具:特点:所有文件版本和历史......
  • 猫头虎 分享:Python库 Tornado 的简介、安装、用法详解入门教程
    ......
  • 猫头虎分享:Python库 FastAPI 的简介、安装、用法详解入门教程
    ......
  • Visual Studio 2022安装教程
    如有问题请留言。一、下载VisualStudio20221.访问官网: 前往VisualStudio的官方网站(如VisualStudio官网),在首页或下载页面寻找VisualStudio2022的下载链接。2.选择版本: VisualStudio2022提供多个版本,包括社区版(Community)、专业版(Professional)和企业版(Enterprise)......
  • Python-和-PowerShell-协作教程-全-
    Python和PowerShell协作教程(全)原文:PowerShellandPythonTogether协议:CCBY-NC-SA4.0一、面向调查人员的PowerShell简介PowerShell提供了一个强大的获取引擎,可以从实时系统、服务器、外围设备、移动设备和数据驱动的应用程序(如ActiveDirectory)中获取大量信息。......