首页 > 编程语言 >C/C++新春烟花

C/C++新春烟花

时间:2025-01-11 11:31:24浏览次数:3  
标签:动画 爆炸 升空 烟花 C++ 新春 绘制

图片

系列文章

序号直达链接
1C/C++爱心代码
2C/C++跳动的爱心
3C/C++李峋同款跳动的爱心代码
4C/C++满屏飘字表白代码
5C/C++大雪纷飞代码
6C/C++烟花代码
7C/C++黑客帝国同款字母雨
8C/C++樱花树代码
9C/C++奥特曼代码
10C/C++精美圣诞树
11C/C++俄罗斯方块小游戏
12C/C++贪吃蛇小游戏
13C/C++孤单又灿烂的神-鬼怪
14C/C++闪烁的爱心
15C/C++哆啦A梦
16C/C++简单圣诞树
17C/C++小宇宙
18C/C++冰墩墩
19C/C++七彩花朵
20C/C++玫瑰花
21C/C++小猪佩奇
22C/C++简易爱心
23C/C++流星雨
24C/C++2048小游戏
25C/C++爱心圣诞树
26C/C++文字跑马灯
27C/C++教师工作量管理系统
28C/C++满天繁星
29C/C++漂浮爱心
30C/C++五子棋小游戏
31C/C++球球大作战小游戏
32C/C++走迷宫小游戏
33C/C++粉色爱心
34C/C++跨年烟花
35C/C++棕色小熊
36C/C++粉色动态爱心

目录

系列文章

写在前面

技术需求

完整代码

代码分析

1. 整体结构和功能概述

2. 数据结构与对象模型

3. 烟花的初始化与随机化

4. 升空与爆炸过程

5. 烟花的生命周期与更新

6. 动画的刷新与绘制

7. 随机化与多样性

8. 性能优化

9. 总结

写在后面


写在前面

C/C++实现新春烟花的完整代码。

技术需求

  1. 图形编程:使用 graphics.h 图形库进行图形绘制和动画效果的实现,如绘制圆形(solidcircle)和设置颜色(setfillcolor)。该库提供了基础的图形绘制功能,可以在窗口中显示动态效果。

  2. 随机数生成:通过 rand() 函数生成随机数,控制烟花的初始位置、颜色、爆炸半径等参数,使每次烟花的效果都不相同。

  3. 三角函数应用:使用 cossin 函数计算烟花爆炸时火花的轨迹。通过三角函数来模拟爆炸产生的火花沿不同角度的扩散。

  4. 时间控制:使用 Sleep(2) 来控制动画的刷新速度,使烟花的升空、爆炸等效果更加流畅,并避免动画过快而不易观察。

  5. 批量绘制:通过 BeginBatchDraw()FlushBatchDraw() 实现批量绘制,减少屏幕刷新次数,提高绘制效率,从而减少动画卡顿现象。

  6. 图形界面管理:使用 initgraph(640, 480) 初始化图形界面,设置图形窗口的大小;cleardevice() 清空屏幕,准备绘制下一帧图像;closegraph() 关闭图形界面,结束绘制。

  7. 颜色管理:通过 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. 整体结构和功能概述

程序的目标是通过动画展示烟花从发射到爆炸的过程。每个烟花有多个属性,比如当前位置、爆炸半径、颜色等。程序模拟了多个烟花同时发射并逐个爆炸的效果。整体流程包括以下几个步骤:

  1. 初始化:为每个烟花随机设置初始位置、目标高度、爆炸半径、颜色等属性。
  2. 绘制:根据烟花的当前位置和状态,绘制其升空过程以及爆炸过程。
  3. 运动和更新:更新每个烟花的位置,模拟其升空和爆炸的过程,直到烟花爆炸结束后重新初始化。

2. 数据结构与对象模型

代码中的关键数据结构是 Fire 结构体,表示每个烟花。通过结构体封装烟花的多个属性,使得每个烟花的信息可以独立处理。Fire 结构体包含以下属性:

  • nowxnowy:表示烟花当前的坐标位置。初始时,烟花从屏幕下方随机位置发射,nowy 的初始值大于屏幕的高度,确保烟花从屏幕下方出现。
  • endy:表示烟花升空的目标高度。烟花升至该高度后会爆炸。此属性影响烟花是否进入爆炸阶段。
  • radio:表示烟花爆炸的半径,影响爆炸时烟花粒子的散开范围。
  • explode:记录烟花当前的爆炸进度。在烟花达到目标高度并进入爆炸阶段后,explode 会增加,直到达到设定的爆炸半径。
  • rgbcolor:表示烟花的颜色。rgb 是一个数组,分别存储红、绿、蓝三个色彩通道的值;color 是图形库的 COLORREF 类型,表示实际绘图时使用的颜色值。

每个烟花的这些属性通过一个数组 fire[MAXNUM] 来存储,MAXNUM 定义了最大烟花数量(15个)。这样,程序就能够同时处理多个烟花对象,每个烟花的生命周期独立运行,呈现出多个烟花同时升空和爆炸的效果。

3. 烟花的初始化与随机化

在程序的初始化阶段,通过 Init 函数为每个烟花随机生成初始属性,包括位置、颜色、目标高度、爆炸半径等。具体来说:

  • 随机位置:通过随机数生成烟花的初始 x 坐标(在屏幕宽度范围内)和 y 坐标(设定为屏幕底部下方的某个位置),确保每个烟花的发射位置不同。
  • 随机高度和爆炸半径:目标高度 (endy) 和爆炸半径 (radio) 都是随机生成的,这使得每个烟花的升空过程和爆炸效果各不相同。
  • 随机颜色:为了使烟花呈现多彩效果,颜色也是随机选择的。从预定义的几种颜色中随机选取一种,使得每个烟花的颜色有所区别。

4. 升空与爆炸过程

  • 升空阶段:在 Draw 函数中,如果烟花的当前高度 nowy 大于目标高度 endy,烟花仍然处于升空阶段。此时,烟花的颜色会逐渐变亮(通过逐步增加 RGB 三个色通道的值来实现),并以小圆点的形式绘制在屏幕上,模拟烟花的上升过程。

  • 爆炸阶段:当 nowy 小于或等于 endy 时,烟花开始进入爆炸阶段。此时,烟花将发射出多个粒子,粒子会在不同方向上以圆形轨迹散开,模拟烟花爆炸时四散的火花。每个粒子的颜色会随着距离爆炸中心的远近而逐渐变化,粒子的大小也会发生变化,爆炸效果随着 explode 值的增加而逐渐增强,直到爆炸达到最大半径。

爆炸的轨迹是通过三角函数来计算的,使用 cossin 函数分别计算粒子在水平和垂直方向的移动距离。这些粒子沿着360度方向均匀分布,使得烟花的爆炸效果呈现出圆形的火花效果。

5. 烟花的生命周期与更新

每个烟花的生命周期包括升空和爆炸两个阶段。在升空阶段,烟花不断向上移动,直到达到目标高度 endy。在爆炸阶段,烟花会发射出多个粒子并逐渐扩散开来,模拟烟花的爆炸效果。

  • 升空过程:烟花的 nowy 值会持续递减,模拟烟花的上升。当烟花的 nowy 值达到或低于目标高度 endy 后,烟花就进入爆炸阶段。
  • 爆炸过程:一旦进入爆炸阶段,烟花的 explode 值开始增加,直到它达到设定的爆炸半径 radio。每当 explode 达到 radio 时,烟花会重新随机初始化位置、颜色等属性,进入新的生命周期。

这一过程中,烟花会根据设定的规则(比如升空速度和爆炸半径)进行运动,爆炸的粒子效果也会随着时间的推移发生变化,直到烟花生命周期结束。

6. 动画的刷新与绘制

为了实现流畅的动画效果,程序使用了 BeginBatchDrawFlushBatchDraw 函数,这两个函数分别表示批量绘制的开始和结束。通过这些函数,程序可以一次性绘制出所有烟花的更新状态,而不是每次绘制单个烟花,从而提高了动画的性能和流畅度。

  • cleardevice:每次绘制新的一帧之前,先清除屏幕上的内容,确保上一帧的烟花不会影响到当前帧。
  • setfillcolorsolidcircle:用于设置烟花粒子的颜色和绘制圆形。setfillcolor 设置颜色,solidcircle 绘制一个实心圆,代表烟花的粒子。

动画每帧通过调用 MoveDraw 函数来更新烟花的位置和状态,并重新绘制屏幕,模拟烟花的升空和爆炸效果。Sleep(2) 控制每帧的间隔时间,从而调整动画的速度。

7. 随机化与多样性

这段代码的一个重要特点是它通过随机化产生多样化的烟花效果。每个烟花在升空和爆炸的过程中具有不同的速度、颜色、轨迹和爆炸半径。通过使用随机数生成位置、颜色、爆炸半径等,使得每次运行程序时,呈现出来的烟花效果都不同,增强了视觉效果的多样性和趣味性。

8. 性能优化

为了保证动画的流畅性和性能,程序使用了批量绘制和屏幕清除的方式。通过 BeginBatchDrawFlushBatchDraw,可以减少每次绘制时的开销,并避免屏幕频繁的刷新导致的闪烁现象。同时,Sleep(2) 控制每一帧的绘制时间,使得动画的播放速度合适,不会过快或过慢。

9. 总结

这段代码利用图形库中的基本绘图功能和数学运算实现了烟花的升空与爆炸效果。通过模拟多个烟花的并行发射和爆炸,展示了一个动态的烟花动画。程序的结构清晰,模块化设计使得每个部分(如初始化、绘制、更新)都有明确的职责。同时,通过随机化烟花的属性,使得每次运行程序时,展示的效果都有所不同,增加了视觉的多样性和趣味性。

写在后面

我是一只有趣的兔子,感谢你的喜欢!

标签:动画,爆炸,升空,烟花,C++,新春,绘制
From: https://blog.csdn.net/m0_68111267/article/details/145074254

相关文章

  • c++ imu
      #include<iostream>#include<cmath>#include<chrono>#include<thread>#include<random>//Simplehelper:wrapsangleto[-pi,pi]doublewrapToPi(doubleangle){while(angle>M_PI){angle-=2.0*......
  • 【华为OD技术面试手撕真题】- C++手撕技术面试八股文(1)
    文章目录一、delete和delete[]的区别二、const解释一下其作用1.定义常量2.修饰指针3.修饰函数参数4.修饰类成员函数三、struct和class的区别1.默认访问控制2.继承的默认访问控制四、#include<file.h>#include"file.h"的区别五、C++文件......
  • C++语言的学习路线
    C++语言的学习路线C++是一种强大的高级编程语言,广泛应用于系统软件、游戏开发、嵌入式系统和高性能应用等多个领域。由于其丰富的功能和灵活性,C++是一门值得深入学习的语言。本文旨在为初学者制定一条系统的学习路线,帮助他们循序渐进地掌握C++语言。第一阶段:基础知识1.......
  • 1.10日学习笔记之C++的类
    ·类其实就是一种数据类型,和结构相似。类的成员包括两类,属性(成员变量)和行为(成员函数)。·成员函数定义的两种方法(可能有多种,觉得这两种比较常用)1、将类的成员函数定义在类体内,如classCPerson{public:shortage;shortgetage(){returnage;}};2、将......
  • 【C++】穿越编程岁月,细品C++进化轨迹,深化入门基石(续章)——揭秘函数缺省参数的魅力、函
    文章目录一、函数缺省参数二、函数重载三、引用1.引用的概念和定义2.引用的特性3.引用的使用4.const引用5.指针和引用的关系四、inline内联函数和nullptr1.inline2.nullptr一、函数缺省参数   缺省参数其实就是默认参数,它是声明或定义函数时为函数的参数指定......
  • 【C++】揭开C++类与对象的神秘面纱(首卷)(类的基础操作详解、实例化艺术及this指针的深
    文章目录一、类的定义1.类定义格式2.类访问限定符3.类域二、类的实例化1.实例化概念2.对象的大小三、隐藏的this指针与相关练习1.this指针的引入与介绍练习1练习2练习3一、类的定义1.类定义格式   在讲解类的作用之前,我们来看看类是如何定义的,在C++中,class......
  • Qt C++学习笔记1.7
    1.7Qt入门:实现一个图片查看软件需要用到的控件:QLabelQLineEditQPushButton需要实现的功能:打开目录选择图片显示图片的名字显示图片QLabel基本用法设置文本voidsetText(constQString&);获取文本QStringtext()const;设置图片voidsetPixmap(constQPixm......
  • C++并发编程之基于锁的数据结构的适用场合与需要考虑和注意的问题
    在C++多线程编程中,锁是一种常用的同步机制,用于保护共享数据,防止多个线程同时访问和修改,从而避免数据不一致或其他并发问题。基于锁的数据结构适用于多种并发编程场合,但同时也需要注意一些关键问题。1. 适用的并发编程场合锁在以下几种场合特别有用:1.1 保护共享数据当多个......
  • 详解 C++ 防御性编程声明一个类型 int *(*(*foo)(int))[5];
    C++中有一些语法由于灵活性和强大功能显得非常复杂。例如,复杂声明是许多人在学习C++时遇到的难题之一。下面以一条常被称为“C++最难的声明”为例,逐步拆解它的含义。声明:int*(*(*foo)(int))[5];这是一个看似复杂的C++声明。让我们逐步分析它的含义。1.阅读......
  • c++ 赋值运算符的定义
    1.赋值运算符的定义赋值运算符是用于修改已有对象的内容,而不是用于创建新对象。其典型的定义如下:Person&Person::operator=(constPerson&other);Person&Person::operator=(Person&&other);左侧对象(*this):表示已经存在的目标对象。右侧对象(other):表示要从中复制或转......