Question

I am currently making a particle system, a basic one, also using Allegro 5 library.

Here is what i came up with:

int main()
{

    int mouseX = 0, mouseY = 0;
    int randNum = 0;


    std::vector <Particle *> Particles;
    bool running = false, redraw =  false, mouseHold = false;
    int particleCount = 0;

    al_init();
    al_init_image_addon();
    al_install_mouse();
    al_init_font_addon();
    al_init_ttf_addon();

    ALLEGRO_DISPLAY* display = al_create_display(800, 600);
    ALLEGRO_EVENT_QUEUE* event_queue = al_create_event_queue();
    ALLEGRO_TIMER* myTimer = al_create_timer(1.0 / 60);
    ALLEGRO_TIMER* pTimer = al_create_timer(1.0 / 120);
    ALLEGRO_FONT* myFont = al_load_ttf_font("MyFont.ttf", 20, NULL);

    al_register_event_source(event_queue, al_get_display_event_source(display));
    al_register_event_source(event_queue, al_get_timer_event_source(myTimer));
    al_register_event_source(event_queue, al_get_timer_event_source(pTimer));
    al_register_event_source(event_queue, al_get_mouse_event_source());

    running = true;
    al_start_timer(myTimer);
    while(running)
    {
        ALLEGRO_EVENT ev;
        al_wait_for_event(event_queue, &ev);

        if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
            running = false;

        if(ev.type == ALLEGRO_EVENT_MOUSE_AXES)
        {
            mouseX = ev.mouse.x;
            mouseY = ev.mouse.y;
        }

        if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
        {
            if(ev.mouse.button == 1)
                mouseHold = true;
        }

        if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP)
        {
            if(ev.mouse.button == 1)
                mouseHold = false;
        }

        if(ev.type == ALLEGRO_EVENT_TIMER)
        {
            randNum = (std::rand()+1 * ev.timer.count) % 50;
            std::cout << randNum << std::endl;

            if(mouseHold)
            {
                Particle* particle = new Particle(mouseX + randNum, mouseY + randNum);
                Particles.push_back(particle);
            }

            particleCount = Particles.size();
            for(auto i : Particles)
                i->Update();

            redraw = true;
        }

        for(auto iter = Particles.begin(); iter != Particles.end(); )
            {
                if(!(*iter)->GetAlive())
                {
                    delete (*iter);
                    iter = Particles.erase(iter);
                }
                else
                    iter++;
            }

        if(redraw && al_event_queue_is_empty(event_queue))
        {
            for(auto i : Particles)
                i->Draw();

            al_draw_textf(myFont, al_map_rgb(0,200,0), 0, 10, NULL, "Mouse X: %i", mouseX);
            al_draw_textf(myFont, al_map_rgb(0,200,0), 0, 30, NULL, "Mouse Y: %i", mouseY);
            al_draw_textf(myFont, al_map_rgb(0,200,0), 0, 60, NULL, "Particle Count: %i", particleCount);

            al_flip_display();
            al_clear_to_color(al_map_rgb(0,0,0));
            redraw = false;
        } 
    }


    al_destroy_display(display);
    al_destroy_event_queue(event_queue);
    al_destroy_timer(myTimer);
    for(auto i : Particles)
        delete i;
    Particles.clear();

    return 0;
}

Yes, the code is quite bad. It seems i know more about theory behind c++ than actually implementing it.. but im guess im learning.

The problems:

Someone said I couldn't be calling 'new' and 'delete' so many times as this is very bad.

The particle creation is limited by the timer- I can't/don't know how to make it so I can control the speed of particle creation.

I'm not expecting for someone to create on for me, it would be of great use if I could read something to help me understand or someone post some code to learn from/get me thinking?

Was it helpful?

Solution

Your particle generation as you have it layed it is indeed, limited by your timer. You are telling Allegro that if you have the mouse button down when a timer event is fired, generate one particle. You could increase the rate of particle creation by creating multiple particles each timer tick.

    for(int i = 0; i < rate; rate++)
    {
            randNum = (std::rand()+1 * ev.timer.count) % 50;
            std::cout << randNum << std::endl;

            if(mouseHold)
            {
                Particle* particle = new Particle(mouseX + randNum, mouseY + randNum);
                Particles.push_back(particle);
            }
    }

Then just use the variable rate to control how "fast" you are generating particles. This has the drawback of drawing multiple particles with the same original X and Y positions, but since you're also using the randNum, it should be ok.

Another option, which may be more suited for your needs depending on what these particles are doing, is to use a timer ticking at a faster rate to generate your particles. When you are checking for ALLEGRO_EVENT_TIMER do

if(ev.timer.source == timer)
{
    redraw = true;
}
if (ev.timer.source == fasterTimer)
{
    randNum = (std::rand()+1 * ev.timer.count) % 50;
    std::cout << randNum << std::endl;

    if(mouseHold)
    {
        Particle* particle = new Particle(mouseX + randNum, mouseY + randNum);
        Particles.push_back(particle);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top