Thread: Allegro Flickering Graphics

  1. #1
    Registered User
    Join Date
    Mar 2010
    Posts
    2

    Allegro Flickering Graphics

    Hello. I am mostly new to programming, I have been learning straight C for about two months and I have been trying to apply what I am learning to simple game programming with Allegro. But, I have hit kind of a snag. I wrote the beginnings of a very basic "game" and I am trying to compartmentalize some of it into functions to start getting things out of main. My problem is that when I call the draw_platform function that should draw a rectangular platform from a set of variables I send it from main, (among other bad things that I will figure out later) the graphics flicker like crazy. I do not have this problem unless I call the draw_platform function. I am using a buffer and I have also tried other suggestions I have seem on this forum like using vsync(). But that didn't work. Here is the code.

    Code:
    #include <allegro.h> 
    
    int main(int argc, char *argv[]) 
    {
        allegro_init(); 
        install_keyboard(); 
        set_color_depth(16);
    	set_gfx_mode(GFX_AUTODETECT, 640,480,0,0); 
    	
    	BITMAP *cursor;
        cursor = load_bitmap( "cursor.bmp", NULL);
        BITMAP *buffer;
        buffer = create_bitmap(640, 480);
    	
    	int playerx = 320;//cursor origin
    	int playery = 240;
    	
    	int moveright_p1 = 1;
    	int lp1_x = 250, rp1_x = 300;
    	
    	int ground_collide = 0;
    	int ceiling_collide = 0; 
    	int right_collide = 0;
    	int left_collide = 0; 
        int player_jump = 0;
        int height = 470;
        int jumpheight = 350;
        
        int draw_platform( int, int, int, int, int, int, int, int, int, int, int, int);
        
        while ( !key[KEY_ESC] )
        {
     
            int left_edge_p1 = lp1_x - 8; 
            
            clear_keybuf();
            acquire_screen();
            
            line( buffer, lp1_x, 380, lp1_x, 400, makecol( 255, 0, 0)); //left 
            line( buffer, rp1_x, 380, rp1_x, 400, makecol( 255, 0, 0)); //right 
            line( buffer, lp1_x, 380, rp1_x, 380, makecol( 255, 0, 0)); //top 
            line( buffer, lp1_x, 400, rp1_x, 400, makecol( 255, 0, 0)); //bottom 
            
            line( buffer, 0, 0, 0, 480, makecol( 255, 0, 0)); //border
            line( buffer, 0, 0, 640, 0, makecol( 255, 0, 0));
            
            line( buffer, 639, 0, 639, 480, makecol( 255, 0, 0)); //player
            line( buffer, 0, 479, 640, 479, makecol( 255, 0, 0));
            
            draw_platform( 100, 100, 50, 50, 620, 20, 1, 1, 0, 255, 0, 0);
            
            masked_blit( cursor, buffer, 0, 0, playerx, playery, 8, 8 ); //buffer
            blit( buffer, screen, 0, 0, 0, 0, 640, 480); 
            
            if( moveright_p1 == 1 ) //platform 1 movement 
            {
                ++lp1_x, ++rp1_x;
                if( rp1_x == 620 ) moveright_p1 = 0;
            }
            else
            {
                --lp1_x, --rp1_x;
                if( lp1_x == 20 ) moveright_p1 = 1;
            }
            
            ground_collide = 0; //ground collide
            if ( (playery == 470) || ( (playery == 371) && (playerx > left_edge_p1) && (playerx < rp1_x) ) ) ground_collide = 1;
            if ( ground_collide == 1 ) 
            {
                  if (playery == 470) height = 0;
                  if ( (playery == 371) && (playerx > left_edge_p1 ) && (playerx < rp1_x) ) //platform 1 ground collision
                  {
                       if (moveright_p1 == 1) ++playerx;
                       else --playerx;
                  } 
                  if (key[KEY_UP])
                  {
                  player_jump = 1;
                  ground_collide = 0;
                  }
            }    
            else ++playery; //gravity
            
            left_collide = 0; //left of object collide
            if ( (playerx == 630) || ( (playerx >= left_edge_p1 ) && (playery < 401) && (playery > 371) && (playerx <= left_edge_p1 + 8) ) ) left_collide = 1; 
            if (left_collide == 1)
            {
                if ( (playerx >= left_edge_p1 ) && (playerx <= left_edge_p1 + 8) && (playery < 401) && (playery > 371) && (moveright_p1 == 0) ) --playerx;
            }
            else
            if ( left_collide == 0 )
            {
               if (key[KEY_RIGHT])
               {
                  playerx+=1;
               }
            }
            
            right_collide = 0; //right of object collide
            if ( (playerx == 1) || ( (playerx >= rp1_x - 1 ) && (playery < 401) && (playery > 371) && (playerx <= rp1_x + 7) ) ) right_collide = 1; 
            if (right_collide == 1)
            {
                if ( (playerx == rp1_x - 1 ) && (playery < 401) && (playery > 371) && (moveright_p1 == 1) ) ++playerx;
            }
            else
            if ( right_collide == 0 )
            {
               if (key[KEY_LEFT])
               {
                  playerx-=1;
               }
            }
              
            if ( playery == 470 ) height = 470; //on ground
            if ( player_jump == 1 ){}
            else if ( (playery == 371) && (playerx > left_edge_p1) && (playerx < rp1_x) ) height = 371; //on platform 1
            
            
            jumpheight = height - 120;
            
            if ( player_jump == 1 ) //jump
            {
                 playery-=2;
                 if ( playery == jumpheight ) player_jump = 0;
            }
            
            ceiling_collide = 0; //left of object collide
            if ( (playery == 1) || ( (playerx >= left_edge_p1 + 1 ) && (playery == 400) && (playerx <= rp1_x - 1) ) ) ceiling_collide = 1; 
            if (ceiling_collide == 1 ) player_jump = 0; 
            
            release_screen();
            clear_bitmap( buffer ); 
            
            rest(10);
            
        }
        
        clear_bitmap( buffer ); 
        clear_bitmap( cursor ); 
        return 0; 
    }
    END_OF_MAIN() 
    
    int draw_platform( int lp_x, int tp_y, int width, int height, int movebound1, int movebound2, int movement, int start_direction, int up_down, int color_r, int color_g, int color_b ) 
    {                //origin x, origin y, width, height, left/bottom, right/top , movement(1 = yes, 0 = stationary), starting direction(1 = right/up, 0 = left/down), movement(1 = up/down, 0 = right/left), colors r, g ,b  
        
            int bp_y = height + tp_y;
            int rp_x = width + lp_x;
            
            BITMAP *buffer;
            buffer = create_bitmap(640, 480);
        
            line( buffer, lp_x, tp_y, lp_x, bp_y, makecol( color_r, color_g, color_b)); //left 
            line( buffer, rp_x, tp_y, rp_x, bp_y, makecol( color_r, color_g, color_b)); //right 
            line( buffer, lp_x, tp_y, rp_x, tp_y, makecol( color_r, color_g, color_b)); //top 
            line( buffer, lp_x, bp_y, rp_x, bp_y, makecol( color_r, color_g, color_b)); //bottom 
            
            if( movement == 1 )
            {
                if( (start_direction == 1) && (up_down == 0) ) //platform 1 movement 
                {
                   ++lp_x, ++rp_x;
                   if( rp_x + width == movebound1 ) start_direction = 0; //620
                }
                if( (start_direction == 0) && (up_down == 0) )
                {
                   --lp_x, --rp_x;
                   if( lp_x  == movebound2 ) start_direction = 1; //20
                }
                if( (start_direction == 1) && (up_down == 1) )  
                {
                   ++tp_y, ++bp_y;
                   if( tp_y == movebound1 ) start_direction = 0; 
                }
                if( (start_direction == 0) && (up_down == 1) )
                {
                   --tp_y, --bp_y;
                   if( bp_y + height == movebound2 ) start_direction = 1; 
                }
            }
            else{} 
            
            blit( buffer, screen, 0, 0, 0, 0, 640, 480); 
            
            return 0;
    }
    This is probably pretty sloppy code, but I am trying to clean it up a bit.
    Any suggestions on how to fix my problem would be wonderful.

    Thanks,
    -Erlex

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    You seem to be leaking the buffer bitmap you create in the draw_platform function. You'll probably want to pass the buffer in as an argument.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Registered User
    Join Date
    Mar 2010
    Posts
    2
    I am sorry, do you think you could explain that a bit?

  4. #4
    Just a pushpin. bernt's Avatar
    Join Date
    May 2009
    Posts
    426
    Here's the problem, as identified by anon:

    In main...
    Code:
    BITMAP *buffer;
    ...
    blit( buffer, screen, 0, 0, 0, 0, 640, 480);
    In draw_platform...
    Code:
    BITMAP *buffer;
    ...
    blit( buffer, screen, 0, 0, 0, 0, 640, 480);
    The BITMAP *buffer variables are local to their respective functions - that is, the buffers in main and draw_platform are separate (but equal). Every time you run through the loop, you're blitting one screen-size bitmap via draw_platform, then blitting another screen-size bitmap on top of that.

    The result is that you see the bitmap created by draw_platform for a split second, followed by the bitmap from main. The two alternate ad infinitum, creating your flicker.

    By passing the buffer as an argument in draw_platform (and not blitting buffer to the screen at the end of that function), you can draw everything to one bitmap and copy that to the screen every frame. Not to mention you avoid allocating a 640x480 bitmap every time you call draw_platform.

    EDIT: and don't forget to call clear_to_color before you draw to your bitmap.
    Last edited by bernt; 03-02-2010 at 08:38 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Game Programming FAQ
    By TechWins in forum Game Programming
    Replies: 5
    Last Post: 09-29-2004, 02:00 AM
  2. graphics flickering problem
    By Benzakhar in forum A Brief History of Cprogramming.com
    Replies: 2
    Last Post: 02-23-2004, 05:15 PM
  3. Question about allegro and other graphics libraries....
    By o0obruceleeo0o in forum Game Programming
    Replies: 2
    Last Post: 06-11-2003, 11:02 PM
  4. Special Allegro Information
    By TechWins in forum Game Programming
    Replies: 12
    Last Post: 08-20-2002, 11:35 PM
  5. Allegro graphics trouble
    By Brian in forum C++ Programming
    Replies: 0
    Last Post: 02-25-2002, 02:36 PM