1. Introduction
The fireworks program implemented in C++ uses the EGE graphics library. If you don’t have it, you need to install it yourself. Adjustable options include: background image and background music, particle blur, brightness, and ascent speed parameters. The dynamic fireworks created are visually appealing and can be used to impress a girlfriend or for a confession, haha. You can also create it just for fun!
2. Let’s Get to the Code
fire.h
#pragma once
#ifndef FIREWORKS_H_
#define FIREWORKS_H_
#define myrand(m) ((float)rand() * m / 36565)
#include <graphics.h>
struct Speed { double x, y;};
struct Pos { double x, y;};
struct Particle{ Pos pos; Speed speed;};
#define GROUND 580 // Ground position
class Fireworks // Fireworks class {
private:
static const int NUM_PARTICLE = 200;
static const double particleSpeed;
Particle p[NUM_PARTICLE];
color_t color;
int delayTime; // Delay time
int riseTime; // Rise time
int bloomTime; // Explosion time
Pos risePos; // Ascent stage position
Speed riseSpeed; // Ascent speed
public: // Initialization
Fireworks();
void init(); // Update position and related properties
void update(); // Draw based on property values
void draw(PIMAGE pimg = NULL);
};
#endif // ! FIREWORKS_H_
main.cpp
#include <time.h>
#include <graphics.h>
#include "fire.h"
#define NUM_FIREWORKS 10 // Number of fireworks
int main(){
initgraph(1080, 720, INIT_RENDERMANUAL);
srand((unsigned)time(NULL)); // Fireworks
Fireworks* fireworks = new Fireworks[NUM_FIREWORKS];
PIMAGE bgPimg = newimage();
getimage(bgPimg, "night.jpg"); // Draw first to avoid blank period
putimage(0, 0, bgPimg);
delay_ms(0); // Background music
MUSIC bgMusic;
bgMusic.OpenFile("MELANCHOLY.mp3");
bgMusic.SetVolume(1.0f);
if (bgMusic.IsOpen()) {
bgMusic.Play(0);
}
// Image cache, since adding a background image directly with a blur filter will blur the background image,
// so a separate image cache is set up to draw fireworks and add a blur filter, then draw to the window
PIMAGE cachePimg = newimage(800, 800);
// Timer for checking music playback
int timeCount = 0;
for (; is_run(); delay_fps(60)) {
// Check every second, if finished, replay
if ((++timeCount % 60 == 0) && (bgMusic.GetPlayStatus() == MUSIC_MODE_STOP)) {
bgMusic.Play(0);
}
// Update position
for (int i = 0; i < NUM_FIREWORKS; i++) {
fireworks[i].update();
}
// Draw background
putimage(0, 0, bgPimg);
// Draw fireworks to image cache
for (int i = 0; i < NUM_FIREWORKS; i++) {
fireworks[i].draw(cachePimg);
}
// Blur filter, trailing effect
// The second parameter, blur degree, the larger the blur, the thicker the particles
// The third parameter, brightness, the larger the trailing, the longer
// You can try other parameter combinations, such as the following sets:
// 0x03, 0xff
// 0x0b, 0xe0
// 0xff, 0xff
// imagefilter_blurring(cachePimg, 0x0a, 0xff);
// imagefilter_blurring(cachePimg, 0x03, 0xff);
// imagefilter_blurring(cachePimg, 0x0b, 0xe0);
// imagefilter_blurring(cachePimg, 0xff, 0xff);
// imagefilter_blurring(cachePimg, 0x01, 0xff);
imagefilter_blurring(cachePimg, 0x0b, 0xff);
// Cache drawn to window, mode is (final color = window pixel color Or image pixel color), so colors will overlay
putimage(0, 0, cachePimg, SRCPAINT);
}
delete[] fireworks;
delimage(bgPimg);
delimage(cachePimg);
bgMusic.Close();
closegraph();
return 0;}
fire.cpp
#include <cmath>
#define SHOW_CONSOLE
#include "fire.h"
const double Fireworks::particleSpeed = 3.0f;
Fireworks::Fireworks(){
init();}
void Fireworks::init(){
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; // Ascent speed, needs to be negative due to coordinate system
riseSpeed.x = myrand(0.4f) - 0.2f; // Slightly tilted
// Random color
color = HSVtoRGB(myrand(360.0f), 1.0f, 1.0f);
// Set initial speed for each particle
for (int i = 0; i < NUM_PARTICLE - 1; i += 2) {
// To spread out spherically, set initial speed size equal
// Initial random speed horizontal angle and vertical angle, since it is seen on a plane, calculate x, y speed
double levelAngle = randomf() * 360;
double verticalAngle = randomf() * 360;
// Speed projection onto xOy plane
double xySpeed = particleSpeed * cos(verticalAngle);
// Calculate x, y speed
p[i].speed.x = xySpeed * cos(levelAngle);
p[i].speed.y = xySpeed * sin(levelAngle);
// Conservation of momentum, reverse speed for each pair
if (i + 1 < NUM_PARTICLE) {
p[i + 1].speed.x = -p[i].speed.x;
p[i + 1].speed.y = -p[i].speed.y;
}}
void Fireworks::draw(PIMAGE pimg){
// Not started
if (delayTime > 0) return;
// Fireworks ascent stage
else if (riseTime > 0) {
setfillcolor(color, pimg);
// Draw four points to make it larger
bar(risePos.x, risePos.y, risePos.x + 2, risePos.y + 2, pimg);
}
// Fireworks bloom stage
else {
setfillcolor(color, pimg);
for (int i = 0; i < NUM_PARTICLE; i++) {
bar(p[i].pos.x, p[i].pos.y, p[i].pos.x + 2, p[i].pos.y + 2, pimg);
}
}
// Update position and related properties
void Fireworks::update(){
if (delayTime-- > 0) return;
// In the ascent stage, only update fireworks position
else if (riseTime > 0) {
risePos.x += riseSpeed.x;
risePos.y += riseSpeed.y;
// Gravity effect
riseSpeed.y += 0.005;
// Ascent complete, enter explosion stage
if (--riseTime <= 0) {
// Set particle initial position to current fireworks position
for (int i = 0; i < NUM_PARTICLE; i++) {
p[i].pos.x = risePos.x;
p[i].pos.y = risePos.y;
} } }
// Fireworks bloom stage
else if (bloomTime-- > 0) {
// Particles spread out, update particle position
for (int i = 0; i < NUM_PARTICLE; i++) {
p[i].pos.x += p[i].speed.x;
p[i].pos.y += p[i].speed.y;
// Gravity effect
p[i].speed.y += 0.005;
// Speed reduction
p[i].speed.x *= 0.982;
p[i].speed.y *= 0.982;
} }
else {
// Fireworks restart
init();
}}
3. Implementation Effect
Since the fireworks are dynamic, screenshots do not look very good, but the actual dynamic fireworks are quite beautiful. Everyone can try it out, and if you think this fireworks program is well done, please give it a thumbs up.

*Disclaimer: This article is compiled from the internet, and the copyright belongs to the original author. If the source information is incorrect or infringes rights, please contact us for deletion or authorization matters.

Click to read the original text for more information.