![]() |
|
Lag in the main loop |
moisesdias
Member #16,905
October 2018
|
Hello guys, i'm facing a problem with my program: 1while(!finish)
2 {
3 while(!al_is_event_queue_empty(eventQueue))
4 {
5 al_wait_for_event(eventQueue, &event);
6
7 if(event.type == ALLEGRO_EVENT_KEY_DOWN)
8 Keys::keyPressed(keys, event.keyboard.keycode);
9
10 if(event.type == ALLEGRO_EVENT_KEY_UP)
11 Keys::keyReleased(keys, event.keyboard.keycode);
12
13 if(event.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
14 finish = true;
15
16 if(event.type == ALLEGRO_EVENT_TIMER)
17 {
18 gamePlay.update(keys, finish);
19
20 draw = true;
21 }
22 }
23 if(draw)
24 {
25 draw = false;
26 gamePlay.drawGame();
27 }
28}
29
30
31
32void GamePlay::update(bool* keys, bool& finish)
33{
34 if(posX > 1000)
35 test = false;
36 if (posX < 50)
37 test = true;
38 if(test)
39 posX+=10;
40 else
41 posX-=10;
42}
43
44
45
46void GamePlay::drawGame()
47{
48 al_draw_filled_circle(posX,posY,50,al_map_rgba(255,0,0,255));
49 al_flip_display();
50 al_clear_to_color(al_map_rgb(0,0,0));/**isso afeta o backbuffer**/
51}
|
Elias
Member #358
May 2000
|
Remove the ! before al_is_event_queue_empty(). You want to call al_wait_for_event when the queue is empty and wait until there is an event. The way you have it you would only wait for an event if there already is one, so never... which means your loop just runs through millions of times heating up a CPU core and making everything unstable and jumpy. -- |
moisesdias
Member #16,905
October 2018
|
Hi Elias, thanks for your reply, I tried to change the main loop but unfortunely my drawings are still jumpy. I tried a lot of new combinations, but none of them seems to solve the problem 1while(!finish)
2 {
3
4 while(1)
5 {
6 al_wait_for_event(eventQueue, &event);
7
8 if(event.type == ALLEGRO_EVENT_KEY_DOWN)
9 Keys::keyPressed(keys, event.keyboard.keycode);
10
11 if(event.type == ALLEGRO_EVENT_KEY_UP)
12 Keys::keyReleased(keys, event.keyboard.keycode);
13
14 if(event.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
15 finish = true;
16
17 if(event.type == ALLEGRO_EVENT_TIMER)
18 gamePlay.update(keys, finish);
19
20 if(al_is_event_queue_empty(eventQueue))
21 gamePlay.drawGame();
22 }
23
24 }
I also tried a logic with two timers, one for the logic and other for drawing, but it have not worked too. |
trictonicmp
Member #16,611
December 2016
|
1//-------------------------------Main loop--------------------------------
2while (!done)
3{
4 do
5 {
6 //------------------------Getting events--------------------------
7 ALLEGRO_EVENT event;
8 al_wait_for_event(eventQueue, &event);
9
10 if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
11 done = true;
12
13
14
15 if (event.type == ALLEGRO_EVENT_TIMER)
16 {
17 redraw = true;
18 }
19
20 //-----------------------Getting events END-----------------------
21 } while (!al_is_event_queue_empty(eventQueue));
22
23
24
25 //-------------------------Redrawing elements-------------------------
26 if (redraw)
27 {
28 al_flip_display();
29 redraw = false;
30 }
31 //-----------------------Redrawing elements END-----------------------
32 }
33//-----------------------------Main loop END------------------------------
I always use this as my main loop, the only thing that I notice is that your code does not have the "ALLEGRO_EVENT event;" before "al_wait_for_event(eventQueue, &event);" |
Elias
Member #358
May 2000
|
trictonicmp's loop looks right to me. The key points are:
-- |
roger levy
Member #2,513
July 2002
|
Good thread. I'm going to try upgrading Ramen's loop using the advice in here. |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Fixing the formatting and making it more condensed : 1 bool redraw = true;
2 bool quit = false;
3
4 while (!quit) {
5 if (redraw) {
6 Draw();
7 redraw = false;
8 }
9 do {
10 ALLEGRO_EVENT ev;
11 al_wait_for_event(q , &ev);
12 if (ev.type == ALLEGRO_EVENT_TIMER) {
13 Update(dt);
14 redraw = true;
15 }
16 /// Handle events here
17 } while (!al_is_event_queue_empty(q));
18 }
This is pretty much the standard loop, and has been on the wiki for a while. It's just your basic event loop. 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 |
moisesdias
Member #16,905
October 2018
|
Guys, thanks for all the answers, but i'm beginning to get worried about it.. I have removed all the miscellaneous code and I'm going to put here what i'm compiling, it is only three classes, maybe this way it will be easier to find my problem, if there is one: it's really strange, it only prints a red ball moving from one side to another, but it still give some 'jumps' at every two seconds approximately edit: if you guys want, you can run this program only with this code below, i don't discard the possibility of the problem be my installation, and not in my code, who knows.. 1//----------the main class----------
2
3#include "GameManager.h"
4int main()
5{
6 GameManager US;
7 return 0;
8}
9
10//----------GameManager header----------
11
12#ifndef GAMEMANAGER_H
13#define GAMEMANAGER_H
14#include "GamePlay.h"
15
16class GameManager
17{
18 public:
19 GameManager();
20 void manage();
21
22 private:
23 GamePlay gamePlay;
24
25 ALLEGRO_DISPLAY* screen;
26 ALLEGRO_EVENT_QUEUE* eventQueue;
27 ALLEGRO_TIMER* timer;
28
29};
30
31#endif // GAMEMANAGER_H
32
33
34//----------GameManager source----------
35
36#include "GameManager.h"
37
38
39GameManager::GameManager()
40{
41
42 draw = true;
43 finish = false;
44 screen = NULL;
45 eventQueue = NULL;
46 timer = NULL;
47
48 if(!al_init())
49 finish = true;
50
51 screen = al_create_display(1200,800);
52
53 if(!screen || !al_init_primitives_addon())
54 finish = true;
55
56 timer = al_create_timer(1.0 / 60);
57
58 eventQueue = al_create_event_queue();
59
60 al_register_event_source(eventQueue, al_get_timer_event_source(timer));
61 al_register_event_source(eventQueue, al_get_display_event_source(screen));
62
63 al_start_timer(timer);
64
65 manage();
66}
67
68
69
70void GameManager::manage()
71{
72 bool draw = true;
73 bool finish = false;
74
75 while (!finish)
76 {
77 if (draw)
78 {
79 gamePlay.drawGame();
80 draw = false;
81 }
82 do
83 {
84 ALLEGRO_EVENT ev;
85 al_wait_for_event(eventQueue, &ev);
86 if (ev.type == ALLEGRO_EVENT_TIMER)
87 {
88 gamePlay.update();
89 draw = true;
90 }
91
92 // i have also tried to put the gamePlay.updat() here
93 }
94 while (!al_is_event_queue_empty(eventQueue));
95 }
96}
97
98
99
100//----------GamePlay header----------
101
102#ifndef GAMEPLAY_H
103#define GAMEPLAY_H
104
105#include <allegro5/allegro.h>
106#include <allegro5/allegro_primitives.h>
107class GamePlay
108{
109 public:
110 GamePlay();
111 void update();
112 void drawGame();
113
114 private:
115 int posX;
116 int posY;
117 bool test;
118};
119
120#endif // GAMEPLAY_H
121
122
123//----------GamePlay source----------
124
125#include "GamePlay.h"
126
127GamePlay::GamePlay()
128{
129 posX = 500;
130 posY = 500;
131 test = false;
132}
133void GamePlay::update()
134{
135 if(posX > 1000)
136 test = false;
137 if (posX < 50)
138 test = true;
139 if(test)
140 posX+=10;
141 else
142 posX-=10;
143}
144void GamePlay::drawGame()
145{
146 al_draw_filled_circle(posX,posY,50,al_map_rgba(255,0,0,255));
147 al_flip_display();
148 al_clear_to_color(al_map_rgb(0,0,0));
149}
|
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
If you're going to provide code, provide something that compiles please. Here's your code fixed up and compiling : 1//----------the main class----------
2
3
4//----------GamePlay header----------
5
6#ifndef GAMEPLAY_H
7#define GAMEPLAY_H
8
9#include <allegro5/allegro.h>
10#include <allegro5/allegro_primitives.h>
11class GamePlay
12{
13 public:
14 GamePlay();
15 void update();
16 void drawGame();
17
18 private:
19 int posX;
20 int posY;
21 bool test;
22};
23
24#endif // GAMEPLAY_H
25
26
27//#include "GameManager.h"
28
29//----------GameManager header----------
30
31#ifndef GAMEMANAGER_H
32#define GAMEMANAGER_H
33//#include "GamePlay.h"
34
35class GameManager
36{
37 public:
38 GameManager();
39 void manage();
40
41 private:
42 GamePlay gamePlay;
43
44 ALLEGRO_DISPLAY* screen;
45 ALLEGRO_EVENT_QUEUE* eventQueue;
46 ALLEGRO_TIMER* timer;
47
48 bool draw;
49 bool finish;
50};
51
52#endif // GAMEMANAGER_H
53
54
55//----------GameManager source----------
56
57//#include "GameManager.h"
58
59
60GameManager::GameManager()
61{
62
63 draw = true;
64 finish = false;
65 screen = NULL;
66 eventQueue = NULL;
67 timer = NULL;
68
69 if(!al_init())
70 finish = true;
71
72 if (!al_install_keyboard()) {finish = true;}
73
74 screen = al_create_display(1200,800);
75
76 if(!screen || !al_init_primitives_addon())
77 finish = true;
78
79 timer = al_create_timer(1.0 / 60);
80
81 eventQueue = al_create_event_queue();
82
83 al_register_event_source(eventQueue, al_get_timer_event_source(timer));
84 al_register_event_source(eventQueue, al_get_display_event_source(screen));
85 al_register_event_source(eventQueue, al_get_keyboard_event_source());
86
87 al_start_timer(timer);
88
89 manage();
90}
91
92
93
94void GameManager::manage()
95{
96
97 while (!finish)
98 {
99 if (draw)
100 {
101 gamePlay.drawGame();
102 draw = false;
103 }
104 do
105 {
106 ALLEGRO_EVENT ev;
107 al_wait_for_event(eventQueue, &ev);
108 if (ev.type == ALLEGRO_EVENT_TIMER)
109 {
110 gamePlay.update();
111 draw = true;
112 }
113 else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
114 finish = true;
115 }
116 else if (ev.type == ALLEGRO_EVENT_KEY_DOWN && ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
117 finish = true;
118 }
119
120 // i have also tried to put the gamePlay.updat() here
121 }
122 while (!al_is_event_queue_empty(eventQueue));
123 }
124}
125
126
127//----------GamePlay source----------
128
129//#include "GamePlay.h"
130
131GamePlay::GamePlay()
132{
133 posX = 500;
134 posY = 500;
135 test = false;
136}
137void GamePlay::update()
138{
139 if(posX > 1000)
140 test = false;
141 if (posX < 50)
142 test = true;
143 if(test)
144 posX+=10;
145 else
146 posX-=10;
147}
148void GamePlay::drawGame()
149{
150 al_draw_filled_circle(posX,posY,50,al_map_rgba(255,0,0,255));
151 al_flip_display();
152 al_clear_to_color(al_map_rgb(0,0,0));
153}
154
155int main()
156{
157 GameManager US;
158 return 0;
159}
The resulting exe works fine. The red ball goes back and forth smoothly. There was one glitch on the first run, where it skipped a little, but I assume that was a vsync timing issue. 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 |
moisesdias
Member #16,905
October 2018
|
I'm sorry Edgar, I have removed a lot of classes, I did not see the remaining variables. So, I don't think that the problem is my computer, maybe I have messed up when installing codeblocks and allegro, but I'm less worried now that it worked fine for you. do you guys know a recognized tutorial for installation of allegro with any IDE? for windows or linux? |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
I wouldn't consider it solved yet. The code listed works fine when graphics takes less than 1.0/FPS, but when it takes longer than that, you will have frame skipping. The solution is to discard all timer events after the first in each iteration. This will skip all extra timer events in case they pile up, and it will slow down gracefully. 1 bool redraw = true;
2 bool quit = false;
3
4 int ticks = 0;
5 while (!quit) {
6 if (redraw) {
7 Draw();
8 redraw = false;
9 ticks = 0;
10 }
11 do {
12 ALLEGRO_EVENT ev;
13 al_wait_for_event(q , &ev);
14 if (ev.type == ALLEGRO_EVENT_TIMER) {
15 ++ticks;
16 if (ticks == 1) {
17 Update(dt);
18 }
19 redraw = true;
20 }
21 /// Handle events here
22 } while (!al_is_event_queue_empty(q));
23 }
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 |
moisesdias
Member #16,905
October 2018
|
Edgar, I've tried to put this new variable to avoid updating twice before drawing, but my problem persists, unfortunnely.. I have also tried to leave only the al_flip_display() on my Draw function: 1
2void GamePlay::update()
3{
4 if(posX > 1000)
5 test = false;
6 if (posX < 50)
7 test = true;
8 if(test)
9 posX+=10;
10 else
11 posX-=10;
12
13 al_clear_to_color(al_map_rgb(0,0,0));
14 al_draw_filled_circle(posX,posY,50,al_map_rgba(255,0,0,255));
15}
16void GamePlay::drawGame()
17{
18 al_flip_display();
19
20}
21
22
23//instead of
24
25
26
27void GamePlay::update()
28{
29 if(posX > 1000)
30 test = false;
31 if (posX < 50)
32 test = true;
33 if(test)
34 posX+=10;
35 else
36 posX-=10;
37}
38void GamePlay::drawGame()
39{
40 al_draw_filled_circle(posX,posY,50,al_map_rgba(255,0,0,255));
41 al_flip_display();
42 al_clear_to_color(al_map_rgb(0,0,0));
43}
but it did not help. Damn, I was pretty sure that the ticks variable would solve the issue hahahaha edit: I've checked my screen refresh rate and it's on 60Hz |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
moisesdias said: do you guys know a recognized tutorial for installation of allegro with any IDE? for windows or linux? MSVS is pretty easy. All you do is use Nugat to install Allegro. MinGW and CodeBlocks is not super hard either, but takes some work. Linux can be as easy as 'sudo apt-get install liballegro5-dev' if you're on Ubuntu. moisesdias said: but it did not help. Damn, I was pretty sure that the ticks variable would solve the issue hahahaha edit: I've checked my screen refresh rate and it's on 60Hz It literally has to move 10 pixels at a time, there's something else going on. Did you compile and run the code I gave back to you? 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 |
moisesdias
Member #16,905
October 2018
|
Guys, I've found the problem, it was not the code, but an old VGA monitor that I was using with my notebook, I don't know exactly why, but when I disconnect him the circle moves smoothly on the screen Anyway, thanks Edgar and thanks for all who have replied!! |
|