Jump to content

  • Log In with Google      Sign In   
  • Create Account

can I go without events?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
13 replies to this topic

#1 fir   Members   -  Reputation: -456

Like
0Likes
Like

Posted 11 March 2014 - 11:52 AM

i wonder if in winapi win32 game programming I can go without events

for keyboard and for mouse - If i would like to ask for keyboard and mouse state in each frame and totally ignore events?

 

- are there easy ways to read mouse position in other way than by event?

- are some things worse when i would use each frame checking than events servicing?

 



Sponsor:

#2 EricsonWillians   Members   -  Reputation: 288

Like
0Likes
Like

Posted 11 March 2014 - 12:28 PM

In Khan Academy's Javascript programs there are native "mouseX" and "mouseY" variables that, when used, already give you the actual mouse position. I don't know the API you've mentioned, but It's not common to have these variables by default. Events are the main way to deal with it. Nevertheless, take a good look at the API and search for it.


Edited by EricsonWillians, 11 March 2014 - 12:29 PM.

Creator and only composer at Poisone Wein and Übelkraft dark musical projects:

 


#3 TheChubu   Crossbones+   -  Reputation: 4761

Like
0Likes
Like

Posted 11 March 2014 - 12:39 PM

Here MSDN Raw Input


"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

 

My journals: dustArtemis ECS framework and Making a Terrain Generator


#4 Aardvajk   Crossbones+   -  Reputation: 6208

Like
0Likes
Like

Posted 11 March 2014 - 01:05 PM

I use GetAsyncKeyState on my update loop directly. If you implement this with events you normally end up just reimplementing an array of bools for each key state anyway so seems pointless.

The problems arise when it comes to abstracting input away from being directly tied to a given device. Event based approach can be easier to decouple.

#5 samoth   Crossbones+   -  Reputation: 5033

Like
1Likes
Like

Posted 11 March 2014 - 01:15 PM

You will at least have to handle the events for the window, or you will be unable to move or close it.

 

Other than that, you can do completely without events, but it is a really, really, really bad idea. User uses a different keyboard (different, as in language) and you're screwed. User clicks very fast, and you miss the click. User does <insert one of 1000 other things> and you're screwed.

 

Events work, and they work well. Plus, they work with different languages, with different devices, mappings, resolutions, different anything. And they don't burn CPU time polling.

 

One good example where polling keyboard state results in a total fuckup is when e.g. US American programmers assume that "/" is a proper key and uses it for some interactive control, and your end user has a German keyboard. With events, it is a nuisance since you must hold down shift before pressing the key (holding it works, at least), but if the program samples the keyboard state, the program is totally unusable (there simply isn't a way to press any combination of keys that works). Similar for []{}\.


Edited by samoth, 11 March 2014 - 01:28 PM.


#6 warnexus   Prime Members   -  Reputation: 1502

Like
0Likes
Like

Posted 11 March 2014 - 01:17 PM

It is certainly much easier to handle input with events. Events are built into the library and will make your programming journey slightly easier. The only thing you need to handle yourself is how to apply the correct logic given the built-in event functionality.


Edited by warnexus, 11 March 2014 - 04:08 PM.


#7 fir   Members   -  Reputation: -456

Like
0Likes
Like

Posted 11 March 2014 - 01:45 PM

You will at least have to handle the events for the window, or you will be unable to move or close it.

 

Other than that, you can do completely without events, but it is a really, really, really bad idea. User uses a different keyboard (different, as in language) and you're screwed. User clicks very fast, and you miss the click. User does <insert one of 1000 other things> and you're screwed.

 

Events work, and they work well. Plus, they work with different languages, with different devices, mappings, resolutions, different anything. And they don't burn CPU time polling.

 

especially interesting is this 'user clicks to fast' - keyboard and mouse, Do mouse programmed by polling can fail in some cases? Or in general it would work ok?



#8 samoth   Crossbones+   -  Reputation: 5033

Like
0Likes
Like

Posted 11 March 2014 - 02:10 PM

Do mouse programmed by polling can fail in some cases? Or in general it would work ok?
If you have a reasonable frame rate, it will in general (most of the time) work. But what if your frame rate isn't so great or you have a bit of lag for some reason? If the state that you are looking for (say, button down) isn't there the very moment you look, you will miss it.

 

The nature of polling is "right now, check what the state is" whereas the nature of events is "whenever user clicks, you get exactly 1 event, and you can consume it any time you want". With polling, it is in principle always possible to miss something. With events, it just isn't possible (unless the operating system is FUBAR).



#9 cdoubleplusgood   Members   -  Reputation: 848

Like
0Likes
Like

Posted 11 March 2014 - 03:27 PM


i wonder if in winapi win32 game programming I can go without events

May I ask: Why would you do that?



#10 fir   Members   -  Reputation: -456

Like
0Likes
Like

Posted 11 March 2014 - 03:46 PM

 

Do mouse programmed by polling can fail in some cases? Or in general it would work ok?
If you have a reasonable frame rate, it will in general (most of the time) work. But what if your frame rate isn't so great or you have a bit of lag for some reason? If the state that you are looking for (say, button down) isn't there the very moment you look, you will miss it.

 

The nature of polling is "right now, check what the state is" whereas the nature of events is "whenever user clicks, you get exactly 1 event, and you can consume it any time you want". With polling, it is in principle always possible to miss something. With events, it just isn't possible (unless the operating system is FUBAR).

 

 

so say i got a 5 seconds lag in my app and user types the tekst

(say 30 keystrokes) will it be queued in windows and then flushed as a set of 30 keydowns ?

 

it was always unclear to me 



#11 fir   Members   -  Reputation: -456

Like
0Likes
Like

Posted 11 March 2014 - 03:49 PM

 


i wonder if in winapi win32 game programming I can go without events

May I ask: Why would you do that?

 

Im not sure if i would or not, just wonder - in some cases polling

could be easier than event servicing (when you poll all you polling routines are independant each another, when you service an event you must wrote some call trees or lists to service them)



#12 carangil   Members   -  Reputation: 490

Like
1Likes
Like

Posted 16 March 2014 - 11:23 AM

The problem with polling is you can miss something.  If the user presses and releases a key before you get around to polling again, you will completely miss it.  Mouse clicks are fast, and if your frame rate stalls for whatever reason (not even your program's fault; maybe the dreaded McAfee just started to do an update in the background...) and you're out of luck.

 

I get that you want to just poll to check if a key is pressed in your code.  I like to do that too.  But it's easy to do with events:  (Rough pseudocode; haven't done win32 events in a while:

bool keystate[MAX_KEY];
bool mousebutton[MAX_MOUSEBUTTON];
int  mousex, mousey;

#define MOUSE_LEFT 0
#define MOUSE_RIGHT 1


eventhandler(...) 
{


  while (event = getnextevent(...)) 
  {

    if(event==KEY_DOWN && keycode < MAX_KEY)
        keystate[keycode] = 1;

    if(event==KEY_UP && keycode < MAX_KEY)
        keystate[keycode] = 0;

    if (event==L_MOUSE_DOWN)
         mousebutton[MOUSE_LEFT] = 1;
    
    if (event==L_MOUSE_UP)
         mousebutton[MOUSE_LEFT] = 0;

    if (event==MOUSE_MOVE)
    {  
        mousex = event_mouse_x;
        mousey = event_mouse_y;
    }
  }
}

Then, in your code you can do  if(keystate[KEY_L_CTRL]) all you want.  Or sprite.draw(mousex, mousey).

 

The above could still suffer from missing presses.  If the system slows down, and you call the event loop once per frame, if a keydown AND a keyup press bunch up against each other, then in one frame's processing of events you would set, and unset a single key in the same call to the loop.  One way to do that is handle the player's inputs in the event handler itself:

   if(event==KEY_DOWN && keycode < MAX_KEY)
   {
        keystate[keycode] = 1;
  
        if (keycode == playerconfig.firekey)
            player.fire=1;

        if (keycode == playerconfig.jump)
            player.jump= 1;
   }

This way the event loop is looking for particular events, and sets those flags in the player object.  Each frame, after the event handler is run, when the player's control code is run, it checks it's action flags and does the appropriate action.  This way you can't miss a jump or fire event, even if the next event is the queue is releasing the button.

 

You can abstract that completely and do this:


while (event = getnextevent(...))
{
    memset(keypressed, 0, sizeof(keypressed)); //clear pressed events

    if(event==KEY_DOWN && keycode < MAX_KEY)
    {
        keystate[keycode] = 1;
        keypressed[keycode] = 1;
    }

    if(event==KEY_UP && keycode < MAX_KEY)
        keystate[keycode] = 0;

}

Now, you can't miss an event.  If the key was pressed at all since the last frame, keypressed will be '1'.  And if its still pressed keystate will be '1'.  So now anywhere in your game loop you can do this:

if (keypressed[ player_config.fire_key] || ( keystate[player_config.fire_key] && (this_frame - last_fire_frame >= 20)) 
{
    last_fire_frame = this_frame;
    fire_a_bullet();
}

What this does is fire a bullet every time the player presses the fire key OR if the player holds down the fire key, one bullet every 20 frames.

 

Also this is all assume a single main loop thread, that looks something like this:

while(not_quitting)
{
   handle_window_events();
   increment_game_logic();
   draw();
}


#13 samoth   Crossbones+   -  Reputation: 5033

Like
1Likes
Like

Posted 16 March 2014 - 11:44 AM




so say i got a 5 seconds lag in my app and user types the tekst

(say 30 keystrokes) will it be queued in windows and then flushed as a set of 30 keydowns ?
Yes, even a bit more than that. You will get roughly 30 key down and key up events, plus roughly 30 char events.

 

By counting down and up events, you know which keys are still down (for things like game controls). By handling character events, you know what the user has typed (in terms of "text").

 

I used the wording "roughly" because one key press does not necessarily correspond to a virtual key (usually it does, but the weird AltGr key to the right of the space key for example sends two key-downs and two key-ups for every press). Further, keys and characters are different things. Several keys pressed can result in a single character, for example Shift+a will result in A, and ´+e will result in é whereas Shift+´+e will result in è, but Shift+´+Shift+e will give È.

 

This is extremely complicated to a point where it gets annoying and unmanageable (especially in some non-roman languages where ligatures are mandatory and completely different glyphs). The nice thing is, you don't need to care because what comes out on the WM_CHAR end is already correct, human-readable characters in whatever language the user has configured (which you maybe don't even can't pronounce).



#14 carangil   Members   -  Reputation: 490

Like
0Likes
Like

Posted 16 March 2014 - 12:19 PM

Using WM_CHAR will save you a lot of trouble.  If you are going to interpret the keystrokes as text (player is entering their name), you should use WM_CHAR.  For player actions, use WM_KEYDOWN/UP.  Pressing, holding and releasing a key will generate many events.  If you press and hold shift-A you will get this:

 

shift keydown

a keydown

capital A char (repeated several times)

capital A char (repeated several times)

capital A char (repeated several times)

a key up

shift key up






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS