I'm having a weird problem I know I shouldn't be running into with my program ... but I have basically a game engine that displays a character and a screen full of 32x32 tiles of 'grass'.(These are place holder graphics for the real game ... no point in getting a bunch done when the engine doesn't even work) I can draw the character and move him around fine, but when I start drawing the tiles(even just one row slows it down considerably) it gets HORRIBLE ... I don't understand what could be going wrong here and would like some help.
Main program cpp file.
| 1 | #include <allegro.h> |
| 2 | #include <string> |
| 3 | #include "MapEngine.h" |
| 4 | //************************************************************************* |
| 5 | //Initialization |
| 6 | |
| 7 | BITMAP *buffer; |
| 8 | bool updateMap; |
| 9 | BITMAP *Test; |
| 10 | int x = 0; |
| 11 | int y = 0; |
| 12 | int xBoundry = 640; |
| 13 | int yBoundry = 480; |
| 14 | //************************************************************************* |
| 15 | //Timer |
| 16 | |
| 17 | volatile long speed_counter=0; |
| 18 | void increment_speed_counter() |
| 19 | { |
| 20 | speed_counter++; |
| 21 | } |
| 22 | END_OF_FUNCTION(increment_speed_counter); |
| 23 | |
| 24 | //************************************************************************* |
| 25 | //Engine |
| 26 | |
| 27 | void engine(void) |
| 28 | { |
| 29 | allegro_init(); |
| 30 | install_keyboard(); |
| 31 | install_timer(); |
| 32 | install_mouse(); |
| 33 | set_mouse_speed(1,1); |
| 34 | set_mouse_range(0,0, xBoundry, yBoundry); |
| 35 | install_sound(DIGI_AUTODETECT,MIDI_AUTODETECT,0); |
| 36 | LOCK_VARIABLE(speed_counter); |
| 37 | LOCK_FUNCTION(increment_speed_counter); |
| 38 | install_int_ex(increment_speed_counter, BPS_TO_TIMER(60)); |
| 39 | set_color_depth(16); |
| 40 | if (set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0) != 0) |
| 41 | { |
| 42 | allegro_exit(); |
| 43 | exit(1); |
| 44 | } |
| 45 | buffer = create_bitmap(640,480); |
| 46 | clear_bitmap(buffer); |
| 47 | Test = load_bitmap("Images\\Test.bmp", desktop_palette); |
| 48 | loadMap("Test.map"); |
| 49 | loadTiles(); |
| 50 | } |
| 51 | //************************************************************************* |
| 52 | //Program for calling necessary functions |
| 53 | |
| 54 | void program(void) |
| 55 | { |
| 56 | if(key[KEY_LEFT] && x > 0) |
| 57 | { |
| 58 | x--; |
| 59 | updateMap = true; |
| 60 | } |
| 61 | else if(key[KEY_RIGHT] && x < xBoundry - 16) |
| 62 | { |
| 63 | x++; |
| 64 | updateMap = true; |
| 65 | } |
| 66 | if(key[KEY_DOWN] && y < yBoundry - 16) |
| 67 | { |
| 68 | y++; |
| 69 | updateMap = true; |
| 70 | } |
| 71 | else if(key[KEY_UP] && y > 0) |
| 72 | { |
| 73 | y--; |
| 74 | updateMap = true; |
| 75 | } |
| 76 | } |
| 77 | //************************************************************************* |
| 78 | //Display |
| 79 | |
| 80 | void display(void) |
| 81 | { |
| 82 | draw_sprite(buffer, drawMap(0,0,0,0), 0, 0); |
| 83 | draw_sprite(buffer, Test, x, y); |
| 84 | draw_sprite(screen,buffer,0,0); |
| 85 | clear_bitmap(buffer); |
| 86 | } |
| 87 | |
| 88 | //************************************************************************* |
| 89 | //Main Program |
| 90 | |
| 91 | int main(int argc, char *argv[]) |
| 92 | { |
| 93 | engine(); |
| 94 | |
| 95 | while(!key[KEY_ESC]) |
| 96 | { |
| 97 | while(speed_counter>0) |
| 98 | { |
| 99 | program(); |
| 100 | speed_counter--; |
| 101 | } |
| 102 | if(updateMap) |
| 103 | { |
| 104 | display(); |
| 105 | updateMap = false; |
| 106 | } |
| 107 | } |
| 108 | if(key[KEY_ESC]) |
| 109 | { |
| 110 | destroy_bitmap(Test); |
| 111 | destroy_bitmap(buffer); |
| 112 | } |
| 113 | |
| 114 | return 0; |
| 115 | } |
| 116 | END_OF_MAIN() |
Header file for MapEngine.
#ifndef MapEngine_h_included #define MapEngine_h_included int loadMap(std::string s); int loadTiles(void); BITMAP* drawMap(int x, int y, int a, int b); #endif
Cpp file for MapEngine
| 1 | #include <allegro.h> |
| 2 | #include <fstream> |
| 3 | #include <string> |
| 4 | using namespace std; |
| 5 | |
| 6 | BITMAP *buffer1; |
| 7 | BITMAP *Tile; |
| 8 | int length; |
| 9 | int height; |
| 10 | int tileX = 0; |
| 11 | int tileY = 0; |
| 12 | int map[1000][1000]; |
| 13 | string tiles[1000]; |
| 14 | int xBoundry1 = 640; |
| 15 | int yBoundry1 = 480; |
| 16 | |
| 17 | int loadMap(string s) |
| 18 | { |
| 19 | ifstream fileIn(("Map\\" + s).c_str()); |
| 20 | fileIn >> length; |
| 21 | fileIn >> height; |
| 22 | map[length][height]; // x, y |
| 23 | int x = 0; |
| 24 | int y = 0; |
| 25 | while (x < length - 1) |
| 26 | { |
| 27 | while (y < height - 1) |
| 28 | { |
| 29 | fileIn >> map[x][y]; |
| 30 | y++; |
| 31 | } |
| 32 | x++; |
| 33 | y = 0; |
| 34 | } |
| 35 | fileIn.close(); |
| 36 | buffer1 = create_bitmap(640,480); |
| 37 | return 0; |
| 38 | } |
| 39 | |
| 40 | int loadTiles(void) //Sprite number |
| 41 | { |
| 42 | ifstream fileIn("Tiles\\tiles.shl"); |
| 43 | int y = 0; |
| 44 | fileIn >> y; |
| 45 | int i = 0; |
| 46 | tiles[y]; |
| 47 | while (i < y) |
| 48 | { |
| 49 | fileIn >> tiles<i>; |
| 50 | tiles<i> = "Tiles\\" + tiles<i>; |
| 51 | i++; |
| 52 | } |
| 53 | fileIn.close(); |
| 54 | return 0; |
| 55 | } |
| 56 | |
| 57 | string getTile(int x) |
| 58 | { |
| 59 | string s = tiles[x] + ".bmp"; |
| 60 | return s; |
| 61 | } |
| 62 | |
| 63 | BITMAP* drawMap(int x, int y, int a, int b) //x is leftmost tile, y is upper most tile |
| 64 | //(a,b) is start pixil for [x][y] |
| 65 | { |
| 66 | int origA = a, origB = b; |
| 67 | clear_bitmap(buffer1); |
| 68 | while(a <= xBoundry1 + 32) |
| 69 | { |
| 70 | while (b <= yBoundry1 + 32) |
| 71 | { |
| 72 | Tile = load_bitmap(getTile(map[x][y]).c_str(), desktop_palette); |
| 73 | draw_sprite(buffer1, Tile, a, b); |
| 74 | b += 32; |
| 75 | } |
| 76 | a += 32; |
| 77 | b = origB; |
| 78 | } |
| 79 | return buffer1; |
| 80 | } |
and for the map file right now I'm using 50x50 of grass, which it should only be displaying around half of that I think.
Tile = load_bitmap(getTile(map[x][y]).c_str(), desktop_palette);
draw_sprite(buffer1, Tile, a, b);
What you should be doing here is drawing tiles from a pre-loaded array (or perhaps a vector if you're using C++) or tilemap. Loading from disk is much slower than loading from memory. So you need a function to load all the tiles into memory at the start of your game or level, storing them in a global array or vector. Then draw them directly.
[edit]
Don't forget to destroy the bitmaps where you're done with them. The code you have now will cause your computer to run out of memory in a hurry.
because you have Tile = load_bitmap(getTile(map[x][y]).c_str(), desktop_palette); in MapEngine.drawMap
Load the image once in MapEngine.loadMap
[edit]
Damn - beaten.
[/edit]
Note also that desktop_palette is considered read-only. Don't pass it to load_bitmap. Supply your own PALETTE structure to receive the palette.
And don't copy your buffer to the screen with draw_sprite() - use blit().