MFC学习之新年烟花效果代码实例

2022已到尾声,不知过去的这一年你过的如何。新年将至,万象更新,有仪式感的来迎接新的一年吧!

一、EGE的介绍、安装和使用
先从EGE官网(http://www.xege.org )下载安装包文件
在这里插入图片描述
把安装包内 include 文件夹内所有文件,复制到你的编译器安装目录下的include目录内再把lib目录下的文件,根据自己的编译器,复制对应的东西到你的编译器安装目录下的lib目录内,具体编译器所依赖的文件情况:
本实例用的vc2015 + ege20.08,include目录:D:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include;lib目录:D:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib。
官方的安装教程:EGE安装使用教程

在这里插入图片描述

二、程序设计需要注意的问题:需要考虑的内容
烟花包含多个粒子,粒子数,爆炸时粒子速度大小,粒子颜色
设置一些时间变量,用来控制烟花上升的时刻,时长和绽放的时间
上升速度和位置,这个速度需要注意坐标系里y是向下为正。
烟花初始随机设定好本次的发射位置,和时间,速度等相关属性,绽放完后重新开始。
每次都会先更新烟花位置再绘制。
考虑一下重力因素(有往下的加速度),空气阻力因素(速度衰减),爆炸时的球状散开(速度大小相等,方向不同),可以求x, y分速度。
稍微考虑一下水平动量守恒,做一对速度相反的粒子,因为是随机的,怕有时太随机了偏向一边

(1)、对烟花进行 初始化 ,设置烟花从准备到发射,再到绽放的一整个流程的参数,比如三个时间,爆炸时每个粒子的速度。
其中粒子爆炸速度比较难计算,因为要设置爆炸成球状,速度大小都是相等的,只是速度的方向不同。随机得到方向后,就 将速度投影到xOy平面上,然后想分别投影到x轴和y轴。 可以参考空间向量如何获得其两个x, y方向的分量


	delayTime = rand() % 300 + 20;
	riseTime = rand() % 80 + 160;
	bloomTime = 160;

	risePos.x = rand() % 450 + 300.0f;
	risePos.y = GROUND;

	riseSpeed.y = myrand(1.0f) - 3.0f;	//上升速度,根据坐标系需要是负的
	riseSpeed.x = myrand(0.4f) - 0.2f;	//可稍微倾斜
	//随机颜色
	color = HSVtoRGB(myrand(360.0f), 1.0f, 1.0f);
	//给每一个粒子设置初始速度
	for (int i = 0; i < NUM_PARTICLE - 1; i += 2)
	{
		//为了球状散开,设初始速度大小相等
		//初始随机速度水平角度和垂直角度,因为看到是平面的,所以求x, y分速度
		double levelAngle = randomf() * 360;
		double verticalAngle = randomf() * 360;
		//速度投影到xOy平面
		double xySpeed = particleSpeed * cos(verticalAngle);

		//求x, y分速度
		p[i].speed.x = xySpeed * cos(levelAngle);
		p[i].speed.y = xySpeed * sin(levelAngle);

		//动量守恒,每对速度反向
		if (i + 1 < NUM_PARTICLE)
		{
			p[i + 1].speed.x = -p[i].speed.x;
			p[i + 1].speed.y = -p[i].speed.y;
		}
	}

(2)、每一帧里对烟花的位置以及粒子的位置进行更新。上升时只更新烟花的位置就行了,因为粒子都在一起,爆炸时就要分别计算粒子的位置了。从上升到爆炸的过渡阶段,要给每一个粒子设置位置,因为之前更新的都是烟花的位置,粒子的位置没有给,设置为当前位置就好了。每一次对位置进行更新,都会将对应的时间值减1
阶段的判断:
准备阶段 :延迟时间 大于0, 不更新位置
上升阶段 :延迟时间 不大于0,并且 上升时间 大于0, 更新烟花位置,如果到达爆炸阶段,就给粒子当前位置。
爆炸阶段 :前面两个时间都不大于0,爆炸时间 大于0, 更新粒子位置
结束阶段 :前面三个时间都为0,这时就对烟花重新初始化

if (delayTime-- > 0)
		return;
	//处于上升阶段,只更新Fire位置
	else if (riseTime > 0)
	{
		risePos.x += riseSpeed.x;
		risePos.y += riseSpeed.y;

		//重力作用
		riseSpeed.y += 0.005;

		//上升完毕,到达爆炸阶段
		if (--riseTime <= 0)
		{
			//设粒子初始位置为Fire当前位置
			for (int i = 0; i < NUM_PARTICLE; i++)
			{
				p[i].pos.x = risePos.x;
				p[i].pos.y = risePos.y;
			}
		}
	}
	//Fire绽放阶段
	else if (bloomTime-- > 0)
	{
		//粒子散开,更新粒子位置
		for (int i = 0; i < NUM_PARTICLE; i++)
		{
			p[i].pos.x += p[i].speed.x;
			p[i].pos.y += p[i].speed.y;
			//重力作用
			p[i].speed.y += 0.005;
			//速度减慢
			p[i].speed.x *= 0.982;
			p[i].speed.y *= 0.982;
		}
	}
	else
	{
		//Fire重新开始
		init();
	}

注意事项:
因为涉及模糊滤镜,又有背景图,所以不可能在有背景的窗口加模糊滤镜,这样背景会糊掉,所以只能另外设个图像缓存,在里面做。
将图像缓存绘制到窗口时,要特别注意,我们需要的是光叠加的效果,所以绘制时需要到三元光栅操作码 SRCPAINT, 即 目标图像和源图像颜色位或,这个请参考官网源文档,这个码还挺难找的,因为码很多

三、大家看效果吧,个人感觉还可以,细节问题可以多调整参数进行测试。

MFC学习之新年烟花测试实例

实例代码:https://download.csdn.net/download/u014740628/87368242
参考地址:https://www.jb51.net/article/235389.htm

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逃逸的卡路里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值