easyx图形库基础:5.多物体运动+图片+消息处理

news2024/11/17 11:31:50

多物体运动+图片+帧率控制+消息处理

  • 一. 多物体运动
    • 1.如何合理的管理小球:
    • 2.初始化每一个球的信息:
    • 3.绘制多物体的运动:
    • 4.尝试添加小球个数:
      • num==10:![请添加图片描述](https://img-blog.csdnimg.cn/ce058e08c11c4410a7d09d25ca9275b3.png)
      • num==100:
      • num==1000:
      • #define num 100000
    • 5.批量绘图:
  • 二.图片
    • 1.图片格式
    • 2.IMAGE对象
    • 3.加载图片到image中
    • 4.图片的输出:
  • 三.消息处理
    • 1.基本概念:
    • 2.获取消息
    • 3.ExMessage结构体:
    • 4.使用和操作:

一. 多物体运动

我们之前了解过有关弹球小游戏中多个小球在窗体中运动反弹,现在,我们不满足于只有一个小球在窗体内运动了。我们希望,有更多的小球可以在窗体内运动。初始状态下,它们随机分布在窗体内。接下来,按照各自的速度与方向进行运动。此外,各小球的颜色也不尽相同。为了实现这样的效果,需要分别记录每一个小球的以下数据:

1.如何合理的管理小球:

1.定义一个结构体,存储小球的消息,有x,y坐标,水平竖直的速度,和小球的颜色。
2.#define num 100 作为我们小球数量。
3.#define R 20 作为我们小球半径

#define num 100
#define R 10![请添加图片描述](https://img-blog.csdnimg.cn/9f137a006d0243389764067aaa977561.png)

typedef struct ball {
	int x;
	int y;
	int vx;
	int vy;
}Ba;

2.初始化每一个球的信息:

1.初始化小球生成的坐标范围;
2.根据随机生成的速度和角度计算水平和竖直速度;
3.使用hsv颜色模型生成随机颜色。

void InitBall(Ba* ball)
{
	//循环初始化每一个数组内容
	for (int i = 0; i < num; i++)
	{
		//初始化坐标
		ball[i].x = (rand() % (800 - 2 * R)) - (400 - R);
		ball[i].y = (rand() % (600 - 2 * R)) - (300 - R);
		//随机生成实际速度
		int V = (rand() % 6) + 3;
		//随机生成角度
		int angle = rand() % 360;
		//确定随机的水平竖直速度
		double rad = PI / 180;
		ball[i].vx = V * cos(rad * angle);
		ball[i].vy = V * sin(rad * angle);
		//随机生成颜色
		ball[i].color = HSVtoRGB(rand() % 360, 0.8, 0.5);
	}
}

3.绘制多物体的运动:

1.cleardevice函数和Sleep函数一个在for循环的前面一个在for循环的后面。
2.如果把Sleep放到绘制小球的后面就会产生一个一个小球绘制然后移动的效果。
3.clear放到for循环的开始绘制一个球就清屏:

void Drawball(Ba* ball)
{
	while (1)
	{
		// 清空画面
		cleardevice();
		for (int i = 0; i < num; i++)
		{
			//设置小球填充颜色
			setfillcolor(ball[i].color);
			// 绘制小球
			solidcircle(ball[i].x, ball[i].y, R);
			// 碰到或越过上下边界反弹
			if (ball[i].y >= 300 - R || ball[i].y <= -300 + R)
			{
				ball[i].vy = -(ball[i].vy);
			}
			// 碰到或越过左右边界反弹
			if (ball[i].x <= -400 + R || ball[i].x >= 400 - R)
			{
				ball[i].vx = -(ball[i].vx);
			}
			ball[i].x += ball[i].vx;
			ball[i].y += ball[i].vy;
		}

		Sleep(40);
	}
}

4.尝试添加小球个数:

num==10:请添加图片描述

num==100:

请添加图片描述

num==1000:

请添加图片描述

#define num 100000

请添加图片描述

1.我们的球的变量是在栈区开辟的空间,栈的空间是比较有限的那么当我们需要非常多球的时候那么栈区的空间不足够我们去使用所以发生了栈溢出,所以我们需要进行动态开辟数组;

原来的:

int main()
{
	initgraph(800, 600);
	// 坐标系原点在窗体中心,X轴正方向向右,Y轴正方向向上
	setorigin(400, 300);
	setaspectratio(1, -1);
	// 设置背景色
	setbkcolor(RGB(164, 225, 202));
	// 使用背景色清空窗体
	cleardevice();
	//开辟数组
	Ba ball[num];
	//获取当前时间
	srand((unsigned int)time(NULL));
	//初始化数数组内容:
	InitBall(ball);
	//传数组内容,进行小球运动;
	Drawball(ball);
	closegraph();
	return 0;
}

更改之后的:

int main()
{
	initgraph(800, 600);
	// 坐标系原点在窗体中心,X轴正方向向右,Y轴正方向向上
	setorigin(400, 300);
	setaspectratio(1, -1);
	// 设置背景色
	setbkcolor(RGB(164, 225, 202));
	// 使用背景色清空窗体
	cleardevice();
	//开辟数组
	Ba* tmp=(Ba*)malloc(sizeof(Ba)*num);
	if (tmp == NULL)
	{
		perror("malloc file\n");
		exit(-1);
	}
	Ba* ball = tmp;
	//获取当前时间
	srand((unsigned int)time(NULL));
	//初始化数数组内容:
	InitBall(ball);
	//传数组内容,进行小球运动;
	Drawball(ball);
	getchar()
	closegraph();
	return 0;
}

5.批量绘图:

1.我们发现绘制的过程中num比较大的时候我们画面闪烁会比较严重?
2.我们的球就是一个一个绘制到屏幕上的球比较少的时候cpu和显卡之间的交互还是比较好的但是当num比较多的时候,cpu出去当前需要绘制的球但是上一个还没有绘制完成,这个时候就有可能会产生闪烁;

3.有什么解决方法呢?
批量绘图:
请添加图片描述

void Drawball(Ba* ball)
{
	//开启批量绘图,之后所有的绘图操作就会累计
	BeginBatchDraw();
	while (1)
	{
		// 清空画面
		cleardevice();
		for (int i = 0; i < num; i++)
		{
			//设置小球填充颜色
			setfillcolor(ball[i].color);
			// 绘制小球
			solidcircle(ball[i].x, ball[i].y, R);
			// 碰到或越过上下边界反弹
			if (ball[i].y >= 300 - R || ball[i].y <= -300 + R)
			{
				ball[i].vy = -(ball[i].vy);
			}
			// 碰到或越过左右边界反弹
			if (ball[i].x <= -400 + R || ball[i].x >= 400 - R)
			{
				ball[i].vx = -(ball[i].vx);
			}
			ball[i].x += ball[i].vx;
			ball[i].y += ball[i].vy;
		}
		FlushBatchDraw();
		//使累计的绘图操作一下绘制:
		Sleep(40);
	}
	//结束批量绘图:
	EndBatchDraw();
}

二.图片

1.图片格式

图片是人对视觉感知的物质再现。图片可以由光学设备获取,如照相机。也可以人为创作,如手工绘画。图片可以保存在纸质介质、胶片等等对光信号敏感的介质上。随着数字采集技术和信号处理理论的发展,越来越多的图像以数字形式存储。因而,有些情况下“图片”一词实际上是指数字图像。对于数字图像而言,有多种不同的方法组织和保存图片。常见的文件格式有有 bmp 、 gif 、 jpg 、 png 等。
Easyx图形库可以支持以下几种图片格式: bmp 、 gif 、 jpg 、 png 、 tif 、 emf 、 wmf 、 ico 。不在支持列表的文件格式无法被图形库读取。

2.IMAGE对象

受EasyX支持的图片格式可以被加载并存储在 IMAGE 对象当中。 对象 是一个C++中的概念,被用于面向对象风格的编程,它由C语言中的结构体升级而来。

3.加载图片到image中

现在,我们为刚刚声明的 IMAGE 对象填充图片信息。可以使用 loadimage 函数加载一个图片文件,如果加载成功,可以把这个图片的信息填充到 IMAGE 对象中。
使用loadimage函数加载图片到我们的image对象中:
在这里插入图片描述

第二个参数的类型为 ==LPCTSTR ==,你可能之前没有见过它。它是一个宏,用于适配多字节字符与宽字符。
该宏根据不同的设置,代表着不同的字符指针。

  1. 多字节字符模式下,它是 const char * 。
  2. 宽字符模式下,它是 const wchar_t * 。
    多字节字符是一种字符长度可变的模式:一个英文字符占用一个 char ,而中文字符将会占用两
    个 char 。
    宽字符是一种字符长度恒定的模式:在windows系统下,不论英文还是中文字符,均占用2个字节。
    目前我们并不想对字符模式展开讨论。暂时,我们使用较为熟悉的多字节字符,即 LPCTSTR 会被看做
    为 const char * 。在 Visual Studio 中,默认情况下,将使用宽字符模式。你可以通过以下的办法,将
    设置修改为多字节字符。
    在【工程属性】选项卡中,将【配置属性】-【高级】-【字符集】调整为未设置即可。

4.图片的输出:

接着调用 putimage 函数,可以把 image 对象中的图片显示在窗体上。
在这里插入图片描述

//定义一个Image对象
	IMAGE pho;
	//加载图片到
	loadimage(&pho,"./zw.jpg");
	putimage(0,0, &pho);

1.注意putimage函数使用的是逻辑坐标;
2.如果改变x,y的正方向的化会导致加载的图片和原来的图片产生方向的改变。

请添加图片描述

请添加图片描述

请添加图片描述
请添加图片描述

三.消息处理

1.基本概念:

EasyX中的消息是用户对窗体进行操作而产生的事件的载体。简单地来说,用户在窗体上进行操作,将会产生消息。例如:用户在窗体上操作鼠标、按下键盘、调整窗体大小都将产生消息。消息产生后,会按照消息产生的先后顺序,放置到窗体的消息队列当中。等待程序从消息队列中获取消息进行处理。

2.获取消息

  1. 获取消息
    通过 getmessage 函数可以从消息队列中获取到一个消息,并将这个消息从消息队列中移除。然后,程序可以对这个消息进行处理,并作出对应的响应。

让我们来看看 getmessage 这个函数该如何使用吧。
ExMessage getmessage(BYTE filter = -1);
void getmessage(ExMessage *msg, BYTE filter = -1);
getmessage 函数有两个重载版本,除了参数类型不同,函数的作用是相同的。

请添加图片描述

3.ExMessage结构体:

请添加图片描述

4.使用和操作:

请添加图片描述

实现一个代码完成鼠标在窗体中移动的过程中,正常移动以鼠标位置正常绘制一个黑色的小球,按下左键绘制一个红色的球,按下右键绘制一个蓝色的球,按下ctrl和左键绘制一个矩形。

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<easyx.h>
int main()
{
	initgraph(800, 600);
	setbkcolor(WHITE);
	cleardevice();
	//消息处理
	ExMessage msg;
	
	//鼠标移动绘制小球
	while (1)
	{
		//不段的获取鼠标消息
		getmessage(&msg, EX_MOUSE);
		switch (msg.message)
		{
			case WM_LBUTTONDOWN:
				setfillcolor(RED);
				solidcircle(msg.x, msg.y, 10);
				break;
			case WM_RBUTTONDOWN:
				if (msg.ctrl)
				{
					setfillcolor(GREEN);
					solidrectangle(msg.x, msg.y, msg.x + 20, msg.y + 20);
					continue;
				}
				else
				{
					setfillcolor(BLUE);
					solidcircle(msg.x, msg.y, 10);
				}
				break;
		}
		setfillcolor(BLACK);
		solidcircle(msg.x, msg.y, 2);
	}
	getchar();
	closegraph();
	return 0;
}

总结:使用结构体中的消息标识通过switch case语句去走不同的消息标识进行不同的处理。
如果使用ifelse语句自己范围结构体一些数据有一些成员变量的类型你不清楚结构体变量的.操作范围不是很灵活的
使用消息标识+switch语句就可以非常好的获取对应的信息并且做出相关的操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/890118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

线程|线程的使用、四种实现方式

1.线程的实现方式 1.用户级线程 开销小&#xff0c;用户空间就可以创建多个。缺点是&#xff1a;内核无法感知用户级多个线程的存在&#xff0c;把其当作只有一个线程&#xff0c;所以只会提供一个处理器。 2.内核级线程 相对于用户级开销稍微大一点&#xff0c;可以利用多…

【JavaSE】面向对象之继承

继承 继承概念继承的语法父类成员的访问子类和父类没有同名成员变量子类和父类有同名成员变量成员方法名字不同成员方法名字相同 super关键字子类构造方法super和this继承方式 继承概念 继承(inheritance)机制&#xff1a;是面向对象程序设计使代码可以复用的最重要的手段&…

分代收集 + 垃圾回收算法

分代假说 1. 弱分代假说&#xff08;Weak Generational Hypothesis&#xff09;&#xff1a;绝大多数对象都是朝生夕灭的 2. 强分代假说&#xff08;Strong Generational Hypothesis&#xff09;&#xff1a;熬过越多次垃圾收集过程的对象就越难以消亡 3. 跨代引用假说&…

网工软考 | 软考改机考,解读你最关心的5个问题

2023年下半年软考改为机考后&#xff0c;后台收到了很多的留言&#xff0c;大家对于实行机考的疑问还是有很多&#xff0c;例如要不要画图&#xff0c;用的什么输入法&#xff0c;报名费会不会涨价等。 今天就给大家解答一波。 01 软考改机考FAQ Q&#xff1a;软考机考会不会随…

华为内部,提拔项目经理的等级依据

大家好&#xff0c;我是老原。 最近和朋友吃饭&#xff0c;都在聊项目化&#xff0c;企业转型…… 要知道&#xff0c;一件事一旦到了饭桌上成了谈资&#xff0c;就说明它的趋势已经形成了。 这同时也表示&#xff0c;市场对项目经理的要求更高了。 早在2009年的高端项目经…

【eNSP】交换机(vlan和vlan间通信)

【eNSP】交换机&#xff08;vlan和vlan间通信&#xff09; 原理术语过程 实验根据图片连接模块配置设备名称和IP地址配置交换机交换机链路指定sw1配置sw2配置 设置网关交换机互联实验设置查看设置结果 ospf配置 原理 HUB集线器&#xff1a;它的作用可以简单的理解为将一些机器…

信捷 XDH Ethercat 高速计数器计数准确性

本人在X0,X1连手轮(手轮刻度100)&#xff0c;CNT_AB指令使用高速计数器HSC0,出现了计数值不对。 转1圈应该有计数值变化400&#xff0c;实际变化只有50左右&#xff0c;有时多于50&#xff0c;有时少于50。 检查发现SFD320等于4&#xff0c;是正确的&#xff0c;百般不得其解…

AI 与智能化 API 治理的探索实践

7月 Eolink 受邀参加 QECon 2023 全球软件质量&效能大会&#xff08;北京站&#xff09;。Eolink CEO 刘昊臻&#xff0c;发表了主题为**「AI 与智能化 API 治理的探索实践」**的演讲&#xff0c;分享 Eolink 在 API 全生命周期中治理实践与 AI 结合的探索。 Eolink 作为国…

String trim方法,使用前需要判空

背景是接口导入时&#xff0c;部分字段因为手动录入可能误输空格&#xff0c;所以需去掉前后空格&#xff0c;这些属性为非必填&#xff0c;所以未校验非空&#xff0c;引发空指针异常。 代码类似这样&#xff0c;未判断是否为空&#xff0c;直接trim,导致空指针异常 Testpubl…

【JVM】运行时数据区——自问自答

Q:Java 运行时数据区解构&#xff0c;哪些数据线程独占&#xff0c;哪些是线程共享&#xff1f;每个区域会产生GC和异常吗&#xff1f; 运行时数据区&#xff1a; 1、PC寄存器 2、堆区 3、JVM栈 4、Native栈 5、方法区 其中&#xff0c;PC寄存器、Native栈、JVM栈是线程独占的…

【Spring专题】Spring之Bean生命周期源码解析——阶段四(Bean销毁)(拓展,了解就好)

目录 前言阅读建议 课程内容一、Bean什么时候销毁二、实现自定义的Bean销毁逻辑2.1 实现DisposableBean或者AutoCloseable接口2.2 使用PreDestroy注解2.3 其他方式&#xff08;手动指定销毁方法名字&#xff09; 三、注册销毁Bean过程及方法详解3.1 AbstractBeanFactory#requir…

python列表笔记,python列表用法及基础操作

列表的介绍 定义100个变量&#xff0c;每个变量存放一个学生的姓名可行吗&#xff1f;有更好的办法吗&#xff1f; 答&#xff1a; 列表 一、列表的格式 定义列的格式&#xff1a;[元素1, 元素2, 元素3, ..., 元素n] 变量tmp的类型为列表 tmp [xiaoWang,180, 65.0] 列…

数模论文写作细节要求

目录 优秀论文必要条件 数学建模的基本思路 第一步&#xff1a;了解问题——查文献、找数据 第二步&#xff1a;阐述要解决什么问题、用什么方法 其余步骤&#xff1a;给出数学模型、计算求解、对比结果与真实情况、应用于现实问题。 使用某种数学方法的理由和依据 创…

【SAP-MDG】MDG配置-配置工作流任务 Configure Workflow Tasks

一、配置工作流任务的前提&#xff1a; 1.工作流能启动的常规设置已设置完毕&#xff1b;&#xff08;前面提到的内容&#xff09; 2.配置目录&#xff1a;SPRO→SAP NetWeaver→Application Server→Business Management→SAP Business Workflow.&#xff08;SPRO→SAP NetW…

Splashtop:适合旅行办公人士的远程工作解决方案

无论是重要的商务旅行&#xff0c;还是旅游度假&#xff0c;还是数字游牧生活方式的诱惑&#xff0c;许多人都会发现自己在机场贵宾室制作演示文稿&#xff0c;在古雅的咖啡馆参加虚拟会议&#xff0c;或者在偏远海滩的宁静背景下集思广益。 随处远程办公的生活让人向往。尽管…

5G科技防汛,助力守护一方平安

“立秋虽已至&#xff0c;炎夏尚还在”&#xff0c;受台风席卷以及季节性影响全国多地正面临强降水的严峻挑战。“落雨又顺秋&#xff0c;绵绵雨不休”&#xff0c;正值“七下八上” 防汛关键时期&#xff0c;贵州省水文水资源局已全面进入备战状态。 为确保及时响应做好防汛抢…

Linux SIGCHLD信号

在子进程结束之后&#xff0c;会默认给父进程发送SIGCHLD信号。 有以下代码&#xff1a; 编译并运行以上代码&#xff1a; 可以看到在子进程结束之后&#xff0c;将SIGCHLD信号发送给了父进程&#xff0c;然后输出SIGCHLD信号的代号17。 在后台运行以上代码并查看进程信息&am…

IDEAdebug调试时查看时间戳和Date类型的对象,格式化为yyyy-mm-hh

平时debug时遇到Date或者时间戳时看时间不好判断到底是几月几号&#xff0c;希望直接格式化为想要的格式 比如 下面&#xff0c;Date直接显示为 yyyy-mm-hh的格式 解决方案&#xff1a; 无需下载插件&#xff0c;如图 //Date格式化 return new SimpleDateFormat("…

SIP网络音频模块SV-2401V网络对讲音频模块(支持POE)

功能和特点 音频工作方式&#xff1a; 音频解码&#xff1a;即音频播放。接收来自网络的音频流&#xff0c;经过模块解码后通过线路输出高质量音频信号。目前支持可以播放以下音频格式&#xff1a;MP3、WAV (PCM IMA ADPCM)、G.711、G.722等&#xff0c;可以播放最高48k采样率…

汽车租赁管理系统/汽车租赁网站的设计与实现

摘 要 租赁汽车走进社区&#xff0c;走进生活&#xff0c;成为当今生活中不可缺少的一部分。随着汽车租赁业的发展&#xff0c;加强管理和规范管理司促进汽车租赁业健康发展的重要推动力。汽车租赁业为道路运输车辆一种新的融资服务形式、广大人民群众一种新的出行消费方式和…