Better loading bitmaps, drawing, and fixing problems (Using Allegro)

Started by
1 comment, last by Captain P 15 years, 10 months ago
My first project is finally working, and now I am wondering if there is a better way to load bitmaps. I mean, making a list of BITMAP* whatever and load_bitmap(whatever, whatever); is very annoying. Is there a better way to do this? I also want to check each one for error, like not existing. But with fewer lines! Then, I want to know how to draw the bitmaps without checking if(condition), else if(condition) again and again. Isn't that what robots are for? Finally, my window flickers faster that people run to their bags during lunch! I have a double buffer, am I using it correctly? If I am not, how can I make this better? Thank you to everyone!

#include <allegro.h>

int croom = 1;
int pxpos = 320;
int pypos = 140;
int direction = 1;

int timecount = 0;
void timeplus()
{
    timecount ++;
    if(timecount >= 5)
    {
        timecount = 1;
    }
}

void world()
{

    BITMAP *alert1, *alert2, *alert3;
    BITMAP *startbit, *humbit, *scibit, *tecbit, *musbit, *japbit, *dreamer, *end;
    BITMAP *buffer = create_bitmap(640,480);

    alert1 = load_bitmap("alert1.bmp",NULL);
    alert2 = load_bitmap("alert2.bmp",NULL);
    alert3 = load_bitmap("alert3.bmp",NULL);
    startbit = load_bitmap("startbit.bmp",NULL);
    humbit = load_bitmap("humbit.bmp",NULL);
    scibit = load_bitmap("scibit.bmp",NULL);
    tecbit = load_bitmap("tecbit.bmp",NULL);
    musbit = load_bitmap("musbit.bmp",NULL);
    japbit = load_bitmap("japbit.bmp",NULL);
    dreamer = load_bitmap("dreamer.bmp",NULL);
    end = load_bitmap("end.bmp",NULL);

    bool exit = false;

    while(exit != true)
    {
        clear_bitmap(screen);
        clear_bitmap(buffer);

        if(timecount == 1 || timecount == 2)
        {
            if(direction == 1){draw_sprite(screen,alert1,pxpos,pypos); draw_sprite(buffer,alert1,pxpos,pypos);}
            else if(direction == 2){draw_sprite_h_flip(screen,alert1,pxpos,pypos); draw_sprite_h_flip(buffer,alert1,pxpos,pypos);}
        }
        else if(timecount == 3)
        {
            if(direction == 1){draw_sprite(screen,alert2,pxpos,pypos);draw_sprite(buffer,alert2,pxpos,pypos);}
            else if(direction == 2){draw_sprite_h_flip(screen,alert2,pxpos,pypos); draw_sprite_h_flip(buffer,alert2,pxpos,pypos);}
        }
        else if(timecount == 4 || timecount == 5)
        {
            if(direction == 1){draw_sprite(screen,alert3,pxpos,pypos); draw_sprite(buffer,alert3,pxpos,pypos);}
            else if(direction == 2){draw_sprite_h_flip(screen,alert3,pxpos,pypos); draw_sprite_h_flip(buffer,alert3,pxpos,pypos);}
        }

        if(croom == 1){draw_sprite(screen,startbit,0,0);}
        else if(croom == 2){draw_sprite(screen,humbit,0,0); draw_sprite(buffer,humbit,0,0);}
        else if(croom == 3){draw_sprite(screen,scibit,0,0); draw_sprite(buffer,scibit,0,0);}
        else if(croom == 4){draw_sprite(screen,tecbit,0,0); draw_sprite(buffer,tecbit,0,0);}
        else if(croom == 5){draw_sprite(screen,musbit,0,0); draw_sprite(buffer,musbit,0,0);}
        else if(croom == 6){draw_sprite(screen,japbit,0,0); draw_sprite(buffer,japbit,0,0);}
        else if(croom == 7){draw_sprite(screen,dreamer,0,0); draw_sprite(buffer,dreamer,0,0);}
        else if(croom == 8){draw_sprite(screen,end,0,0); draw_sprite(buffer,end,0,0);}

        draw_sprite(screen,buffer,0,0);

        if(croom < 1 || croom > 8){exit = true;}
        if(pxpos < 10){croom --; pxpos = 540;}
        if(pxpos > 630){croom ++; pxpos = 100;}

        if(key[KEY_ESC]){exit = true;}
        else if(key[KEY_LEFT]){direction = 1; pxpos -= 5;}
        else if(key[KEY_RIGHT]){direction = 2; pxpos += 5;}

    }
    destroy_bitmap(alert1);
    destroy_bitmap(alert2);
    destroy_bitmap(alert3);
    destroy_bitmap(startbit);
    destroy_bitmap(humbit);
    destroy_bitmap(scibit);
    destroy_bitmap(tecbit);
    destroy_bitmap(musbit);
    destroy_bitmap(japbit);
    destroy_bitmap(dreamer);
    destroy_bitmap(end);
    destroy_bitmap(buffer);


}
int main()
{
    allegro_init();

    install_keyboard();
    install_timer();
    LOCK_VARIABLE(timecount);
    LOCK_FUNCTION(timeplus);
    install_int_ex(timeplus,MSEC_TO_TIMER(300));


    set_color_depth(16);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0);

    world();

    clear_keybuf();
    return 0;
}
END_OF_MAIN();


Advertisement
Quote:Original post by yurian
making a list of BITMAP* whatever and load_bitmap(whatever, whatever); is very annoying. Is there a better way to do this?


Probably, but for that I would need to know what the images are used for. For example, if they are frames in an animation sequence, you can give them the same name but with a different frame number ("frame1.bmp", "frame2.bmp"). Then you can load all images in one loop by constructing the correct bitmap name based on the loop's index.

Quote:I also want to check each one for error, like not existing. But with fewer lines!


You can create your own bitmap loading function that checks if the bitmap loaded successfully. Something like:

BITMAP* loadBitmap(const std::string &fileName, RGB *pal = NULL) {    BITMAP *bmp = load_bitmap(fileName.c_str(), pal);    if (bmp == NULL) {        // Display a message saying that the bitmap couldn't be loaded        // (including the bitmap's name) and exit the program (or        // handle the error some other way)    }    return bmp;}


Making the check inside the function means that the calling code doesn't need to check it each time it calls loadBitmap(). On the other hand, loadBitmap() might not know how to handle the error properly (maybe you don't want to display a message or exit the program), in which case it should just report the error and do nothing. Probably the most convenient way to do this is with exceptions.

Also, if you use something like boost::shared_ptr, you won't need to call destroy_bitmap() for each bitmap.

Quote:Then, I want to know how to draw the bitmaps without checking if(condition), else if(condition) again and again.


Again, depending on what the bitmaps are used for, you can probably organize them so that you won't need the if checks.

For example, with the bitmaps that are used with croom, you could put them in an array or std::vector, and use croom to call the correct bitmap like so:

draw_sprite(screen,croomBitmaps[croom],0,0);


Quote:my window flickers faster that people run to their bags during lunch! I have a double buffer, am I using it correctly?


I'm not familiar with allegro, but it doesn't seem right to draw each bitmap to both the buffer and the screen, especially given that you draw the buffer on the screen at the end of the loop. I think you should only draw the bitmaps on the buffer.
Indeed, only draw to your buffer, and at the end, draw your buffer to the screen. At the start of a frame, do not clear your screen, only your buffer. Otherwise you defeat the whole purpose of double buffering.
Create-ivity - a game development blog Mouseover for more information.

This topic is closed to new replies.

Advertisement