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);
    }
}

我正在使用的瓷砖:

http://i.stack.imgur.com/k4DbZ.png

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因为重新加载地图文件导致延迟!

谢谢!