bitmap help?

Started by
9 comments, last by Ravyne 14 years ago
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(); 


Advertisement
Opps sorry im using allegro with c++ :)
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);
ok do you mean change where i have blit or the draw_sprite.
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 placeconst 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.
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?

throw table_exception("(? ???)? ? ???");

im sorry just new to allegro. theres not too many tutorials for it an the forums is not so active. I still cant get it too work now its just a black screen.
Ok so i fixed it an now i got the background an my sprite but now i get flicker on the sprite. Should i blit it for it to stop flickering?
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

throw table_exception("(? ???)? ? ???");

ok so it should go something like this

draw_sprite(tileset,buffer, 640,480);draw_sprite(frame1,buffer, my_player_x, my_player_y);draw_sprite(buffer,screen,0,0);

This topic is closed to new replies.

Advertisement