系列文章
目录
写在前面
C/C++实现新春烟花的完整代码。
技术需求
-
图形编程:使用
graphics.h
图形库进行图形绘制和动画效果的实现,如绘制圆形(solidcircle
)和设置颜色(setfillcolor
)。该库提供了基础的图形绘制功能,可以在窗口中显示动态效果。 -
随机数生成:通过
rand()
函数生成随机数,控制烟花的初始位置、颜色、爆炸半径等参数,使每次烟花的效果都不相同。 -
三角函数应用:使用
cos
和sin
函数计算烟花爆炸时火花的轨迹。通过三角函数来模拟爆炸产生的火花沿不同角度的扩散。 -
时间控制:使用
Sleep(2)
来控制动画的刷新速度,使烟花的升空、爆炸等效果更加流畅,并避免动画过快而不易观察。 -
批量绘制:通过
BeginBatchDraw()
和FlushBatchDraw()
实现批量绘制,减少屏幕刷新次数,提高绘制效率,从而减少动画卡顿现象。 -
图形界面管理:使用
initgraph(640, 480)
初始化图形界面,设置图形窗口的大小;cleardevice()
清空屏幕,准备绘制下一帧图像;closegraph()
关闭图形界面,结束绘制。 -
颜色管理:通过
RGB()
函数定义烟花的颜色,并利用setfillcolor()
设置填充颜色,以模拟不同的火花效果。
完整代码
#include <graphics.h>
#include <math.h>
#include <time.h>
#include <stdio.h>
#define MAXNUM 15
#define WIDTH 640
#define HEIGHT 480
#define PI 3.1415926
struct Fire
{
int nowx;
int nowy;
int endy;
int radio;
int explode;
int rgb[3];
COLORREF color;
}fire[MAXNUM];
void Init()
{
for (int i = 0; i < MAXNUM; i++)
{
fire[i].nowx = rand() % WIDTH;
fire[i].nowy = HEIGHT + rand() % 250 + 50;
fire[i].endy = rand() % 100 + 10;
fire[i].radio = rand() % 50 + 120;
fire[i].explode = 0;
int c[][3] = { {255, 0, 0}, {210, 190, 255}, {255, 120, 0}, {255, 0, 150}, {255, 240, 100}, {10, 255, 255}, {160, 10, 255}, {255, 200, 60} };
int n = rand() % 8;
fire[i].color = RGB(c[n][0], c[n][1], c[n][2]);
fire[i].rgb[0] = c[n][0];
fire[i].rgb[1] = c[n][1];
fire[i].rgb[2] = c[n][2];
}
}
……
代码分析
这段代码是一个简单的烟花爆炸动画实现,模拟了烟花的升空和爆炸过程。通过图形库的绘制功能以及一定的物理与数学计算,成功地创造出一个动态的烟花效果。以下将从多个角度对这段代码进行详细分析。
1. 整体结构和功能概述
程序的目标是通过动画展示烟花从发射到爆炸的过程。每个烟花有多个属性,比如当前位置、爆炸半径、颜色等。程序模拟了多个烟花同时发射并逐个爆炸的效果。整体流程包括以下几个步骤:
- 初始化:为每个烟花随机设置初始位置、目标高度、爆炸半径、颜色等属性。
- 绘制:根据烟花的当前位置和状态,绘制其升空过程以及爆炸过程。
- 运动和更新:更新每个烟花的位置,模拟其升空和爆炸的过程,直到烟花爆炸结束后重新初始化。
2. 数据结构与对象模型
代码中的关键数据结构是 Fire
结构体,表示每个烟花。通过结构体封装烟花的多个属性,使得每个烟花的信息可以独立处理。Fire
结构体包含以下属性:
nowx
和nowy
:表示烟花当前的坐标位置。初始时,烟花从屏幕下方随机位置发射,nowy
的初始值大于屏幕的高度,确保烟花从屏幕下方出现。endy
:表示烟花升空的目标高度。烟花升至该高度后会爆炸。此属性影响烟花是否进入爆炸阶段。radio
:表示烟花爆炸的半径,影响爆炸时烟花粒子的散开范围。explode
:记录烟花当前的爆炸进度。在烟花达到目标高度并进入爆炸阶段后,explode
会增加,直到达到设定的爆炸半径。rgb
和color
:表示烟花的颜色。rgb
是一个数组,分别存储红、绿、蓝三个色彩通道的值;color
是图形库的COLORREF
类型,表示实际绘图时使用的颜色值。
每个烟花的这些属性通过一个数组 fire[MAXNUM]
来存储,MAXNUM
定义了最大烟花数量(15个)。这样,程序就能够同时处理多个烟花对象,每个烟花的生命周期独立运行,呈现出多个烟花同时升空和爆炸的效果。
3. 烟花的初始化与随机化
在程序的初始化阶段,通过 Init
函数为每个烟花随机生成初始属性,包括位置、颜色、目标高度、爆炸半径等。具体来说:
- 随机位置:通过随机数生成烟花的初始
x
坐标(在屏幕宽度范围内)和y
坐标(设定为屏幕底部下方的某个位置),确保每个烟花的发射位置不同。 - 随机高度和爆炸半径:目标高度 (
endy
) 和爆炸半径 (radio
) 都是随机生成的,这使得每个烟花的升空过程和爆炸效果各不相同。 - 随机颜色:为了使烟花呈现多彩效果,颜色也是随机选择的。从预定义的几种颜色中随机选取一种,使得每个烟花的颜色有所区别。
4. 升空与爆炸过程
-
升空阶段:在
Draw
函数中,如果烟花的当前高度nowy
大于目标高度endy
,烟花仍然处于升空阶段。此时,烟花的颜色会逐渐变亮(通过逐步增加 RGB 三个色通道的值来实现),并以小圆点的形式绘制在屏幕上,模拟烟花的上升过程。 -
爆炸阶段:当
nowy
小于或等于endy
时,烟花开始进入爆炸阶段。此时,烟花将发射出多个粒子,粒子会在不同方向上以圆形轨迹散开,模拟烟花爆炸时四散的火花。每个粒子的颜色会随着距离爆炸中心的远近而逐渐变化,粒子的大小也会发生变化,爆炸效果随着explode
值的增加而逐渐增强,直到爆炸达到最大半径。
爆炸的轨迹是通过三角函数来计算的,使用 cos
和 sin
函数分别计算粒子在水平和垂直方向的移动距离。这些粒子沿着360度方向均匀分布,使得烟花的爆炸效果呈现出圆形的火花效果。
5. 烟花的生命周期与更新
每个烟花的生命周期包括升空和爆炸两个阶段。在升空阶段,烟花不断向上移动,直到达到目标高度 endy
。在爆炸阶段,烟花会发射出多个粒子并逐渐扩散开来,模拟烟花的爆炸效果。
- 升空过程:烟花的
nowy
值会持续递减,模拟烟花的上升。当烟花的nowy
值达到或低于目标高度endy
后,烟花就进入爆炸阶段。 - 爆炸过程:一旦进入爆炸阶段,烟花的
explode
值开始增加,直到它达到设定的爆炸半径radio
。每当explode
达到radio
时,烟花会重新随机初始化位置、颜色等属性,进入新的生命周期。
这一过程中,烟花会根据设定的规则(比如升空速度和爆炸半径)进行运动,爆炸的粒子效果也会随着时间的推移发生变化,直到烟花生命周期结束。
6. 动画的刷新与绘制
为了实现流畅的动画效果,程序使用了 BeginBatchDraw
和 FlushBatchDraw
函数,这两个函数分别表示批量绘制的开始和结束。通过这些函数,程序可以一次性绘制出所有烟花的更新状态,而不是每次绘制单个烟花,从而提高了动画的性能和流畅度。
cleardevice
:每次绘制新的一帧之前,先清除屏幕上的内容,确保上一帧的烟花不会影响到当前帧。setfillcolor
和solidcircle
:用于设置烟花粒子的颜色和绘制圆形。setfillcolor
设置颜色,solidcircle
绘制一个实心圆,代表烟花的粒子。
动画每帧通过调用 Move
和 Draw
函数来更新烟花的位置和状态,并重新绘制屏幕,模拟烟花的升空和爆炸效果。Sleep(2)
控制每帧的间隔时间,从而调整动画的速度。
7. 随机化与多样性
这段代码的一个重要特点是它通过随机化产生多样化的烟花效果。每个烟花在升空和爆炸的过程中具有不同的速度、颜色、轨迹和爆炸半径。通过使用随机数生成位置、颜色、爆炸半径等,使得每次运行程序时,呈现出来的烟花效果都不同,增强了视觉效果的多样性和趣味性。
8. 性能优化
为了保证动画的流畅性和性能,程序使用了批量绘制和屏幕清除的方式。通过 BeginBatchDraw
和 FlushBatchDraw
,可以减少每次绘制时的开销,并避免屏幕频繁的刷新导致的闪烁现象。同时,Sleep(2)
控制每一帧的绘制时间,使得动画的播放速度合适,不会过快或过慢。
9. 总结
这段代码利用图形库中的基本绘图功能和数学运算实现了烟花的升空与爆炸效果。通过模拟多个烟花的并行发射和爆炸,展示了一个动态的烟花动画。程序的结构清晰,模块化设计使得每个部分(如初始化、绘制、更新)都有明确的职责。同时,通过随机化烟花的属性,使得每次运行程序时,展示的效果都有所不同,增加了视觉的多样性和趣味性。
写在后面
我是一只有趣的兔子,感谢你的喜欢!
标签:动画,爆炸,升空,烟花,C++,新春,绘制 From: https://blog.csdn.net/m0_68111267/article/details/145074254