|
Bug (or not) in Allegro |
kuarcke
Member #15,798
November 2014
|
Hello, I'm creating a game with Allegro 5, Visual Studio 8 and Windows XP. A photo of the problem: A video of the "bug": Below the drawing code of tiles: In tile class has a std :: vector<tile> contains that all existing tiles on the map, and the method draw () the map I draw them like this: 1//class map
2//all_tiles is std::vector<tile> static that contains all of the map tiles
3
4void map::draw(){
5 al_clear_to_color(WHITE);
6 for(int i = 0 ; i < (int) tile::all_tiles.size() ; i++)
7 tile::all_tiles.at(i)->draw();
8}
Do not bother to swap the buffers because the documentation says that the Allegro automatically identifies what the current backbuffer. I think be no problem with my computer 'cause I have done some games in Java (which is much slower than c ++) and ran perfectly. Does the problem is because Windows XP? Or am I doing something wrong? |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Show more relevant code. Where are you flipping the display? Are you using transforms? Also, have you verified vsync is running? My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
kuarcke
Member #15,798
November 2014
|
I have not posted much of anything because the code is very simple. void repaint(){ al_clear_to_color(WHITE); mapa.draw(); al_flip_display(); }
Information that may be important: each object has a pointer to tile corresponds to their respective image. Carry the tileset atlas, he divided the tiles, and move the pointer of each image to its corresponding tile. |
LennyLen
Member #5,313
December 2004
|
Show ALL the code. This is very unlikely to be a bug with Allegro, or it would be more common.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Where are you setting up the display? My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
kuarcke
Member #15,798
November 2014
|
Main class: 1#include <allegro5/allegro.h>
2#include <allegro5/allegro_image.h>
3#include <allegro5/allegro_primitives.h>
4#include "map.h"
5#include <stdio.h>
6#include <windows.h>
7
8#define WIDTH 1280
9#define HEIGHT 800
10#define GAME_NAME "Game Allegro"
11#define FPS 60.0
12#define LPS 120.0
13
14int load();
15void main_loop();
16void events();
17void update();
18void repaint();
19void quit();
20
21map mapa;
22
23ALLEGRO_DISPLAY *display = NULL;
24ALLEGRO_EVENT_QUEUE *eventqueue = NULL;
25ALLEGRO_TIMER *timer_fps = NULL;
26ALLEGRO_TIMER *timer_lps = NULL;
27
28ALLEGRO_EVENT evento;
29
30bool play = true;
31bool keys[226];
32
33bool need_redraw = false;
34bool need_update = false;
35
36int main(int argc, char **argv){
37 if(!load()){
38 quit();
39 printf("\nPressione uma tecla para sair.");
40 getchar();
41 return 0;
42 }
43 main_loop();
44}
45
46int load(){
47
48 //ALLEGRO E ADDONS
49 if(!al_init())
50 {
51 printf("Problema ao iniciar Allegro.");
52 return 0;
53 }
54
55
56 if(!al_init_image_addon())
57 {
58 printf("Problema ao iniciar Addon de imagem do Allegro.");
59 return 0;
60 }
61
62 if(!al_init_primitives_addon())
63 {
64 printf("Problema ao iniciar Addon de primitivas do Allegro.");
65 return 0;
66 }
67
68 if(!al_install_keyboard())
69 {
70 printf("Problema ao instalar teclado.");
71 return 0;
72 }
73
74 //FULL SCREEN
75 //al_set_new_display_flags(ALLEGRO_FULLSCREEN);
76 display = al_create_display(WIDTH, HEIGHT);
77
78 if(!display)
79 {
80 printf("Problema ao criar janela do Allegro.");
81 return 0;
82 }
83
84
85 timer_fps = al_create_timer(1.0 / FPS);
86 timer_lps = al_create_timer(1.0 / LPS);
87 al_set_window_title(display, GAME_NAME);
88
89 eventqueue = al_create_event_queue();
90 al_register_event_source(eventqueue, al_get_timer_event_source(timer_fps));
91 al_register_event_source(eventqueue, al_get_timer_event_source(timer_lps));
92 al_register_event_source(eventqueue, al_get_keyboard_event_source());
93
94 al_start_timer(timer_fps);
95 al_start_timer(timer_lps);
96 map = al_load_bitmap("mapa.bmp");
97 //---
98
99 if(!mapa.load("mapa.bmp",WIDTH, HEIGHT))
100 return 0;
101
102 return 1;
103}
104
105void main_loop(){
106 while(play){
107 if(need_redraw){
108 repaint();
109 need_redraw = false;
110 }
111
112 if(need_update){
113 update();
114 need_update = false;
115 }
116 events();
117 }
118
119}
120
121void events(){
122 al_wait_for_event(eventqueue, &evento);
123 if(evento.type == ALLEGRO_EVENT_KEY_DOWN){
124 if(evento.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
125 quit();
126 if(evento.keyboard.keycode == ALLEGRO_KEY_UP)
127 keys[ALLEGRO_KEY_UP] = true;
128 if(evento.keyboard.keycode == ALLEGRO_KEY_DOWN)
129 keys[ALLEGRO_KEY_DOWN] = true;
130 if(evento.keyboard.keycode == ALLEGRO_KEY_LEFT)
131 keys[ALLEGRO_KEY_LEFT] = true;
132 if(evento.keyboard.keycode == ALLEGRO_KEY_RIGHT)
133 keys[ALLEGRO_KEY_RIGHT] = true;
134
135 }else if(evento.type == ALLEGRO_EVENT_KEY_UP){
136 if(evento.keyboard.keycode == ALLEGRO_KEY_UP)
137 keys[ALLEGRO_KEY_UP] = false;
138 if(evento.keyboard.keycode == ALLEGRO_KEY_DOWN)
139 keys[ALLEGRO_KEY_DOWN] = false;
140 if(evento.keyboard.keycode == ALLEGRO_KEY_LEFT)
141 keys[ALLEGRO_KEY_LEFT] = false;
142 if(evento.keyboard.keycode == ALLEGRO_KEY_RIGHT)
143 keys[ALLEGRO_KEY_RIGHT] = false;
144
145 }else if(evento.timer.source == timer_fps){
146 need_redraw = true;
147 }else if(evento.timer.source == timer_lps){
148 need_update= true;
149 }
150}
151
152void update(){
153 mapa.update(keys);
154}
155
156void repaint(){
157 al_clear_to_color(WHITE);
158 mapa.draw();
159 al_flip_display();
160}
161
162void quit(){
163 play = false;
164 al_destroy_display(display);
165 al_destroy_timer(timer_fps);
166 al_destroy_timer(timer_lps);
167 al_destroy_event_queue(eventqueue);
168}
map class: 1#include "map.h"
2map::map(void)
3{
4}
5map::~map(void)
6{
7}
8
9int map::load(const char *file_name, int window_width, int window_height)
10{
11 xx = 0.0;
12
13 al_init_image_addon();
14 file = al_load_bitmap(file_name);
15 if(!file){
16 printf("\nFalha ao ler arquivo %s", file_name);
17 return 0;
18 }
19 width = al_get_bitmap_width(file);
20 height = al_get_bitmap_height(file);
21
22 //todos tiles do mapa
23 //all_tiles = new tile[width * height];
24
25 //carrega o tileset - imagem / tamanho do tile
26 if(!tile_set.load("tileset.jpg", 32))
27 return 0;
28
29 tiles_to_show_x = window_width / tile_set.get_tile_size();
30 tiles_to_show_y = window_height / tile_set.get_tile_size();
31
32 ALLEGRO_COLOR color;
33
34 tile *tl;
35
36 for(int r = 0 ; r < height ; r++)
37 {
38 for(int c = 0 ; c < width ; c++)
39 {
40 color = al_get_pixel(file, c, r);
41
42 if(color_to_tile(color) == 0)
43 continue;
44
45 int index = r * width + c;
46 tl = new tile();
47
48 tl->set_x(c * tile_set.get_tile_size());
49 tl->set_y(r * tile_set.get_tile_size());
50 tl->set_w(tile_set.get_tile_size());
51 tl->set_h(tile_set.get_tile_size());
52 tl->set_tile_index(color_to_tile(color));
53 tl->set_image(tile_set.get_tile(tl->get_tile_index()));
54 }
55 }
56 printf("%d tiles carregados.",tile::all_tiles.size());
57 al_destroy_bitmap(file);
58 return 1;
59}
60
61void map::draw(){
62 for(int i = 0 ; i < (int) tile::all_tiles.size() ; i++)
63 tile::all_tiles.at(i)->draw();
64}
65
66void map::update(bool keys[]){
67 for(int i = 0 ; i < (int) tile::all_tiles.size() ; i++)
68 tile::all_tiles.at(i)->update(keys);
69}
70
71int map::color_to_tile(ALLEGRO_COLOR color){
72
73 int index;
74
75 if(compare_color(color, BLACK))
76 index = 1;
77 else if(compare_color(color, RED))
78 index = 2;
79 else if(compare_color(color, GREEN))
80 index = 3;
81 else if(compare_color(color, BLUE))
82 index = 4;
83 else if(compare_color(color, YELLOW))
84 index = 5;
85 else if(compare_color(color, MAGENTA))
86 index = 6;
87 else if(compare_color(color, CYAN))
88 index = 7;
89 else
90 index = 0;
91 return index;
92}
93
94bool map::compare_color(ALLEGRO_COLOR color1, ALLEGRO_COLOR color2){
95 return (color1.r == color2.r) && (color1.g == color2.g) && (color1.b == color2.b);
96}
tileset class: 1#include "tileset.h"
2
3tileset::tileset(){}
4tileset::~tileset(){}
5int tileset::load(const char *file, int ts)
6{
7 tile_size = ts;
8 al_init_image_addon();
9 image = al_load_bitmap(file);
10
11 if(!image){
12 printf("\nFalha ao ler tileset %s", file);
13 return 0;
14 }
15
16 width = al_get_bitmap_width(image);
17 height = al_get_bitmap_height(image);
18
19 //caso o tileset nao seja multiplo do tamanho de seus tiles
20 if((width % tile_size != 0) | (height % tile_size != 0)){
21 printf("\nTileset nao compativel com o tamanho dos tiles.");
22 return 0;
23 }
24 number_tiles = width / height;
25
26 tiles_x = width / tile_size;
27 tiles_y = height / tile_size;
28
29 sub_tiles = new ALLEGRO_BITMAP*[tiles_x * tiles_y];
30
31 for(int r = 0 ; r < tiles_y ; r++)
32 for(int c = 0 ; c < tiles_x ; c++)
33 sub_tiles[r * tiles_x + c + 1] = al_create_sub_bitmap(image, c * tile_size, r * tile_size, tile_size, tile_size);
34
35 return 1;
36
37}
38int tileset::get_tile_size(){
39 return tile_size;
40}
41ALLEGRO_BITMAP * tileset::get_tile(int index){
42 return sub_tiles[index];
43}
tile class: 1#include "tile.h"
2
3std::vector<tile*> tile::all_tiles;
4
5tile::tile(){
6 all_tiles.push_back(this);
7}
8tile::~tile(){
9}
10int tile::get_tile_index()
11{
12 return tile_index;
13}
14bool tile::is_solid()
15{
16 return solid;
17}
18
19ALLEGRO_BITMAP * tile::get_image()
20{
21 return image;
22}
23void tile::set_tile_index(int index)
24{
25 tile_index = index;
26}
27
28void tile::set_solid(bool state)
29{
30 solid = state;
31}
32void tile::set_image(ALLEGRO_BITMAP * img)
33{
34 image = img;
35}
36void tile::draw(){
37 al_draw_bitmap(image,get_x(),get_y(),0);
38}
39void tile::update(bool keys[]){
40 if(keys[ALLEGRO_KEY_RIGHT])
41 set_x(get_x() + 5);
42}
It is all. |
Arthur Kalliokoski
Second in Command
February 2005
|
That video looks like a vsync problem to me. The display is updated while the monitor is halfway through showing the previous frame. Try this before creating the display: al_set_new_display_option(ALLEGRO_VSYNC, 1, ALLEGRO_SUGGEST); and if that doesn't work, there should be a setting in your graphics utility to allow programs to set vsync/flipping and not override it. They all watch too much MSNBC... they get ideas. |
kuarcke
Member #15,798
November 2014
|
al_set_new_display_option (ALLEGRO_VSYNC, 1, ALLEGRO_SUGGEST); worked, the tiles are perfect now, but the game is too slow, the controls are coming with 1 sec delay ; |
Arthur Kalliokoski
Second in Command
February 2005
|
Try adjusting your timer values. They all watch too much MSNBC... they get ideas. |
kuarcke
Member #15,798
November 2014
|
Tips? because they seem ok to me. |
l j
Member #10,584
January 2009
|
Check if your event queue is empty before drawing, that should solve the input delay.
|
Arthur Kalliokoski
Second in Command
February 2005
|
I was thinking that somehow the timer would cause a delay after the vsync or something, so it'd have two delays, one for the vsync and one for the timer itself. If you sped up the timer a bit so it'd always ask for a redraw before a vsync kicked in, then it'd work better I'd think. They all watch too much MSNBC... they get ideas. |
kuarcke
Member #15,798
November 2014
|
It worked guys, is perfect right now with vsync! while (!al_event_queue_is_empty(eventqueue)) { al_wait_for_event(eventqueue, & event); if (evento.type == ALLEGRO_EVENT_KEY_DOWN) { //do something ... } } Many thanks for the help. |
|