Thread: problem in allegro with sprite leaving trail

  1. #1
    Unregistered Leeman_s's Avatar
    Join Date
    Oct 2001
    Posts
    753

    problem in allegro with sprite leaving trail

    I am moving a ship around the screen but it leaves a trail. To get rid of the trail I clear the buffer. If I clear the buffer I get a bad flicker. I know I've seen good allegro games that don't have flicker, anyone have an idea of what to do? Oh and I have implemented triple buffering.

    Here is the code:
    Code:
    #include <allegro.h> // You must include the Allegro Header file
    
    void increase_speed();
    void init_all();
    void clean_all();
    void clean_bitmap(BITMAP* page);
    void flip_page(BITMAP* page1, BITMAP* page2, BITMAP* active_page);
    
    volatile long speed_counter = 0;//A long integer which will store the value of the speed counter.
    
    int main(int argc, char *argv[])
    {
    	allegro_init(); // Initialize Allegro
    	install_keyboard(); // Initialize keyboard routines
    	set_color_depth(16); // Set the color depth						
    	set_gfx_mode(GFX_AUTODETECT, 640,480,0,0); // Change our graphics mode to 640x480
    
    	install_timer();
    	LOCK_VARIABLE(speed_counter);
    	LOCK_FUNCTION(increase_speed);
    	install_int_ex(increase_speed, BPS_TO_TIMER(60));//Set our BPS
    
    	BITMAP *ship, *page1, *page2, *active_page, *background; 
    
    	page1      = create_video_bitmap(SCREEN_W, SCREEN_H);
        page2      = create_video_bitmap(SCREEN_W, SCREEN_H);
    	background = load_bitmap("lee.bmp", NULL);
        ship       = load_bitmap("ship.bmp", NULL); // Load our picture
    
        clean_bitmap(page1);
        clean_bitmap(page2);
    
        active_page    = page1;
    
    	int x          = 0;
    	int y          = 0;
    	bool validness = true;
    
    /*///////////////////////////////////////////////////////////////////////////////////*/
    /*////// Name: Main Loop ////////////////////////////////////////////////////////////*/
    /*///////////////////////////////////////////////////////////////////////////////////*/
    
    	while(!key[KEY_ESC])
    	{
    		while(speed_counter > 0)
    		{
    		    validness = true;
    
    		    if(key[KEY_RIGHT])
    		    {
    			    x++;// Moving right so up the X coordinate by 1
    			    if(x > 558)
    		    	{
    		    		validness = false;
    			    	x--;
    			    }
    		    }
    		    else if(key[KEY_LEFT])// Ditto' - only for left key
    		    {
    			    x--;// Moving left, so lower the X coordinate by 1
    			    if(x < 0)
    			    {
    				    validness = false;
    				    x++;
    			    }
    		    }
    		    else if(key[KEY_UP])// If the user hits the up key, change the picture's Y coordinate
    		    {
    			    y--;// Moving up, so lower the Y coordinate by 1
    			    if(y < 0)
    			    {
    				    validness = false;
    				    y++;
    			    }
    		    }
    		    else if(key[KEY_DOWN])// Ditto' - only for down
    		    {
    			    y++;// Moving down, so up the Y coordinate by 1
    			    if(y > 338)
    			    {
    				    validness = false;
    				    y--;
    			    }
    		    }
    			speed_counter--;
    		};
    		
    		if(validness == true)
    		{
    		    acquire_screen();// Get the screen
    
    		    masked_blit(ship, active_page, 0,0, x, y,640,480);
                show_video_bitmap(active_page);
    
    		    release_screen();// Release it
    
    			flip_page(page1, page2, active_page);
    		}
    	};
    
    
    	destroy_bitmap(ship);//Release the bitmap data
    	destroy_bitmap(background);
    
    
    	return(0);// Exit with no errors
    }
    END_OF_MAIN(); // This must be called right after the closing bracket of your MAIN function.
                   // It is Allegro specific.
    void increase_speed()
    {
    	speed_counter++;
    }
    END_OF_FUNCTION(increase_speed);
    
    void clean_bitmap(BITMAP* page)
    {
    	acquire_bitmap(page);
        clear_bitmap(page);
        release_bitmap(page);
    }
    END_OF_FUNCTION(clear_bitmap);
    
    void flip_page(BITMAP* page1, BITMAP* page2, BITMAP* active_page)
    {
    	if (active_page == page1)
            active_page = page2;
        else
            active_page = page1;
    }
    END_OF_FUNCTION(flip_page);
    Last edited by Leeman_s; 09-12-2002 at 06:48 PM.

  2. #2
    I lurk
    Join Date
    Aug 2002
    Posts
    1,361
    You must have some idea of where the error is taking place? Narrow down your code to the section suspected of causing this behavior and post it... or even bold or color it amongst your other code. You'll be more likely to receive an answer this way...

    Anyway, what it seems like is you're clearing and redrawing the entire screen when only a small portion needs to be redrawn. I haven't worked specifically with allegro, but is there a function for "invalidating" a certain section of the screen and redrawing only that?

  3. #3
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    I have no experience with Allegro, so I won't bother looking through your code... probably just confuse me. But it sounds like you're erasing the front-buffer as opposed to the back buffer; or maybe you're erasing the entire back buffer and only sometimes redrawing the whole thing...
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  4. #4
    Unregistered Leeman_s's Avatar
    Join Date
    Oct 2001
    Posts
    753
    there is no error in my code, it flickers because if you dont clear the buffer, you will have a trail. when you clear the buffer its rapidly changing between black from clearing and then color where my bitmap goes.

  5. #5
    I lurk
    Join Date
    Aug 2002
    Posts
    1,361
    there is no error in my code, it flickers because if you dont clear the buffer, you will have a trail. when you clear the buffer its rapidly changing between black from clearing and then color where my bitmap goes.
    *Sigh* Yes, there is an error, a logical error. You're doing something wrong... you're getting unexpected behavior. Notice the italics? This is to get you to look at the word and really think about what I mean by it.

  6. #6
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    Originally posted by Leeman_s
    there is no error in my code
    so sure? i found one. look harder.
    hello, internet!

  7. #7
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    moi: Sorry, let me rephrase that. Of course there was no compiler or linker error, as you doubtlessly meant; but I found a logical error, like eibro just said in his post.

    Hunter2:
    its rapidly changing between black from clearing and then color where my bitmap goes
    Have an offscreen buffer where you draw your stuff; you clear that and redraw onto it, and when everything's drawn onto the offscreen buffer, you copy it to the front buffer overwriting the previous image; thus, you eliminate the flicker from erasing the front buffer (the screen).

    **EDIT**
    In case you already understood perfectly well what I just said, you can forget it all
    Last edited by Hunter2; 09-12-2002 at 07:33 PM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  8. #8
    Blank
    Join Date
    Aug 2001
    Posts
    1,034
    I'm not exactly sure how well your code runs
    because I don't have allegro setup but ...

    You have to blit the background onto
    active_page, you don't need the validness check
    either. Just draw the background and ship each time.

    Get the code to work first but another thing you might want
    to try is some code that looks like this
    Code:
    BITMAP* load_graphic(const char* filename)
    {
          BITMAP* bmp;
          int w, h;
    
          BITMAP* tmp = load_bitmap(filename, NULL); 
          if (tmp == NULL)
              error();
    
          w = tmp->w;
          h = tmp->h;
          bmp = create_video_bmp(w, h);
          if (bmp == NULL)
                 bmp = create_system_bmp(w, h);
     
          blit(tmp, bmp, 0, 0, w,  h);
          destroy_bitmap(tmp);
          return bmp;
    }
    If I understand the docs right. For best possible speed try to create all of your sprites and the background in video memory this way. It's possible you could run out out of video ram, so then use create_system_bmp.
    Last edited by Nick; 09-12-2002 at 07:37 PM.

  9. #9
    Blank
    Join Date
    Aug 2001
    Posts
    1,034
    Maybe I'll post back with some code since I've been
    meaning to install a compiler on this machine.

  10. #10
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    Originally posted by Hunter2
    moi: Sorry, let me rephrase that. Of course there was no compiler or linker error, as you doubtlessly meant; but I found a logical error, like eibro just said in his post.

    nah, i didn't go hunting for missing semicolons or anything. also, its late at night so i might be wrong. but here is the error i mentioned in my post above:

    active_page is set to page1. and it will be correctly blitted to and shown and everything. but the flip_page () function doesn't actually flip the page. i won't post why here, because hunter i'm sure you know (unless i'm just off the deep end here), and leeman you should try to figure out for yourself why it doesnt. so, all the drawing is being done on page1 even when its visible hence the flickering.
    hello, internet!

  11. #11
    Blank
    Join Date
    Aug 2001
    Posts
    1,034
    That's a case for making those variables global
    You arn't modifing active_page.

  12. #12
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    Originally posted by Nick
    That's a case for making those variables global
    You arn't modifing active_page.
    akk no!!!!!!!!!!!!!!!!!!!!!!!!!! global variables are baaaaad practice.

    just do the much same thing you did with your rudimentary

    void swap(int *a, int *b)

    function that is in many beginners textbooks.

    Code:
    // prototype
    void flip_page(BITMAP *page1, BITMAP *page2, BITMAP **active_page);
    
    // invocation of function
    flip_page(page1, page2, &active_page);
    
    // function
    void flip_page(BITMAP *page1, BITMAP *page2, BITMAP **active_page)
    {
    	if (*active_page == page1)
            *active_page = page2;
        else
            *active_page = page1;
    }
    note that C++ also allows you to pass by refrence or something like that (which this C and C++ compatible function emulates with pointers), but i don't know any C++ so you're on your own there.
    hello, internet!

  13. #13
    Blank
    Join Date
    Aug 2001
    Posts
    1,034
    If anything he should make a surface class and then abstract
    the whole concept of flipping a page. This will allow him to change
    between double buffering, hardware page flipping, tripple buffering page flipping easily.

    I've never seen a large game done in c without some globals but I guess there's always a first.

  14. #14
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    Originally posted by Nick
    If anything he should make a surface class and then abstract
    the whole concept of flipping a page. This will allow him to change
    between double buffering, hardware page flipping, tripple buffering page flipping easily.

    I've never seen a large game done in c without some globals but I guess there's always a first.
    i didn't say globals were satan-spawn, but there's no reason to throw in a new one every 5 seconds when something else could do the job just fine.
    hello, internet!

  15. #15
    Unregistered Leeman_s's Avatar
    Join Date
    Oct 2001
    Posts
    753
    well i kept the function the same but added an extra buffer. it sure reduces flicker, not sure why if my flip func doesnt work....anyone care to comment/help?
    Code:
    #include <allegro.h> // You must include the Allegro Header file
    
    void increase_speed();
    void init_all();
    void clean_all();
    void clean_bitmap(BITMAP* page);
    void flip_page(BITMAP* page1, BITMAP* page2, BITMAP* page3, BITMAP* active_page);
    
    volatile long speed_counter = 0;//A long integer which will store the value of the speed counter.
    
    int main(int argc, char *argv[])
    {
    	allegro_init(); // Initialize Allegro
    	install_keyboard(); // Initialize keyboard routines
    	set_color_depth(16); // Set the color depth						
    	set_gfx_mode(GFX_AUTODETECT, 640,480,0,0); // Change our graphics mode to 640x480
    
    	install_timer();
    	LOCK_VARIABLE(speed_counter);
    	LOCK_FUNCTION(increase_speed);
    	install_int_ex(increase_speed, BPS_TO_TIMER(150));//Set our BPS
    
    	BITMAP *ship, *page1, *page2, *page3, *active_page, *background, *bullet; 
    
    	page1      = create_video_bitmap(SCREEN_W, SCREEN_H);
        page2      = create_video_bitmap(SCREEN_W, SCREEN_H);
        page3      = create_video_bitmap(SCREEN_W, SCREEN_H);
    	background = load_bitmap("lee.bmp", NULL);
        ship       = load_bitmap("ship.bmp", NULL); // Load our picture
    
        clean_bitmap(page1);
        clean_bitmap(page2);
    	clean_bitmap(page3);
    
        active_page    = page1;
    
    	int x          = 0;
    	int y          = 0;
    	bool validness = true;
    
    /*///////////////////////////////////////////////////////////////////////////////////*/
    /*////// Name: Main Loop ////////////////////////////////////////////////////////////*/
    /*///////////////////////////////////////////////////////////////////////////////////*/
    
    	while(!key[KEY_ESC])
    	{
    		while(speed_counter > 0)
    		{
    		    validness = true;
    
    			if(key[KEY_UP] && key[KEY_RIGHT])
    			{
    				y--;// Moving down, so up the Y coordinate by 1
    				x++;
    			    if(y < 0)
    			    {
    				    y++;
    			    }
    				if(x > 604)
    				{
    					x--;
    				}
    			}
    			else if(key[KEY_UP] && key[KEY_LEFT])
    			{
    				y--;// Moving down, so up the Y coordinate by 1
    				x--;
    			    if(y < 0)
    			    {
    				    y++;
    			    }
    				if(x < 0)
    				{
    					x++;
    				}
    			}
    			else if(key[KEY_DOWN] && key[KEY_LEFT])
    			{
    				y++;// Moving down, so up the Y coordinate by 1
    				x--;
    			    if(y > 440)
    			    {
    				    y--;
    			    }
    				if(x < 0)
    				{
    					x++;
    				}
    			}
    			else if(key[KEY_DOWN] && key[KEY_RIGHT])
    			{
    				y++;// Moving down, so up the Y coordinate by 1
    				x++;
    			    if(y > 440)
    			    {
    				    y--;
    			    }
    				if(x > 604)
    				{
    					x--;
    				}
    			}
    		    else if(key[KEY_RIGHT])
    		    {
    			    x++;// Moving right so up the X coordinate by 1
    			    if(x > 604)
    		    	{
    		    		validness = false;
    			    	x--;
    			    }
    		    }
    		    else if(key[KEY_LEFT])// Ditto' - only for left key
    		    {
    			    x--;// Moving left, so lower the X coordinate by 1
    			    if(x < 0)
    			    {
    				    validness = false;
    				    x++;
    			    }
    		    }
    		    else if(key[KEY_UP])// If the user hits the up key, change the picture's Y coordinate
    		    {
    			    y--;// Moving up, so lower the Y coordinate by 1
    			    if(y < 0)
    			    {
    				    validness = false;
    				    y++;
    			    }
    		    }
    		    else if(key[KEY_DOWN])// Ditto' - only for down
    		    {
    			    y++;// Moving down, so up the Y coordinate by 1
    			    if(y > 440)
    			    {
    				    validness = false;
    				    y--;
    			    }
    		    }
    
    			speed_counter--;
    		};
    		
    		if(validness == true)
    		{
    		    acquire_screen();// Get the screen
    
    			clean_bitmap(page1);
    			clean_bitmap(page2);
    			clean_bitmap(page3);
    
    		    masked_blit(ship, active_page, 0,0, x, y,640,480);
                show_video_bitmap(active_page);
    
    		    release_screen();// Release it
    
    			flip_page(page1, page2, page3, active_page);
    		}
    	};
    
    
    	destroy_bitmap(ship);//Release the bitmap data
    	destroy_bitmap(background);
    	destroy_bitmap(page1);
    	destroy_bitmap(page2);
    	destroy_bitmap(page3);
    	destroy_bitmap(bullet);
    
    	return(0);// Exit with no errors
    }
    END_OF_MAIN(); // This must be called right after the closing bracket of your MAIN function.
                   // It is Allegro specific.
    void increase_speed()
    {
    	speed_counter++;
    }
    END_OF_FUNCTION(increase_speed);
    
    void clean_bitmap(BITMAP* page)
    {
    	acquire_bitmap(page);
        clear_bitmap(page);
        release_bitmap(page);
    }
    END_OF_FUNCTION(clear_bitmap);
    
    void flip_page(BITMAP* page1, BITMAP* page2, BITMAP* page3, BITMAP* active_page)
    {
    	if(active_page == page1)
            active_page = page2;
        if(active_page == page2)
            active_page = page3;
    	if(active_page == page3)
    		active_page = page1;
    }
    END_OF_FUNCTION(flip_page);

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem declaring struct in allegro
    By bobish in forum Game Programming
    Replies: 7
    Last Post: 03-08-2002, 09:26 AM
  2. Allegro problem...
    By QuestionC in forum C Programming
    Replies: 1
    Last Post: 12-31-2001, 02:04 AM
  3. Problem with Allegro
    By CeeCee in forum Game Programming
    Replies: 3
    Last Post: 12-24-2001, 07:59 PM
  4. problem with output
    By Garfield in forum C Programming
    Replies: 2
    Last Post: 11-18-2001, 08:34 PM
  5. Allegro Problem
    By Xterria in forum Game Programming
    Replies: 6
    Last Post: 08-30-2001, 02:32 PM