Sign in to follow this  
Schade

bitmap help?

Recommended Posts

Hello i have a background drawn an a animation but the problen is that my player leaves a streak behind him when he moves, iv tryed double buffering but no success. Any help will be appreciated. Thanks

#include <iostream>
#include <allegro.h>

using namespace std;

volatile long speed_counter = 0;

void increment_speed_counter()
{
	speed_counter++;
}
END_OF_FUNCTION(increment_speed_counter);

BITMAP *buffer;
BITMAP *tileset;
BITMAP *frame1;

int x = 0;
int y = 0;



int main(int argc, char *argv[])
{
 
    allegro_init();
	set_window_title("2d Tile");
	set_config_file("game.cfg");
	install_timer();
    install_keyboard();
	
	LOCK_VARIABLE(speed_counter);
	LOCK_FUNCTION(increment_speed_counter);

	install_int_ex(increment_speed_counter,BPS_TO_TIMER(90));

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

	clear_keybuf();
	
	

	buffer = create_bitmap(640,480);
	if (buffer == NULL)
	{
		set_gfx_mode(GFX_TEXT,0,0,0,0);
		allegro_message("Could not create buffer!");
		exit(EXIT_FAILURE);		
	}


	tileset =load_bitmap("tileset1.bmp",NULL);//Size 30*30
	if(tileset == NULL)
	{
		set_gfx_mode(GFX_TEXT,0,0,0,0);
		allegro_message("Could not create background!");
		exit(EXIT_FAILURE);
	}
	
	
	
	frame1 = load_bitmap("down1.bmp",NULL);
	if (frame1 == NULL)
	{
		set_gfx_mode(GFX_TEXT,0,0,0,0);
		allegro_message("Could not create player!");
		exit(EXIT_FAILURE);
	}
	
	 

	int my_player_x = 0;
	int my_player_y = 0;

	int frame_counter = 0;


    while (!key[KEY_ESC])
	{	   
		while(speed_counter > 0)
		{
		    if(key[KEY_D])
			{
				my_player_x++;
			}
			 if(key[KEY_A])
			{
				my_player_x--;
			}
			 if(key[KEY_W])
			{
				my_player_y--;
			}
			 if(key[KEY_S])
			{
				my_player_y++;
			}
			 

		speed_counter--;
		frame_counter++;
		
		if(frame_counter > 240)
		{
			frame_counter = 0;
		}
	  }

		if(frame_counter < 60)
		{
		draw_sprite(tileset,frame1,my_player_x,my_player_y);//Draw the first frame
		}
		else if(frame_counter >= 60 && frame_counter < 120) //Between 1 and 2 seconds
		{
			draw_sprite(tileset, frame1, my_player_x, my_player_y); // Draw the second frame
		}
		else if(frame_counter >= 120 && frame_counter < 180) // If we are between 2 and 3 seconds
		{
			draw_sprite(tileset, frame1, my_player_x, my_player_y); // Draw the first frame again,
			// to acheive better effect
		}
		else // If we are over 3 seconds
		{
			draw_sprite(tileset, frame1, my_player_x, my_player_y); // Draw the last frame.
		}
		
		blit(tileset,screen,0,0,0,0,640,480);// Draw buffer to screen
		blit(frame1, screen,0,0,0,0,0,0);
		
		clear_bitmap(buffer);
		
	}
		destroy_bitmap(buffer);
		destroy_bitmap(tileset);
		destroy_bitmap(frame1);
		allegro_exit();
		return 0; 
}   
END_OF_MAIN(); 


Share this post


Link to post
Share on other sites
To address the problem, you'll need to clear the drawing surface you're using. It looks like you're using the screen bitmap to draw directly onto the screen instead of using the backbuffer, buffer.

So:
1) Change the code so that you're drawing on the buffer, then blitting the buffer onto the screen
2) Or, continue drawing on the screen, and use clear_bitmap(screen);

Share this post


Link to post
Share on other sites
In the code you provided, you draw onto the tileset bitmap, and then draw the tileset bitmap onto the screen. This demonstrates the streaks you described. Next, after you've drawn onto the screen, you clear the buffer bitmap, which isn't being used anywhere else in the code (aka. isn't being blitted to the screen), and therefore, has no effect. Also, take the time to intent your code correctly, so it is easily readable by others and more importantly, you yourself.


// Use constants whenever you use a number in more than one place
// Doing so relieves you of having to remember where the constant
// is used, and having to change the constant in more than one place
const int screenWidth = 640;
const int screenHeight = 480;

// Be sure to check for errors:
if ( set_gfx_mode( GFX_AUTODETECT_WINDOWED, screenWidth, screenHeight, 0, 0) ) {
allegro_message( "Unable to set video mode." );
return -1;
}

BITMAP* buffer = create_bitmap( screenWidth, screenHeight );
if ( !buffer ) {
allegro_message( "Unable to create buffer bitmap." );
return -2;
}

/*

.
.
.

*/


int frameCount = 0;
while ( !key[KEY_ESC] ) {
if ( speed_counter )
continue; // Loop until speed_counter is 0

/* logic here: */
frameCount ++;

// Player movement:
if ( key[KEY_W] ) my_player_y--;
if ( key[KEY_S] ) my_player_y++;
if ( key[KEY_A] ) my_player_x--;
if ( key[KEY_D] ) my_player_x++;

/* drawing here: */
clear_bitmap( buffer ); // Clear the buffer
blit( tileset, buffer, 0, 0, 0, 0, 640, 480); // Draw background onto the buffer
draw_sprite( buffer, frame1, my_player_x, my_player_y ); // Draw player onto the buffer

draw_sprite( screen, buffer, 0, 0 ); // Present the buffer to the screen
}




The code above shows a restructuring of the game, separating game logic and drawing. Drawing on a separate buffer in Allegro serves as double buffering as well as speeding up rendering effects, such as transparency and mixing. Reading from a hardware buffer, the screen, is an expensive operation and should be used sparingly.

Share this post


Link to post
Share on other sites
The specific problem is that you're not redrawing your background on each frame.

Also, if your background consumes the entire visible area, then you don't have to clear the buffer, just redraw the background (unless your background has transparency, which is probably shouldn't.) What's the point of clearing it to a single color if its just going to be covered over again?

Share this post


Link to post
Share on other sites
Good. Now the problem is that you're not double-buffering.

The order things should happen is:

1) Draw background to buffer
2) Draw sprites to buffer
3) Draw buffer to screen

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this