How do you use ALLEGRO Event/Timer to update character movement

For example,

I have a character on screen. If i press the "Left Arrow key", the character would move left, but then it won't move again unless i let go of the key, and re-press it. How can i update the game so the character moves as long as I hold the arrow key?

Here's Allegro's tutorial on Timer:
http://wiki.allegro.cc/index.php?title=Allegro_5_Tutorial/Timers

I can't figure out how to use this in my program. I just want the character to move while the key is still pressed.
Post your code. I have experience using Allegro 5 and am part of the Allegro.cc community. I think your code problem may be in the keyboard events and not the event timers.
Last edited on by closed account z6A9GNh0
I excluded most of the unnecessary codes for you, here is the keyboard code in main(). I deleted the timer awhile ago since I couldn't get to work. How would i add the timer in this code?







while (!0){

a.Char_Coord();
c.Boundary();

al_wait_for_event(event_queue, &ev);

if (ev.type == ALLEGRO_EVENT_KEY_UP){
switch (ev.keyboard.keycode){
case ALLEGRO_KEY_UP:
if (c.wall==3)
Move.Movement(0);
else
Move.Movement(3);
c.mvn = 3;
break;
case ALLEGRO_KEY_LEFT:
if (c.wall==2)
Move.Movement(0);
else
Move.Movement(2);
c.mvn = 2;
break;
case ALLEGRO_KEY_RIGHT:
if (c.wall==1)
Move.Movement(0);
else
Move.Movement(1);
c.mvn = 1;
break;
case ALLEGRO_KEY_DOWN:
if (c.wall==4)
Move.Movement(0);
else
Move.Movement(4);
c.mvn = 4;
break;
}
}


else if (ev.type == ALLEGRO_EVENT_KEY_DOWN){
switch (ev.keyboard.keycode){
case ALLEGRO_KEY_DOWN:
if (c.wall==4)
Move.Movement(0);
else
Move.Movement(4);
c.mvn = 4;
break;
case ALLEGRO_KEY_LEFT:
if (c.wall==2)
Move.Movement(0);
else
Move.Movement(2);
c.mvn = 2;
break;
case ALLEGRO_KEY_RIGHT:
if (c.wall==1)
Move.Movement(0);
else
Move.Movement(1);
c.mvn = 1;
break;
case ALLEGRO_KEY_UP:
if (c.wall==3)
Move.Movement(0);
else
Move.Movement(3);
c.mvn = 3;
break;
}
}


}

return 0;
}
Last edited on
Have you read the basic keyboard example?
http://wiki.allegro.cc/index.php?title=Basic_Keyboard_Example

I would have to see the full code to and mess with it to see exactly what is going on, but it looks like you are doing the code that should be in the event timer in the key press code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include <stdio.h>
#include <allegro5/allegro.h>
 
const float FPS = 60;
const int SCREEN_W = 640;
const int SCREEN_H = 480;
const int BOUNCER_SIZE = 32;
enum MYKEYS {
   KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT
};
 
int main(int argc, char **argv)
{
   ALLEGRO_DISPLAY *display = NULL;
   ALLEGRO_EVENT_QUEUE *event_queue = NULL;
   ALLEGRO_TIMER *timer = NULL;
   ALLEGRO_BITMAP *bouncer = NULL;
   float bouncer_x = SCREEN_W / 2.0 - BOUNCER_SIZE / 2.0;
   float bouncer_y = SCREEN_H / 2.0 - BOUNCER_SIZE / 2.0;
   bool key[4] = { false, false, false, false };
   bool redraw = true;
   bool doexit = false;
 
   if(!al_init()) {
      fprintf(stderr, "failed to initialize allegro!\n");
      return -1;
   }
 
   if(!al_install_keyboard()) {
      fprintf(stderr, "failed to initialize the keyboard!\n");
      return -1;
   }
 
   timer = al_create_timer(1.0 / FPS);
   if(!timer) {
      fprintf(stderr, "failed to create timer!\n");
      return -1;
   }
 
   display = al_create_display(SCREEN_W, SCREEN_H);
   if(!display) {
      fprintf(stderr, "failed to create display!\n");
      al_destroy_timer(timer);
      return -1;
   }
 
   bouncer = al_create_bitmap(BOUNCER_SIZE, BOUNCER_SIZE);
   if(!bouncer) {
      fprintf(stderr, "failed to create bouncer bitmap!\n");
      al_destroy_display(display);
      al_destroy_timer(timer);
      return -1;
   }
 
   al_set_target_bitmap(bouncer);
 
   al_clear_to_color(al_map_rgb(255, 0, 255));
 
   al_set_target_bitmap(al_get_backbuffer(display));
 
   event_queue = al_create_event_queue();
   if(!event_queue) {
      fprintf(stderr, "failed to create event_queue!\n");
      al_destroy_bitmap(bouncer);
      al_destroy_display(display);
      al_destroy_timer(timer);
      return -1;
   }
 
   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_register_event_source(event_queue, al_get_keyboard_event_source());
 
   al_clear_to_color(al_map_rgb(0,0,0));
 
   al_flip_display();
 
   al_start_timer(timer);
 
   while(!doexit)
   {
      ALLEGRO_EVENT ev;
      al_wait_for_event(event_queue, &ev);
 
      if(ev.type == ALLEGRO_EVENT_TIMER) {
         if(key[KEY_UP] && bouncer_y >= 4.0) {
            bouncer_y -= 4.0;
         }
 
         if(key[KEY_DOWN] && bouncer_y <= SCREEN_H - BOUNCER_SIZE - 4.0) {
            bouncer_y += 4.0;
         }
 
         if(key[KEY_LEFT] && bouncer_x >= 4.0) {
            bouncer_x -= 4.0;
         }
 
         if(key[KEY_RIGHT] && bouncer_x <= SCREEN_W - BOUNCER_SIZE - 4.0) {
            bouncer_x += 4.0;
         }
 
         redraw = true;
      }
      else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
         break;
      }
      else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) {
         switch(ev.keyboard.keycode) {
            case ALLEGRO_KEY_UP:
               key[KEY_UP] = true;
               break;
 
            case ALLEGRO_KEY_DOWN:
               key[KEY_DOWN] = true;
               break;
 
            case ALLEGRO_KEY_LEFT: 
               key[KEY_LEFT] = true;
               break;
 
            case ALLEGRO_KEY_RIGHT:
               key[KEY_RIGHT] = true;
               break;
         }
      }
      else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
         switch(ev.keyboard.keycode) {
            case ALLEGRO_KEY_UP:
               key[KEY_UP] = false;
               break;
 
            case ALLEGRO_KEY_DOWN:
               key[KEY_DOWN] = false;
               break;
 
            case ALLEGRO_KEY_LEFT: 
               key[KEY_LEFT] = false;
               break;
 
            case ALLEGRO_KEY_RIGHT:
               key[KEY_RIGHT] = false;
               break;
 
            case ALLEGRO_KEY_ESCAPE:
               doexit = true;
               break;
         }
      }
 
      if(redraw && al_is_event_queue_empty(event_queue)) {
         redraw = false;
 
         al_clear_to_color(al_map_rgb(0,0,0));
 
         al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0);
 
         al_flip_display();
      }
   }
 
   al_destroy_bitmap(bouncer);
   al_destroy_timer(timer);
   al_destroy_display(display);
   al_destroy_event_queue(event_queue);
 
   return 0;
}
Here is the full code of my Pokemon game. It's quite messy but this project is only for learning/practicing classes/allegro.








#include <stdio.h>
#include <allegro5/allegro.h>
#include "allegro5/allegro_image.h"
#include "allegro5/allegro_native_dialog.h"
#include <iostream>

using namespace std;


class Coordinations {

public:
static int LeftRight, UpDown, aiX, aiY;
static int wall;
static int mvn, aiMvn;
void Boundary();

};

int Coordinations::LeftRight = 540;
int Coordinations::UpDown = 240;
int Coordinations::wall;
int Coordinations::mvn = 2;


class Characters: public Coordinations {

private:
ALLEGRO_BITMAP *image[15];

public:

void Character_Load();
void Char_Coord();
int AI_Load();
int AI_Coord();
};


void Characters::Character_Load() // Load Character
{
image[0] = al_load_bitmap("ptown.png"); //Map image


image[1] = al_load_bitmap("AshRight.png");
image[2] = al_load_bitmap("AshLeft.png");
image[3] = al_load_bitmap("AshUp.png");
image[4] = al_load_bitmap("AshDown.png");

image[5] = al_load_bitmap("AshLeft+1.png");
image[6] = al_load_bitmap("AshLeft+2.png");
image[7] = al_load_bitmap("AshDown+1.png");
image[8] = al_load_bitmap("AshDown+2.png");
image[9] = al_load_bitmap("AshUp+1.png");
image[10] = al_load_bitmap("AshUp+2.png");
image[11] = al_load_bitmap("AshRight+1.png");
image[12] = al_load_bitmap("AshRight+2.png");

}

void Characters::Char_Coord()
{
int LeftPressed = 0;

al_clear_to_color(al_map_rgb(0, 0, 0)); // Map (Coordinations)
al_draw_bitmap(image[0],0,0,0);



al_draw_bitmap(image[mvn],LeftRight,UpDown,0); //Character (Sprite, Coordinations)
al_flip_display();

if (mvn == 2)
mvn = 5;

if (mvn == 5)
mvn = 6;

if (mvn == 4)
mvn = 7;

if (mvn == 7)
mvn = 8;

if (mvn == 3)
mvn = 10;

if (mvn == 10)
mvn = 9;

if (mvn == 1)
mvn = 12;

if (mvn == 12)
mvn = 11;



}


class KeyMovement: public Coordinations {

public:

void Movement(int);

};

void Coordinations::Boundary()
{

if (LeftRight>540)
wall = 1;

else if ((( UpDown < 240) && ((LeftRight != 460) ||(LeftRight != 310))))
wall = 3;

else if (LeftRight <= 0)
wall = 2;

else if (UpDown > 330)
wall = 4;

else
wall = 0;

}

void KeyMovement::Movement(int a)
{

if (a == 1) //1 - Right, 2 - Left, 3 - Up, 4 - Down
LeftRight += 5;

else if (a == 2)
LeftRight -= 5;

else if (a == 3)
UpDown -= 5;

else if (a == 4)
UpDown += 5;

else if (a == 0);

}




int main(int argc, char **argv)
{

ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue = NULL;

al_init();
al_init_image_addon();
al_install_keyboard();

display = al_create_display(575, 480);

event_queue = al_create_event_queue();
al_register_event_source(event_queue, al_get_keyboard_event_source());
ALLEGRO_EVENT ev;

Characters a;
KeyMovement Move;

a.Character_Load();

Coordinations c;
int work = 0;





while (!0){

a.Char_Coord();
cout<<"LeftRight:"<<c.LeftRight<<endl;
cout<<"Updown:"<<c.UpDown<<endl;
c.Boundary();

al_wait_for_event(event_queue, &ev); // Waits for Key input

if (ev.type == ALLEGRO_EVENT_KEY_UP){
switch (ev.keyboard.keycode){
case ALLEGRO_KEY_UP:
if (c.wall==3)
Move.Movement(0);
else
Move.Movement(3);
c.mvn = 3;
break;
case ALLEGRO_KEY_LEFT:
if (c.wall==2)
Move.Movement(0);
else
Move.Movement(2);
c.mvn = 2;
break;
case ALLEGRO_KEY_RIGHT:
if (c.wall==1)
Move.Movement(0);
else
Move.Movement(1);
c.mvn = 1;
break;
case ALLEGRO_KEY_DOWN:
if (c.wall==4)
Move.Movement(0);
else
Move.Movement(4);
c.mvn = 4;
break;
}
}


else if (ev.type == ALLEGRO_EVENT_KEY_DOWN){
switch (ev.keyboard.keycode){
case ALLEGRO_KEY_DOWN:
if (c.wall==4)
Move.Movement(0);
else
Move.Movement(4);
c.mvn = 4;
break;
case ALLEGRO_KEY_LEFT:
if (c.wall==2)
Move.Movement(0);
else
Move.Movement(2);
c.mvn = 2;
break;
case ALLEGRO_KEY_RIGHT:
if (c.wall==1)
Move.Movement(0);
else
Move.Movement(1);
c.mvn = 1;
break;
case ALLEGRO_KEY_UP:
if (c.wall==3)
Move.Movement(0);
else
Move.Movement(3);
c.mvn = 3;
break;
}
}


}

return 0;
}
It is because the ALLEGRO_KEY_UP and ALLEGRO_KEY_DOWN are the states and only execute once per keypress. You need to have your movement code to in the if(ev.type == ALLEGRO_EVENT_TIMER) {} section. The keyboard code I showed in my previous post is easier in my opinion for movement. The reason you are only moving one pixel per press is because as I said you have your movement in the key state code so it only runs every press rather than holding it.
I tried that before. I put the keyboard codes inside the timer {} code and it never worked.
Create a boolean array for each possible keycode like such:

bool pressed_key[ALLEGRO_KEY_MAX];

Then when a key is pressed, change the keycode index in the array to true:

1
2
3
case ALLEGRO_EVENT_KEY_DOWN:
    pressed_key[evt.keyboard.keycode] = true;
    break;


Then simply check to see if a key is being pressed with your timer. For example:

if(pressed_key[ALLEGRO_KEY_UP])

Hope this helps. It's how I achieved this sort of movement.
closed account (o1vk4iN6)
while (!0){

why... I mean, why not just put 1 if your going to do that.
Last edited on
I still can't get it to work. When I press one of the arrow keys, LeftRight or Updown don't change in value.
FourSight, you may find better help from the forums for Allegro. I may be missing something but the guys there are pretty good at helping fix and understand problems. I just stated what I believe it is, but I could be wrong in that assumption. You will find tons of help specific to Allegro at http://www.allegro.cc but I will keep tweaking the code to see if I can see what it is exactly that is giving the problem :).
Last edited on by closed account z6A9GNh0
Topic archived. No new replies allowed.