Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Game slow down from drawing player

Credits go to beoran, Edgar Reynaldo, and Kris Asick for helping out!
This thread is locked; no one can reply to it. rss feed Print
Game slow down from drawing player
Bingocat
Member #15,424
December 2013

I've been making a shooter game and have just added sprites for players. After I added drawing the players, the game has been sorta slow and sometimes takes 5-15 seconds to close after I click X. Also, it uses a lot more CPU when the drawing part is in. When I take the drawing code out, the game is normal speed again. Is there anything wrong with this code? I have to take a region from a sprite sheet, then rotate it. Is there something wrong with the way I did it?

#SelectExpand
1ALLEGRO_BITMAP *buffer = al_create_bitmap(64, 64); 2al_set_target_bitmap(buffer); 3if (players[i].type == 0) 4 al_draw_bitmap_region(playerImage1, player.width * players[i].frame, 0, player.width, player.height, 0, 0, 0); 5else if (players[i].type == 1) 6 al_draw_bitmap_region(playerImage2, player.width * players[i].frame, 0, player.width, player.height, 0, 0, 0); 7 8al_set_target_bitmap(al_get_backbuffer(display)); 9al_draw_rotated_bitmap(buffer, player.width / 2, player.height / 2, players[i].x, players[i].y, players[i].dir, NULL); 10 11double sintheta = sin(players[i].dir); 12double costheta = cos(players[i].dir); 13 14players[i].gunX = players[i].x + (players[i].gunOffX * cos(players[i].dir)) - (players[i].gunOffY * sin(players[i].dir)); 15players[i].gunY = players[i].y + (players[i].gunOffY * cos(players[i].dir)) + (players[i].gunOffX * sin(players[i].dir)); 16 17ALLEGRO_BITMAP *buffer2 = al_create_bitmap(64, 64); 18al_set_target_bitmap(buffer2); 19buffer = NULL; 20al_draw_bitmap_region(weaponImage, 64 * players[i].weapon, 0, 64, 64, 0, 0, 0); 21al_set_target_bitmap(al_get_backbuffer(display)); 22al_draw_rotated_bitmap(buffer2, 32, 32, players[i].gunX, players[i].gunY, players[i].dir, 0);

beoran
Member #12,636
March 2011

You should probably cache (keep) the results of rendering the two buffers. Also you are leaking memory since you don't free your buffers properly. Finally, could you provide the whole program? I mis s sime context that could help to explain more of the slowdown.

Kris Asick
Member #1,424
July 2001

Setting buffer to NULL when you're done with it is leaking memory. You need to first call al_destroy_bitmap() before setting to NULL. All of this lost memory would be the cause of the long shutdown times when you close the program, since Windows is not having to clear all of that lost memory from RAM, video RAM and pagefiles. :P

...I don't THINK that would be the cause of the slowdown during the game though... unless it's not that big a slowdown. If fixing the memory leaks doesn't solve the problem, post some more code to show the actual rendering loop and the parts which pertain to player drawing, as well as pointing out which commands specifically are causing this slowdown.

Although, constantly creating and destroying bitmaps is not good for your framerate in general. You should create your buffers at global scope, initialize them once after the video mode is set, then just clear them to black or overwrite them with new renders any time you need to use them. Also create an atexit() routine so that the buffers are destroyed before Allegro is shut down when you close out the program.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Bingocat
Member #15,424
December 2013

I'm pretty sure that didn't fix it. When I open it, the RAM usage slowly goes up. I stopped it when it got to 25%. Here is the code for drawing. The for loop is for drawing other players when its connected to the server. Not sure exactly what is causing the high RAM usage.

#SelectExpand
1void DrawPlayers(vector <Player> &players, ALLEGRO_BITMAP *playerImage1, ALLEGRO_BITMAP *playerImage2, ALLEGRO_BITMAP *weaponImage, ALLEGRO_FONT *font10, ALLEGRO_DISPLAY *display) { 2 for (unsigned int i = 0; i < players.size(); i++) { 3 ALLEGRO_BITMAP *buffer = al_create_bitmap(64, 64); 4 al_set_target_bitmap(buffer); 5 if (players[i].type == 0) 6 al_draw_bitmap_region(playerImage1, player.width * players[i].frame, 0, player.width, player.height, 0, 0, 0); 7 else if (players[i].type == 1) 8 al_draw_bitmap_region(playerImage2, player.width * players[i].frame, 0, player.width, player.height, 0, 0, 0); 9 10 al_set_target_bitmap(al_get_backbuffer(display)); 11 al_draw_rotated_bitmap(buffer, player.width / 2, player.height / 2, players[i].x, players[i].y, players[i].dir, NULL); 12 13 double sintheta = sin(players[i].dir); 14 double costheta = cos(players[i].dir); 15 16 players[i].gunX = players[i].x + (players[i].gunOffX * cos(players[i].dir)) - (players[i].gunOffY * sin(players[i].dir)); 17 players[i].gunY = players[i].y + (players[i].gunOffY * cos(players[i].dir)) + (players[i].gunOffX * sin(players[i].dir)); 18 19 ALLEGRO_BITMAP *buffer2 = al_create_bitmap(64, 64); 20 al_set_target_bitmap(buffer2); 21 buffer = NULL; 22 al_draw_bitmap_region(weaponImage, 64 * players[i].weapon, 0, 64, 64, 0, 0, 0); 23 al_set_target_bitmap(al_get_backbuffer(display)); 24 al_draw_rotated_bitmap(buffer2, 32, 32, players[i].gunX, players[i].gunY, players[i].dir, 0); 25 26 al_draw_textf(font10, al_map_rgb(255, 255, 255), players[i].x, players[i].y - 33, ALLEGRO_ALIGN_CENTRE, "%s", players[i].name.c_str()); 27 al_draw_filled_rectangle(players[i].x - 15, players[i].y - 20, players[i].x + 15, players[i].y - 18, al_map_rgb(255, 0, 0)); 28 al_draw_filled_rectangle(players[i].x - 15, players[i].y - 20, players[i].x - 15 + players[i].health * 3, players[i].y - 18, al_map_rgb(0, 255, 0)); 29 30 al_destroy_bitmap(buffer); 31 al_destroy_bitmap(buffer2); 32 buffer = NULL; 33 buffer2 = NULL; 34 } 35 36 al_draw_filled_rectangle(5, 5, player.startHealth * 20 + 5, 25, al_map_rgb(255, 0, 0)); 37 al_draw_filled_rectangle(5, 5, player.health * 20 + 5, 25, al_map_rgb(0, 255, 0)); 38 al_draw_rectangle(5, 5, player.startHealth * 20 + 5, 25, al_map_rgb(0, 0, 0), 2); 39 40 ALLEGRO_BITMAP *buffer = al_create_bitmap(64, 64); 41 al_set_target_bitmap(buffer); 42 if (player.type == 0) 43 al_draw_bitmap_region(playerImage1, player.width * player.frame, 0, player.width, player.height, 0, 0, 0); 44 else if (player.type == 1) 45 al_draw_bitmap_region(playerImage2, player.width * player.frame, 0, player.width, player.height, 0, 0, 0); 46 47 al_set_target_bitmap(al_get_backbuffer(display)); 48 49 al_draw_rotated_bitmap(buffer, player.width / 2, player.height / 2, player.x, player.y, player.dir, NULL); 50 51 double sintheta = sin(player.dir); 52 double costheta = cos(player.dir); 53 54 player.gunX = player.x + (player.gunOffX * cos(player.dir)) - (player.gunOffY * sin(player.dir)); 55 player.gunY = player.y + (player.gunOffY * cos(player.dir)) + (player.gunOffX * sin(player.dir)); 56 57 ALLEGRO_BITMAP *buffer2 = al_create_bitmap(64, 64); 58 al_set_target_bitmap(buffer2); 59 al_draw_bitmap_region(weaponImage, 64 * player.weapon, 0, 64, 64, 0, 0, 0); 60 al_set_target_bitmap(al_get_backbuffer(display)); 61 al_draw_rotated_bitmap(buffer2, 32, 32, player.gunX, player.gunY, player.dir, 0); 62 al_destroy_bitmap(buffer); 63 al_destroy_bitmap(buffer2); 64 buffer = NULL; 65 buffer2 = NULL; 66 67}

Edgar Reynaldo
Member #8,592
May 2007
avatar

You've still got a memory leak, because you set buffer = NULL; before calling al_destroy_bitmap(buffer);. Also, you do NOT want to be creating and destroying multiple bitmaps every frame. Store as much of your object as you can in a bitmap ahead of time that is persistent. Pre-draw as much as you can.

Bingocat
Member #15,424
December 2013

Oh oops I missed one of the times setting it to NULL. Everything works fine now thanks for the help.

Go to: