﻿# include <list>

class cRenderClass
{
public:

	cRenderClass(const int, const int);
	~cRenderClass();

	void create(int argc, _TCHAR* argv[]);
	void loop();

	void clear();

	void render();
	void setColour(float, float, float);
	void setPointSize(int);
	void drawPixel(int, int);

    void drawPixel(int x_, int y_, sRGB& colour_, int size_);
private:

	int		 m_sw, m_sh;
	int		 m_point_size;
	float	*m_buffer;
	sRGB	 m_colour;
};



// Generate random integers within a certain range
inline int rand(int max_, int min_ = 0) {
    return  min_ + rand() % (max_ - min_);
}

class Popcorn {
public:
    static constexpr float dt = 0.01;       // Change time of each update
    static constexpr int sleep_time = 5;    // Waiting time per frame
    static constexpr float g = 46.0f;       // Here is the acceleration of gravity in a fictional world, not the earth.

    static constexpr int xv_range = 200;    // The maximum speed x-axis component of the exploded popcorn firework
    static constexpr int yv_range = 200;    // The y-axis component of the maximum velocity of the exploded popcorn firework

    static constexpr float colour_v = 0.1f; // Color change
    static constexpr int init_size = 2;     // The size of the popcorn firework ascension cannonball
    static constexpr int init_v_min = g * 3;  // Ascent speed minimum
    static constexpr int init_v_max = g * 4.5;// Ascent speed maximum

    static constexpr int min_boom_time = 2; // Explosion minimum value relative to dt
    static constexpr int max_boom_time = 4; // Explosion maximum value relative to dt

    static constexpr int tail_count = 32;   // The length of the popcorn firework tail is proportional to the memory occupied
    //static constexpr float tail_d = 32 * dt;// popcorn firework tail

    static constexpr int max_boom_count = 2;// Maximum number of explosions

    static constexpr int max_boom_popcorn = 512;    // The maximum number of explosives generated is limited by memory
    static constexpr int min_boom_popcorn = 433;    // The minimum number of explosives

    static int count;   // Current total number of popcorn firework

    /*
    There is a second explosion, that is, the explosives produced can explode again
     Can explode infinitely
     But the total number will always be limited by memory
    */

public:
    float init_x;
    float init_y;

    float x;
    float y;

    float xv;
    float yv;
    float theta;

    float t;
    float boom_time;

    sRGB colour;

    int boom_count;
    int size;

    struct Position {
        float x;
        float y;
    };
    Position tail[tail_count];

public:
    Popcorn();

    void init(int x_, int y_, int size_, int boom_count_);

    ~Popcorn();
public:
    // Is it invisible? Invisible returns true
    virtual bool invisible();
    // update data
    virtual void update();
    // Perform an explosion effect
    virtual void boom();
    // Draw itself
    virtual void draw();

    // The above functions have been changed to virtual functions, which can be easily replaced by inheritance
};
/*
For example: Just write these three functions

class Popcorn2 :public Popcorn {
    virtual void update();
    virtual void boom();
    virtual void draw();
};

// */

