Allegro 5:平铺地图 -> 滚动滞后
Allegro 5: Tile Maps -> Scroll lag
我目前正在制作一个小游戏
现在我已经通过 Tiled 地图编辑器制作了一张地图,并通过 al_draw_bitmap_region 循环将其显示在屏幕上。
地图显示在屏幕上,但是当我尝试滚动视图时,它需要很长时间才能前进。
这可能是由 "large" 地图 (100x100) 引起的
-> 在 Allegro 4 中,我也使用过一次这种方法,它对我来说效果很好(我曾经将 doubleBuffer 中的所有内容 blit 并在屏幕上 blit 它)
但到目前为止,我似乎还没有在 allegro 5 中找到解决问题的方法
很抱歉,如果这样的板已经打开,我到目前为止还没有找到解决问题的方法。
非常感谢您的帮助!
代码:
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);
}
}
我正在使用的瓷砖:
map::Draw
的这些行是可疑的:
bgSheet = al_load_bitmap("bilder/testas1.png");
buffer = al_create_bitmap(800,600);
map::Draw
每次调用时都会重新加载位图。这不仅会给绘制循环带来不必要的负载,而且每次都会泄漏加载的位图。
尝试在 map::Init
中仅加载一次 bgSheet
并为每个绘制循环使用相同的位图。
您还为每个绘图调用分配并随后泄漏一个新的 buffer
。看来您没有使用缓冲区,所以我会完全删除 al_create_bitmap
调用。如果您的意图是双缓冲,那么在 allegro5 中通常不需要。
此外,您的游戏循环中似乎调用了 map::Init
,这意味着您正在重复加载地图并且可能会花费大量时间等待 I/O。在游戏循环开始之前调用 map::Init
一次。
确实是map.init因为重新加载地图文件导致延迟!
谢谢!
我目前正在制作一个小游戏
现在我已经通过 Tiled 地图编辑器制作了一张地图,并通过 al_draw_bitmap_region 循环将其显示在屏幕上。 地图显示在屏幕上,但是当我尝试滚动视图时,它需要很长时间才能前进。 这可能是由 "large" 地图 (100x100) 引起的 -> 在 Allegro 4 中,我也使用过一次这种方法,它对我来说效果很好(我曾经将 doubleBuffer 中的所有内容 blit 并在屏幕上 blit 它)
但到目前为止,我似乎还没有在 allegro 5 中找到解决问题的方法 很抱歉,如果这样的板已经打开,我到目前为止还没有找到解决问题的方法。
非常感谢您的帮助!
代码:
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);
}
}
我正在使用的瓷砖:
map::Draw
的这些行是可疑的:
bgSheet = al_load_bitmap("bilder/testas1.png");
buffer = al_create_bitmap(800,600);
map::Draw
每次调用时都会重新加载位图。这不仅会给绘制循环带来不必要的负载,而且每次都会泄漏加载的位图。
尝试在 map::Init
中仅加载一次 bgSheet
并为每个绘制循环使用相同的位图。
您还为每个绘图调用分配并随后泄漏一个新的 buffer
。看来您没有使用缓冲区,所以我会完全删除 al_create_bitmap
调用。如果您的意图是双缓冲,那么在 allegro5 中通常不需要。
此外,您的游戏循环中似乎调用了 map::Init
,这意味着您正在重复加载地图并且可能会花费大量时间等待 I/O。在游戏循环开始之前调用 map::Init
一次。
确实是map.init因为重新加载地图文件导致延迟!
谢谢!