Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Rendering tilemap making the game slow.

This thread is locked; no one can reply to it. rss feed Print
Rendering tilemap making the game slow.
zero volt
Member #15,793
November 2014

Hello game developers,
I'm having an issue here, after I render all my tiles and I start moving the player the game becomes very slow and I can barely move the player around.

here's my code and the tiles are in the attachments:

#SelectExpand
1#include <stdio.h> 2#include <allegro5/allegro.h> 3#include <allegro5/allegro_image.h> 4 5int main(int argc, char **argv){ 6 7 int width = 960; 8 int height = 576; 9 10 int pos_y = height - 80; 11 int pos_x = (width / 2) - 20; 12 13 int jump = 10; 14 15 bool done = false; 16 bool redraw = false; 17 18 bool isYup = false; 19 bool isYdown = false; 20 bool isXright = false; 21 bool isXleft = false; 22 bool isSpace = false; 23 24 int xOff = 0; 25 int yOff = 0; 26 27 int mapColumns = 15; 28 int mapSize = 135; 29 int tileSize = 64; 30 31 int map[] = { 32 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 34 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 35 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 36 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 37 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 38 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 39 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 41 }; 42 43 // ------------------------------------------------------------- 44 45 ALLEGRO_DISPLAY *display = NULL; 46 ALLEGRO_EVENT_QUEUE *event_queue = NULL; 47 ALLEGRO_TIMER *timer = NULL; 48 ALLEGRO_BITMAP *bgSheet = NULL; 49 ALLEGRO_BITMAP *player; 50 51 // ------------------------------------------------------------- 52 53 al_init(); 54 al_init_image_addon(); 55 al_install_keyboard(); 56 57 // ------------------------------------------------------------- 58 59 bgSheet = al_load_bitmap("background.png"); 60 display = al_create_display(width, height); 61 event_queue = al_create_event_queue(); 62 timer = al_create_timer(1.0 / 60); 63 player = al_create_bitmap(40, 80); 64 65 // ------------------------------------------------------------- 66 67 al_register_event_source(event_queue, al_get_keyboard_event_source()); 68 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 69 al_start_timer(timer); 70 71 al_set_target_bitmap(player); 72 al_clear_to_color(al_map_rgb(255, 255, 255)); 73 al_set_target_bitmap(al_get_backbuffer(display)); 74 75 // ------------------------------------------------------------- 76 77 while(!done) { 78 ALLEGRO_EVENT ev; 79 al_wait_for_event(event_queue, &ev); 80 81 82 if(ev.type == ALLEGRO_EVENT_KEY_DOWN) { 83 switch(ev.keyboard.keycode) { 84 case ALLEGRO_KEY_UP: 85 isYup = true; 86 break; 87 case ALLEGRO_KEY_DOWN: 88 isYdown = true; 89 break; 90 case ALLEGRO_KEY_RIGHT: 91 isXright = true; 92 break; 93 case ALLEGRO_KEY_LEFT: 94 isXleft = true; 95 break; 96 case ALLEGRO_KEY_SPACE: 97 isSpace = true; 98 break; 99 case ALLEGRO_KEY_ESCAPE: 100 done = true; 101 break; 102 } 103 104 } 105 106 else if(ev.type == ALLEGRO_EVENT_KEY_UP) { 107 switch(ev.keyboard.keycode) { 108 case ALLEGRO_KEY_UP: 109 isYup = false; 110 break; 111 case ALLEGRO_KEY_DOWN: 112 isYdown = false; 113 break; 114 case ALLEGRO_KEY_RIGHT: 115 isXright = false; 116 break; 117 case ALLEGRO_KEY_LEFT: 118 isXleft = false; 119 break; 120 case ALLEGRO_KEY_SPACE: 121 isSpace = false; 122 break; 123 } 124 } 125 126 127 else if(ev.type == ALLEGRO_EVENT_TIMER) { 128 if(isYup) 129 pos_y -= 10; 130 if(isYdown) 131 pos_y += 10; 132 if(isXright) 133 pos_x += 10; 134 if(isXleft) 135 pos_x -= 10; 136 137 if(isSpace) 138 pos_y -= jump; 139 else if(pos_y >= height - 80) 140 pos_y = height - 80; 141 else 142 pos_y += jump; 143 144 redraw = true; 145 } 146 147 if(redraw && al_is_event_queue_empty(event_queue)) { 148 redraw = false; 149 150 int i; 151 for(i = 0; i < mapSize; i++) { 152 int x = tileSize * map[i]; 153 int y = 0; 154 int x_width = tileSize; 155 int y_height = tileSize; 156 int x_screen = tileSize * (i % mapColumns); 157 int y_screen = tileSize * (i / mapColumns); 158 159 al_draw_bitmap_region(bgSheet, x, y, x_width, y_height, x_screen, y_screen, 0); 160 161 } 162 163 al_draw_bitmap(player, pos_x, pos_y, 0); 164 al_flip_display(); 165 al_clear_to_color(al_map_rgb(0,0,0)); 166 } 167 168 } 169 170 // ------------------------------------------------------------- 171 172 al_destroy_bitmap(player); 173 al_destroy_bitmap(bgSheet); 174 al_destroy_event_queue(event_queue); 175 al_destroy_timer(timer); 176 al_destroy_display(display); 177 178 // ------------------------------------------------------------- 179 180 return 0; 181}

jmasterx
Member #11,410
October 2009

Could you post your main.cpp file separately? When I copy the code into my editor it comes in as 1 big long line.

zero volt
Member #15,793
November 2014

Oh I see, I'm just gonna attach the file.

LennyLen
Member #5,313
December 2004
avatar

I've attached it as a .cpp file

jmasterx
Member #11,410
October 2009

You need to allocate your bitmap AFTER creating your display:

  display = al_create_display(width, height);
  bgSheet = al_load_bitmap("background.png");

The way you have it causes it to load as a memory bitmap which is very slow.

Also, after profiling, I think you are in Debug build, in release build it still ran fast on my machine. But yeah, I think that is your issue.

zero volt
Member #15,793
November 2014

Yeah, it works perfectly now, thank you.
umm.. I'm using this option : -lallegro-5.0.10-md is that the debug build ?
and I want to understand what is the difference between putting it at first or at second ? I mean why would it create it as a memory bitmap if it was at first line ?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

zero volt said:

-lallegro-5.0.10-md is that the debug build ?

No, that is the dynamic c-runtime release build. It depends on your libc++ and libc dlls.

Quote:

and I want to understand what is the difference between putting it at first or at second ? I mean why would it create it as a memory bitmap if it was at first line ?

Because you haven't created a display yet, there is nothing to attach the bitmap to for a device context, so it can't be a video bitmap yet, so it is a memory bitmap. You have to call al_convert_bitmaps after creating the display to 'fix' this. Or just create all your bitmaps after the display.

zero volt
Member #15,793
November 2014

While I'm at it, I want to ask one more question:

I added this those lines starting from the if statement to check for collision detection only for the rocks but I couldn't figure out why it's not working.

      int i;
      for(i = 0; i < mapSize; i++) {
        int x = tileSize * map[i];
        int y = 0;
        int x_width = tileSize;
        int y_height = tileSize;
        int x_screen = tileSize * (i % mapColumns);
        int y_screen = tileSize * (i / mapColumns) + 30;

        al_draw_bitmap_region(bgSheet, x, y, x_width, y_height, x_screen, y_screen, 0);


        if((pos_y + 80) >= y_screen && map[i] == 0)
          pos_y = y_screen - 80;

jmasterx
Member #11,410
October 2009

What exactly do you want your collision code to do?

zero volt
Member #15,793
November 2014

Sorry for posting late, I thought the thread was closed!, becasue I couldn't submit a new post, I believe one the rules is you can only submit one post at a time?

Okay so, here's what I want:
When the player pass through a rock which has the value 0 in the array, then the code will stop him. so there's collision detection between the player and the rocks.

I created another for while loop, and so in every iteration I will check for every rock if it has collided in any way with the player.

here's my code so far, I stayed up long last night trying to do it! but it doesn't make sense:

#SelectExpand
1for(i = 0; i < mapSize; i++) { 2 int tile_x = tileSize * (i % mapColumns); 3 int tile_y = tileSize * (i / mapColumns); 4 int tile_width = tile_x + 64; 5 int tile_height = tile_y + 64; 6 7 if(map[i] == 0) { 8 9 if(pos_y < tile_height && pos_y + 80 > tile_height && (pos_x + 40 < tile_width && pos_x > tile_x) || 10 (pos_y < tile_height && pos_y + 80 > tile_height && (pos_x + 40 < tile_width && pos_x + 40 > tile_x) || 11 (pos_y < tile_height && pos_y + 80 > tile_height && (pos_x > tile_x && pos_x < tile_width)))) 12 { 13 pos_y = tile_height; 14 break; 15 16 } 17 18 if(((pos_y + 80) > tile_y) && (pos_y < tile_y) 19 && (pos_x + 40) < tile_width && pos_x > tile_x) { 20 pos_y = tile_y - 80; 21 break; 22 23 } 24 } 25 }

jmasterx
Member #11,410
October 2009

There are lots of interesting articles on 2D tile collision:
http://higherorderfun.com/blog/2012/05/20/the-guide-to-implementing-2d-platformers/
http://www.parallelrealities.co.uk/2011/10/intermediate-game-tutorial-4-tile-based.html

Maybe base your collision on that and ask about specific issues you run into.

In general, you want to completely avoid things like ypos + 80 - 40 / 20 - 32 + 9...... it gets messy very fast ;)

Instead you want to make a structure for a rectangle, and build functions that can check if your player's rectangle is inside a tile of value 0, if it is, get him out of there.

Generally you want your player to have a velocity vector (how far does he go in 1 frame and in what direction), that way, when he hits something, you can just move back that amount.

More precise physics will calculate the penetration amount and apply a linear impulse opposite the penetration amount, but that's for more advanced stuff like car physics.

Go to: