![]() |
|
Mouse movement causes unwanted speed increase for player |
piskypom
Member #16,813
February 2018
|
I've only been using Allegro for about a week. I have a lot to learn. For the moment, I can't figure out what's causing the player movement speed to increase. As soon as I install the mouse and register it, the player will move very fast when I move the mouse. If I leave the mouse still, the player moves at normal speed. If I leave mouse uninstalled, then there is no problem. https://github.com/adabo/Allegro_First_Test/tree/dev_no_switchcase_for_keypress All the game code is in game.cpp. You'll notice that I sort of "wrapped" all the allegro initialization code into c++ member functions. It's just easier for me to look at when you look at the main.cpp. I think all the relevant code will be in these functions: void Game::handle_events(); void Game::handle_key_press(); void Game::draw_player(); *Edit: This is funny. I apparently broke something because now when event.mouse.x == 59, then event.keyboard.keycode== 59 (ESC), which triggers game_is_running to be false which then exits the program. Not what I want. I can't imagine how the two events are talking to each other. *Edit2: I fixed the mouse causing the exit routine. I didn't realize I was assigning false twice to game_is_running. Here's the diff I've been giving the player speed issue some thought and have a theory that when the mouse is moving it refreshes the screen faster than a keyboard being held down. Or another theory is that a the key polling and the mouse movement overlap thus doubling the player's speed. I'll experiment with that.
|
Audric
Member #907
January 2001
|
handle_key_press() is being run after each event, which is wrong. It is basically your "game physics" or "game logic" function, so you should rename it accordingly and run it 60 times per second : 1void Game::handle_events()
2{
3 // Fetch the event (if one exists)
4 al_wait_for_event(event_queue, &event);
5
6 switch (event.type) {
7 case ALLEGRO_EVENT_TIMER:
8 handle_key_press(); <--- here
9 can_redraw = true;
10 break;
11 case ALLEGRO_EVENT_DISPLAY_CLOSE:
12 game_is_running = false;
13 break;
14 case ALLEGRO_EVENT_KEY_DOWN:
15 std::cout << "A key was Pressed: "<< event.keyboard.keycode << std::endl;
16 store_key_state();
17 break;
18 case ALLEGRO_EVENT_KEY_UP:
19 store_key_state();
20 break;
21 case ALLEGRO_EVENT_MOUSE_AXES:
22 handle_mouse_action(event, &target);
23 break;
24 default:
25 std::cout << stderr << " Unsupported event received: " << event.type << std::endl;
26 break;
27 }
28 // <--- removed
29}
|
piskypom
Member #16,813
February 2018
|
Thank you Audric! You solution fixed the issue. I'm still trying to understand how that works. I need to learn about what the timer event is. You mentioned that I should rename the handle_key_press() function. That it's name is inappropriate for what it actually does. I need a little more advice on this because with game development I have no real direction. I'm just learning as I go, teaching myself as I need, eg: youtube videos, articles. I didn't really find any extensive allegro game tutorial series, thus I'm learning the hard way. So this handle_key_press() function is doing the heavy lifting so to speak? The game logic, as you say. I guess I'm a little confused because in my head, the reason I named it "handle_key_press" is because of what happens after the key is pressed, such as the player's position is updated. What would you recommend? P.S: I'd also like to know about the order in which the cases in the switch are currently. Your solution puts the player position update at the top before the keyboard is is polled. Is that right? I guess I don't know how the allegro event queue system works.
|
Audric
Member #907
January 2001
|
The structure that you have is 95% a very commmon pattern, a game loop with fixed time step: I suggested renaming handle_key_press() because at the moment you may have only one active thing, but as soon as you add other game elements you'll see they all need "update" code that gets called as frequently as player update, independantly from player input : bullets keep moving, animating explosions keep changing image, etc. Making a single point of entry game_logic() is very common. edit: About the order of things : The switch "cases" all have a break, so the order they are written does not change the behavior. The events are present in the queue in whatever order they happened. |
piskypom
Member #16,813
February 2018
|
Hm. So the event: ALLEGRO_EVENT_TIMER is called 60 times/per second? If that is the case then yes, it makes much more sense in this design pattern to update per Also, does the timer run asynchronous to the game loop or in it's own thread? Ok, so the queue is literally that: a list/array of events lined up and then the switch just checks the next one in line. So it literally does not matter which order the cases are in. Correct?
|
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Generally you want to check events until the queue is empty, and then draw, but continue to wait for timer events as normal. Your timer tells you when to redraw and when to process logic. 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 |
piskypom
Member #16,813
February 2018
|
OK. I want to do things logically. So what you're saying is that I'm drawing each tick regardless if the queue is empty? If that is the case, how do I check if the queue is empty? 1switch (event.type) {
2 case ALLEGRO_EVENT_TIMER:
3 if (event_queue == EMPTY) {
4 // update and draw stuff;
5 }
6}
|
piskypom
Member #16,813
February 2018
|
|
Audric
Member #907
January 2001
|
Yes, all these allegro systems are asynchronous. They push events at the end of the queue, it can happen at any moment in parallel with the execution of your code. The al_wait_for_event() removes the first event at the front of the queue and then the switch part is when you examine it. |
piskypom
Member #16,813
February 2018
|
Now that is cool! I'm really liking this framework. It's got lots of features, but not so much that it takes away the fun of discovery and invention (or re-invention in my case).
|
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
Think about it. If you're processing your logic once every event, it will speed up when there are a lot of events. If you only process your logic once per timer tick it will stay at the same rate. 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 |
piskypom
Member #16,813
February 2018
|
So true. Using an event system is completely new to me. It's pretty nice, though. And I like the structure and organization of it all. I came across so many bugs yesterday not fully understanding the even queue. I managed to knock out all of them. It's slowly starting to sink in.
|
|