🐍 快过年了,祝大家蛇年大吉,希望新的一年能有人陪你一同看烟火!!!
还不快点赞!!!
这次的动画不仅包含烟花燃放,还有万家灯火,愿家常在心中!!!
TypeScript版本在这里:TypeScript新年烟花代码(附源码,趣味编程)
目录
背景介绍
烟花燃放效果是一种极具视觉冲击力的动画效果,常用于庆祝节日、活动开场或游戏特效。使用 C++ 和 SFML 实现烟花效果,不仅可以提升程序的性能,还能通过代码的可维护性和扩展性,为开发者带来更高效的开发体验。本文将详细介绍如何使用 C++ 和 SFML 实现一个绚丽的新年烟花燃放效果,并探讨其在实际项目中的应用场景。
在实现过程中,我们使用了以下关键技术和库:
-
C++17:提供高性能和面向对象编程的支持。
-
SFML 3.0:一个跨平台的多媒体库,支持图形、音频、输入和网络等功能。
-
随机数生成器:用于生成随机的烟花位置、颜色和粒子运动轨迹。
调试环境
本次代码调试环境为 2023 款 MacBook Pro,搭载苹果M2 Pro芯片,32GB内存,操作系统为macOs Ventura 13.5.2。Mac平台可直接编译运行,其他平台测试运行需确保以下两点:
- C++17 及 SFML3.0 开发环境正常配置
- 修改编译指令中的 SFML 头文件及库所在路径
技术要点
实现烟花燃放效果需要掌握以下关键技术,它们共同构成了实现这一视觉效果的基础。
1. C++17 语言特点及优势
C++17 是继 C++14 之后的一个重要版本,引入了许多新特性和改进,旨在提高编程效率、简化代码以及增强标准库的功能。它在实现烟花效果中的主要优势包括:
-
高性能:C++17 提供了高效的内存管理和计算性能,适合实时图形渲染。
-
面向对象编程:支持类和对象,便于将烟花、粒子等逻辑封装为独立的模块。
-
标准库改进:例如
std::vector
和std::map
的性能优化,以及新特性如std::optional
和std::variant
。 -
新特性支持:如结构化绑定、条件初始化语句等。
2. SFML 3.0 简介
SFML(Simple and Fast Multimedia Library)是一个跨平台的 C++ 库,旨在简化多媒体应用程序的开发。本次开发基于 SFML 3.0,它引入了许多新特性和改进:
-
C++17 支持:SFML 3.0 已全面更新以支持 C++17。
-
改进的事件处理 API:提供了更强大的事件处理机制。
-
音频模块更新:用 miniaudio 替代了 OpenAL。
-
剪切和模板测试:支持更复杂的图形渲染。
-
依赖管理改进:通过 CMake 的
FetchContent
动态获取和构建依赖。
3. 数学运算与物理模拟
烟花效果的核心是物理模拟,涉及以下数学和物理知识:
-
三角函数:通过
sin
和cos
计算粒子的初始速度和方向,模拟烟花爆炸的向外扩散效果。 -
向量运算:更新粒子的位置和速度,模拟粒子的运动轨迹。
-
物理公式:模拟重力加速度(
vy += 0.004
),使粒子在垂直方向上逐渐下落。
4. 随机数生成器
随机性是烟花效果的关键,通过 rand()
实现以下功能:
-
随机生成粒子的位置、速度和颜色:使每次烟花爆炸的效果都不尽相同。
-
随机生成建筑物和窗户:为背景添加随机性,增强视觉效果。
-
随机触发烟花爆炸:每隔一段时间随机生成新的烟花,增加动态效果。
5. 动画与帧循环
动画效果的实现依赖于高效的帧循环,核心技术包括:
-
window.display()
:SFML 提供的 API,用于更新窗口内容。 -
帧循环逻辑:在每一帧中更新粒子状态、清除画布并重新绘制,实现动态效果。
6. 状态管理与模块化
虽然烟花效果主要依赖 SFML 和 C++,但通过面向对象编程,我们实现了模块化开发的优势:
-
状态管理:通过类和对象管理粒子和建筑物的状态,避免不必要的重新计算。
-
事件处理:通过 SFML 的事件系统(如鼠标点击事件)增强交互性,允许用户通过点击触发烟花爆炸。
通过以上技术的结合,我们能够实现一个高效、可维护且视觉效果绚丽的新年烟花燃放效果。
完整代码
以下是实现新年烟花燃放效果的完整代码:
fireworks.cpp (核心逻辑实现)
// main.cpp
#include <SFML/Graphics.hpp>
#include <vector>
#include <random>
#include <cmath>
#include <memory>
#include <iostream>
#include <sstream>
// 数据结构定义
struct Window {
float x;
float y;
bool isLit;
Window(float _x, float _y, bool _isLit) : x(_x), y(_y), isLit(_isLit) {}
};
struct Building {
float x;
float y;
float width;
float height;
std::vector<Window> windows;
Building(float _x, float _y, float _w, float _h) : x(_x), y(_y), width(_w), height(_h) {}
};
struct Particle {
float x;
float y;
float vx;
float vy;
float alpha;
sf::Color color;
float life;
Particle(float _x, fl