How to Implement Dynamic Fireworks in C++ (Source Code Included)

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.

How to Implement Dynamic Fireworks in C++ (Source Code Included)

*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.

How to Implement Dynamic Fireworks in C++ (Source Code Included)

How to Implement Dynamic Fireworks in C++ (Source Code Included)Click to read the original text for more information.

Leave a Comment