I am currently working on a little Game im making
Now I've made a map via Tiled map Editor and put it on the screen via a al_draw_bitmap_region loop. The map is shown on the screen, yet when i try to scroll the view, it takes ages until it goes forward. This is probably caused by the "large" map (100x100) -> in Allegro 4 i used this method once, too and it worked fine for me (i used to blit everything in the doubleBuffer and blit it on the screen)
Yet I seem to not find a solution for my problem in allegro 5 so far I'm sorry if a board like this has already been open, I didnt found a solution for my problem so far.
I'd be really thankfull for help!
Code:
main.cpp:
#include<allegro5\allegro.h>
#include<allegro5\allegro_native_dialog.h>
#include<allegro5\allegro_primitives.h>
#include<allegro5\allegro_image.h>
#include<allegro5\allegro_font.h>
#include<allegro5\allegro_ttf.h>
#include "global.h"
#include "map.h"
using namespace std;
int main()
{
ALLEGRO_DISPLAY *display = NULL;
al_init_primitives_addon();
al_init_image_addon();
al_init_font_addon();
al_init_ttf_addon();
al_init();
ALLEGRO_FONT *font18 = al_load_font("arial.ttf", 18, 0);
if (!al_init())
{
al_show_native_message_box(NULL,NULL,NULL, "Could not initialize Allegro 5", NULL, NULL);
}
bool keys[] = {false, false, false, false};
enum KEYS{UP,DOWN,LEFT,RIGHT};
ALLEGRO_TIMER *timer = NULL;
bool done=false;
bool reDraw=true;
int xOff =0;
int yOff =0;
int count = 0;
int FPS = 5;
int x=10, y=10;
int moveSpeed = 5;
display = al_create_display(ScreenWidth,ScreenHeight);
if(!display)
al_show_native_message_box(NULL,NULL,NULL, "Could not create Allegro Window", NULL,NULL);
al_set_window_title(display,"Outfall-RPG");
al_install_keyboard();
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
event_queue = al_create_event_queue();
timer = al_create_timer(1.0 / FPS); // 1.0 = Sekunden; / FPS = Frames per Second
al_register_event_source(event_queue, al_get_keyboard_event_source());
al_register_event_source(event_queue, al_get_display_event_source(display));
al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_start_timer(timer);
while(!done)
{
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);
map map;
map.Init();
map.LoadMap("map1.txt");
if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
{
switch(ev.keyboard.keycode)
{
case ALLEGRO_KEY_ESCAPE:
done=true;
break;
case ALLEGRO_KEY_LEFT:
keys[LEFT] = true;
break;
case ALLEGRO_KEY_RIGHT:
keys[RIGHT] = true;
break;
case ALLEGRO_KEY_UP:
keys[UP] = true;
break;
case ALLEGRO_KEY_DOWN:
keys[DOWN] = true;
break;
}
}
else if(ev.type == ALLEGRO_EVENT_KEY_UP)
{
switch(ev.keyboard.keycode)
{
case ALLEGRO_KEY_ESCAPE:
done=true;
break;
case ALLEGRO_KEY_LEFT:
keys[LEFT] = false;
break;
case ALLEGRO_KEY_RIGHT:
keys[RIGHT] = false;
break;
case ALLEGRO_KEY_UP:
keys[UP] = false;
break;
case ALLEGRO_KEY_DOWN:
keys[DOWN] = false;
break;
}
}
else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
{
break;
}
else if(ev.type == ALLEGRO_EVENT_TIMER)
{
xOff -= keys[RIGHT] * 3;
xOff += keys[LEFT] * 3;
yOff -= keys[DOWN] * 3;
yOff += keys[UP] * 3;
reDraw=true;
}
if(reDraw && al_is_event_queue_empty(event_queue))
{
map.Draw(xOff, yOff);
//al_set_target_bitmap(al_get_backbuffer(display));
al_flip_display();
al_clear_to_color(al_map_rgb(0,0,0));
reDraw=false;
}
}
al_destroy_event_queue(event_queue);
al_destroy_timer(timer);
al_destroy_display(display);
return 0;
}
map.h
#include <fstream>
#include <string>
#include <algorithm>
#include <iostream>
#include "global.h"
#include<allegro5\allegro.h>
#include<allegro5\allegro_native_dialog.h>
#include<allegro5\allegro_primitives.h>
using namespace std;
class map
{
public:
map();
~map();
void Init();
void Update();
ALLEGRO_BITMAP *buffer;
void LoadMap(const char *filename);
void Draw(int &xOff, int &yOff);
private:
int loadCounterX, loadCounterY;
int mapSizeX, mapSizeY;
int MapFile[200][200];
int BlockSize;
ALLEGRO_BITMAP *bgSheet;
int mapColumns;
int mapSize;
int y;
int sheetSize;
};
map.cpp:
#include "map.h"
map::map()
{
mapSizeX = 101;
mapSizeY = 101;
y=0;
sheetSize = 13;
}
map::~map()
{
}
void map::Init()
{
loadCounterX = loadCounterY = 0;
map::LoadMap("maptest.txt");
BlockSize = 32;
int MapFile[100][100];
mapColumns = 100;
mapSize = 1000;
}
void map::Update()
{
}
void map::Draw(int &x, int &q)
{
int xOff = x;
int yOff = q;
bgSheet = al_load_bitmap("bilder/testas1.png");
buffer = al_create_bitmap(800,600);
//al_set_target_bitmap(buffer);
for (int i=0; i<mapSizeX; i++)
{
for (int j=0; j<mapSizeY; j++)
{
y=0;
while(MapFile[i][j] > sheetSize)
{
MapFile[i][j] = MapFile[i][j] - sheetSize;
y++;
}
// al_draw_bitmap_region(bgSheet, BlockSize*(MapFile[i][j]-1),BlockSize*y, BlockSize, BlockSize, xOff + BlockSize * (i%mapColumns), yOff + BlockSize * (j%mapColumns),0);
//al_set_target_bitmap(buffer);
al_draw_bitmap_region(bgSheet, BlockSize*(MapFile[i][j]-1),BlockSize*y, BlockSize, BlockSize, xOff + (BlockSize *i), yOff + (BlockSize * j),0);
//al_set_target_backbuffer(display);
// Generell gucken, wie ich schneller BITMAPS abbilden kann!
//ALLEGRO_BITMAP *al_get_backbuffer(ALLEGRO_DISPLAY *display)
// al_set_target_bitmap(display);
// Nur abgebildeter Bereich + Puffer blitten (20x20?)
}
}
}
void map::LoadMap(const char *filename)
{
ifstream openfile(filename);
if (openfile.is_open())
{
string line;
getline(openfile, line);
line.erase(remove(line.begin(),line.end(),' '), line.end());
mapSizeX = 100;
openfile.seekg(0,ios::beg);
//openfile >> mapSizeX >> mapSizeY;
while(!openfile.eof())
{
openfile >> MapFile[loadCounterX][loadCounterY];
loadCounterX ++;
if (loadCounterX >= mapSizeX)
{
loadCounterX = 0;
loadCounterY++;
}
}
mapSizeY = loadCounterY;
} //File is Opend
else
{
//al_show_native_message_box(NULL,NULL,NULL, "Could not load Map", NULL,NULL);
}
}
the tiles im using:
These lines of map::Draw
are suspicious:
bgSheet = al_load_bitmap("bilder/testas1.png");
buffer = al_create_bitmap(800,600);
map::Draw
re-loads your bitmap every time you call it. Not only does this put needless load on your draw loop, but you are leaking the loaded bitmap every time.
Try loading bgSheet
just once in map::Init
and using that same bitmap for every draw loop.
You also allocate and subsequently leak a new buffer
for every draw call. It appears that you aren't using the buffer, so I would remove that al_create_bitmap
call entirely. If your intent was to double-buffer, that generally isn't needed in allegro5.
Also, it looks like map::Init
is called in your game loop, which means you are repeatedly loading the map and probably spending a lot of time waiting on I/O. Call map::Init
once before your game loop begins.