Suppose I press the X button before I put in a number. I'm trying to get the third if, the getevent line, to understand that there is an event in the queue and act accordingly. This code serves no actual purpose, but I want to understand exactly how queues store data. I thought the queue would store the input, and then getevent would recognize that there's something in it and save the event in ev, which the next piece would pick up. But in practice, the line doesn't return true.

If somebody could explain this, rather than correct this, I'd appreciate it.

1ALLEGRO_EVENT event;//Creates event 2redraw =true;//Unsure of what the purpose of redraw is. I saw it in the 3//tutorial as well 4 5while(true){ 6while(!al_event_queue_is_empty(queue)){//While the event queue is 7//not empty... 8 9al_get_next_event(&event);//So what does this line do differently? 10//It gets the next event, but how is that 11//different from what I did? 12 13if(event.type == ALLEGRO_EVENT_TIMER){//If the event is AET... 14 input(&event);//It goes to input and passes the event's location... 15 logic();//What is this for? 16 redraw =true;//and again redraw. But redraw was always true. 17} 18} 19if(redraw){ 20 draw();//Then what's this? If this is where the line is drawn, 21//what does logic or input do? 22} 23al_rest(0.001);// rest 1 millisecond to avoid frying the cpu 24}

1ALLEGRO_EVENT event;//Creates event 2redraw =true;//Unsure of what the purpose of redraw is. I saw it in the 3//tutorial as well 4/* when redraw is true (which happens to be any time any logic is done), the scene is redrawn */ 5 6while(true){ 7while(!al_event_queue_is_empty(queue)){//While the event queue is 8//empty... 9 10/* NOT empty */ 11 12al_get_next_event(&event);//So what does this line do differently? 13//It gets the next event, but how is that 14//different from what I did? 15 16/* You peeked at the event which does not remove it from the queue. Peek event should rarely be used. The major difference between my code and yours is that events are popped off the queue in only one place, which will make your code much more maintainable in the long run */ 17 18if(event.type == ALLEGRO_EVENT_TIMER){//If the event is AET... 19 input(&event);//It goes to input and passes the event's location... 20 21/* input() should handle your events. For example it could check if the escape key is pressed and quit the game if so. In a complicated game, you could make input(), logic(), and draw() all function pointers (or put them in a class) and then you could have different components that all use the same loop. For example, a menu loop and a game loop */ 22 23 logic();//What is this for? 24 25/* This updates all of your game objects. It would usually check what happened in input() and move the player etc according to input. You could get away with combining logic and input in many games. You would also update anything that moves or reacts to /time/ in logic(). No drawing should be done in logic(). */ 26 27 redraw =true;//and again redraw. But redraw was always true. 28 29/* redraw should be set to false just before or after draw() in the if block. That was a mistake on my part */ 30 31} 32} 33if(redraw){ 34 draw();//Then what's this? If this is where the line is drawn, 35//what does logic or input do? 36 37/* This does nothing but draw the current state of the game. You should not update things relevant to time or input in here */ 38 39} 40al_rest(0.001);// rest 1 millisecond to avoid frying the cpu 41}

Take the next event out of the event queue specified, and copy the contents into ret_event, returningtrue. The original event will be removed from the queue. If the event queue is empty, return false andthe contents of ret_event are unspecified.

It still looks like it needs two parameters. Unless I'm misunderstanding something.

Let me see if I get the gist here; the event queue almost always has something in it; a timer. Every tick kicks the previous event out of the queue, so that's why the program wouldn't just "remember" the close button. But then why do we keep checking if the event is ALLEGRO_EVENT_TIMER and passing the location based off of that? The timer is always ticking, so all the program would do is act off of the autonomous timer and wouldn't react to user input like DISPLAY_CLOSE, right? I know that's not how it works, but then where am I misunderstanding this?

Queues can hold an infinite number of events. Nothing is removed from the queue until you take something out of it. Functions like al_get_next_event() and al_wait_for_event() removes the oldest element off the queue. You process that event. Then you wait for the next event, etc.

Let me run this one by you; The al_get_next_event sees the timer's tick, then gets rid of it and copies it into event. Have I got it so far?

But the rest of the code only works if the event type is ALLEGRO_EVENT_TIMER. The event holder can only hold one event, right? So what is the point of repeatedly going through input if all you're passing is the location of event, which is holding a timer tick? Or is there an difference between an event queue and ALLEGRO_EVENT event?

Is it just implied that there's more than one source? Here's what I'm seeing:

if (event.type == ALLEGRO_EVENT_TIMER) { input(&event);

The first line checks if the event holder is a timer tick, and the second line uses the event, that tick in input. All that is being used in this example is the ticks. Nothing but. There is no check if the event is a mouse input, or a display close. Why would the input be concerned with the timer? What purpose is there to carrying the timer tick to input? Or am I supposed to just use this as a template and add my own checks for events? Something like:

#SelectExpand

1al_get_next_event(&event); 2 3//This gets the tick from the timer. If the user gave an event beforehand, //then that event is stored just before the tick. 4 5if(event.type == ALLEGRO_EVENT_TIMER) 6 7//This checks if the event was a tick. Which means it's going to be checking //and triggering almost constantly. 8 9{ 10al_get_next_event(&event); 11 12//this gets the event next in the queue, which is the user's event because the //newest event was copied then destroyed by the last al_get_next_event. 13 14input(&event); 15 16//And this handles the user's event that was obtained in the last function. 17}

I don't understand Trent's example either. Perhaps he assumes you aren't going to use events to process input, and instead are just going to poll keyboard/mouse states and look at the event's timestamp.

For games it's easiest to process everything all at once per timer tick. While using events for input guarantees you won't lose any data, it means you have to somehow work that into your timer logic.

So some people take the lazy approach because it usually works without any problems: just check for timer ticks, and then use al_get_keyboard_state() to check if a certain key is pressed at that moment in time.

If you use input polling, you would still wait for a timer tick. Once you get a tick, you poll the keyboard state once and then check to see if whatever keys you are interested in were pressed.

The whole point of the timer tick is to make sure your game runs at a constant speed. If you know you are always checking 60 times per second, then you can simplify the rest of the logic. e.g., If the LEFT key is pressed during that tick, you might move your character over by exactly four pixels.

I followed the tutorials, and I get the individual examples, but the tutorials don't cover anything other than that specific example.

Anyway, I tried building a routine that checks whether there's input on the display, and passes the event to another function that deals with the event. Suppose I click on the X button;

#SelectExpand

1 2while(1) 3{ 4if(!al_is_event_queue_empty(eventqueue))//If there is something in the event queue... 5{ 6 7 8al_get_next_event(eventqueue, &ev);//Get the event 9 10if(ev.type==ALLEGRO_EVENT_TIMER)//This catches the tick right after the X button... 11{ 12 13al_get_next_event(eventqueue, &ev);//So this one should get the X button, the event just before the tick, right? 14 15 input (display, ev);//And then you send the event that should be the display close. 16 17 18} 19} 20 21}

Of course, this doesn't work. The input doesn't doesn't recognize that the event coming in is the display close.

I know that there are easier ways to pull this off, but I want to makes sure I can use this kind of setup to receive mouse or keyboard input. I still don't think I'm understanding the queue thing, or I'm not thinking properly. Sorry for sticking with this problem, but I'm going to have to learn this if I'm going to get close to designing my own game.

I think you're thinking about this the wrong way. Just because there is a timer event in the queue doesn't mean there is another event in the queue, so you may be waiting a while until that event comes.

The event queue will give you the oldest event first, and the rest in ascending order of time received. You could get a key / mouse click event at anytime, and it has nothing to do with a timer event or with a display close event. Don't expect events in any certain order, or you will be disappointed. They will be in the order they happened, but that is all you can expect.

1) When you get a timer event, you should probably set a redraw flag, and you need to update any objects that you have by the amount of time passed.

2) When you get a display close event, then break out of your program loop.

3) When you get other events, send them to each of your objects so they can deal with them as that is the input in your program.