Correct way of handling key down

Moderator
Posts: 133
Joined: 2008.05
Post: #1
Is this correct...
Here are event handlers for keyUp and keyDown
Code:
static pascal OSStatus KeyHoldDown(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUser)
{
    #pragma unused(inCallRef, inEvent)
    MightyMan* blah = (MightyMan*)inUser;
    KeyMap keyMap;
       GetKeys(keyMap);
    if(WasKeyPressed(kVirtualLeftArrowKey,keyMap))
    {
        blah->movingDirection[align=left] = true;
    }
    if(WasKeyPressed(kVirtualRightArrowKey,keyMap))
    {
        blah->movingDirection[align=right] = true;
    }
    if(WasKeyPressed(kVirtualUpArrowKey,keyMap))
    {
        blah->movingDirection[UP] = true;
    }
    if(WasKeyPressed(kVirtualDownArrowKey,keyMap))
    {
        blah->movingDirection[DOWN] = true;
    }
    return noErr;
}
static pascal OSStatus KeyUp(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUser)
{
    #pragma unused(inCallRef, inEvent)
    MightyMan* blah = (MightyMan*)inUser;
    KeyMap keyMap;
       GetKeys(keyMap);
    if(!WasKeyPressed(kVirtualLeftArrowKey,keyMap))
    {
        blah->movingDirection[align=left] = false;
    }
    if(!WasKeyPressed(kVirtualRightArrowKey,keyMap))
    {
        blah->movingDirection[align=right] = false;
    }
    if(!WasKeyPressed(kVirtualUpArrowKey,keyMap))
    {
        blah->movingDirection[UP] = false;
    }
    if(!WasKeyPressed(kVirtualDownArrowKey,keyMap))
    {
        blah->movingDirection[DOWN] = false;
    }    
    return noErr;
}

And when the game updates...

Code:
    if(movingDirection[UP])
{
    sprite->HandleMoveUp();
}
else if(sprite->direction == UP)
    sprite->HandleStopUp();
        
if(movingDirection[DOWN])
{
    sprite->HandleMoveDown();
}
else if(sprite->direction == DOWN)
    sprite->HandleStopDown();
        
if(movingDirection[align=right])
{
    sprite->HandleMoveRight();
}
else if(sprite->direction == RIGHT)
    sprite->HandleStopRight();
        
if(movingDirection[align=left])
{
    sprite->HandleMoveLeft();
}
else if(sprite->direction == LEFT)
    sprite->HandleStopLeft();

And yes I know there is no diagonal Smile
Quote this message in a reply
Moderator
Posts: 365
Joined: 2002.04
Post: #2
Uh, no. You're using GetKeys() in an key event handler, which makes no sense at all. The whole point of a key event handler is that the event contains information about which key has been pressed or released.

I normally just use GetKeys() on its own, so I'm not sure precisely what you'll need to do in this circumstance, but elsewhere I use kEventRawKeyUp events to detect when the player presses the escape key, like this:

Code:
char c;
GetEventParameter(inEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &c);

if(c == kASCIIEscapeCharacter)
{
    // etc.
}

If you don't know which event parameters to look up for the events you're receiving, read the CarbonEvents.h header.

Neil Carter
Nether - Mac games and comic art
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #3
Haha. Yeah, you're totally right, that works a lot better and seems a tad faster in it's response time. As for the rest of the code... does that look ok?
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #4
It's probably better to use raw key up and down events instead, and as ncarter says, get the info out of the events rather than using GetKeys...
Quote this message in a reply
Moderator
Posts: 365
Joined: 2002.04
Post: #5
Quote:Originally posted by LongJumper
As for the rest of the code... does that look ok?

I dunno, does it work? Smile

I pass my control information to the player object all together in a single struct. I don't know if it's better or worse than the way you're doing it. I have a feeling my way would negate the benefit of having an event driven system, so you're probably doing the right thing.

Neil Carter
Nether - Mac games and comic art
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #6
Yeah, I guess it does work. If only I could make the drawing faster now.
Quote this message in a reply
Oldtimer
Posts: 834
Joined: 2002.09
Post: #7
Is there any real reason to use GetKeys? I suppose that the benefits of not having to wait for a rawkeydown event is pretty negligble nowadays?
Quote this message in a reply
Moderator
Posts: 365
Joined: 2002.04
Post: #8
I still use GetKeys() because I still want to support Mac OS 9. If you try to run your game under a Carbon Event loop on OS9, it can get pretty jerky and unpleasant. So, under OS9 I use a busy loop with no event handling, and under OSX I use Carbon Events to monitor system activity with a Carbon Timer running the game loop. I use GetKeys() because it works perfectly well in both circumstances, and I see no reason to change it for now.

Oh yeah, before anyone tells me to drop support for OS9 - go write your own game! Rasp

Neil Carter
Nether - Mac games and comic art
Quote this message in a reply
Oldtimer
Posts: 834
Joined: 2002.09
Post: #9
Well, the problem with GetKeys is that it at times only registers two keys held down, so if you're writing a game where you have to run, jump and shoot at the same time, you apparently have to spread them out a little over the keyboard.
Quote this message in a reply
Moderator
Posts: 365
Joined: 2002.04
Post: #10
I know, but the two keys limit is only a major problem on the oldest of keyboards. Modern keyboards (including most of the later ADB models) support a minimum of two keys, and in most cases they can handle between four and six before they start to misbehave. The precise number of keys you can press at once depends upon where the keys are located in the keymap - certain combinations of keys always block certain other keys. In any case, the modifier keys are always independent, so you can add four other keys without affecting anything.

It's down to the player to choose sensible keys, however. If you decide to put all your movement keys on the same row of the keyboard, they'll probably block one another.

I think this is actually a hardware limitation, and I'd be surprised if keyboard events aren't affected in the same way. Has anyone ever tested this?

Neil Carter
Nether - Mac games and comic art
Quote this message in a reply
Oldtimer
Posts: 834
Joined: 2002.09
Post: #11
I just now that the keyboard that came with the G4 towers can't handle H, D and C together... I'll try switching to key events tonight and get back here on it.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #12
GetKeys is buggy in Mac OS X 10.2.x. Under certain circumstances (involving the user having authenticated as an admin user earlier), GetKeys stops returning any information. The only solution from the user's perspective is to reboot.

GetKeys also has the problem that it's very framerate dependent. If your frame takes a particularly long time for whatever reason, it's very easy to miss a press-release or a release-repress. Not good if your controls involve hammering buttons...
Quote this message in a reply
w_reade
Unregistered
 
Post: #13
Logging out and back in fixes the problem, I'm told, although it's still a hassle.

I personally believe that key up/down events sometimes don't fire when they're supposed to. Whenever I've tried to handle them, I've been able to make a key "stick" and believe it's down when it isn't, provided I abuse my keyboard enough. t's perfectly possible - likely, even - that it's simply down to my own lameness in handling them, but I also believe that I once made Smiley Tag misbehave with sufficient key-hammering.

So I use GetKeys(), because I know it isn't my fault when it breaks, and the fix is trivial.

..and - ha! BobimusPrime is dropping keyUp events too! I haven't been hallucinating! (see General Programming)
Quote this message in a reply
Moderator
Posts: 365
Joined: 2002.04
Post: #14
I haven't seen the GetKeys() bug for a long time - I thought it had been fixed in a system update.

I've also never had a problem with dropping keystrokes, mainly because my games always run at incredibly high frame rates on every machine that I support!

Neil Carter
Nether - Mac games and comic art
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #15
OneSadCookie Wrote:GetKeys is buggy in Mac OS X 10.2.x. Under certain circumstances (involving the user having authenticated as an admin user earlier), GetKeys stops returning any information. The only solution from the user's perspective is to reboot.

Has anyone noticed this bug's revival in 10.3.7? Some apps stop responding to keyboard input here after using the system for a while...
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  NSWindow frame message not returning correct values after moving the window Svarog 6 4,822 Jan 7, 2007 06:41 PM
Last Post: OneSadCookie
  CB Key handling skyhawk 6 3,581 Aug 12, 2003 10:13 AM
Last Post: kelvin