Catching key-up events.

I’m working on an Ouya title, building on a keyboard for now. What I’m trying to do is a directional attack; holding a ‘wasd’ key to store a direction momentarily. Pressing ‘f’ while one of these keys is held will actually fire the attack.

To clear a stored direction, I need to catch key-up events, which it doesn’t look like the CIMEDispatcher sends to anything but an accelerometer abstraction. I hadn’t considered, until just now, looking into the accelerometer abstraction to see if I could somehow build around it to get what I need. Would there be a way to do that?

The alternative I’d been considering was to just extend CIMEDispatcher to dispatch keyUps to my delegate just as it dispatched keyDowns. I’ve done my best not to actually touch any parts of the engine, mostly because contributing to open-source projects still terrifies me. Unfortunately, it looks like I might have to, unless I want to do something really hacky.

Is there something else I’m not considering? Would that be a decent contribution to make to the project?

I am also looking at OUYA development and would like to use the keyboard as a stand in (on the OSX platform for now).

The best I can tell from searching the code is that keyboard support is almost present. By that I mean that both CCEventDispatcher,mm EAGLView.mm have the underpinnings for key events and there is a CCKeyboardEventDelegate defined but there doesn’t seem to be an a matching CCKeyboardDelegate class. What missing is code to bind it together.

My weakness is Obj-C so it is hard for me to figure out what needs to be done. I think CCDirector needs to have code for managing a keyboard dispatcher. I am still trying to figure out how to route the EGL key events through the system.

Just my 2c at the moment.

Update:

Note: this is for OSX developers.

I implemented a mirror of the CCTouchXXX classes for the Keyboard; instead of handling touches it handles keyboard events. Basically there are three new methods in the CCEGLViewProtocol class for propagating keyUp, keyDown and flagsChanged out to the keyboard delegate. Plus a slew of classes that pretty much mirror the cocos2dx classes.

keyboard_dispatcher/
CCKeyboardDelegate
CCKeyboardDispatcher
CCKeyboardHandler
CCKeyboard

In the same manner with touch events you would inherit from CCKeyboardDelegate class and then implement the three delegate methods:

class OverlayLayer: public CCLayer, public CCKeyboardDelegate {
...

#pragma mark Keyboard callbacks
    void keyUp(CCKeyboard* pKeyboard);
    void keyDown(CCKeyboard* pKeyboard);
    void flagsChanged(CCKeyboard* pKeyboard);
...
}

Example implementation:

some where in your construction of your layer:
        CCDirector* pDirector = CCDirector::sharedDirector();
        CCKeyboardDispatcher* dispatcher = pDirector->getKeyboardDispatcher();
        dispatcher->addTargetedDelegate(this, INT_MIN + 1);

some on the destruction of your layer
        CCDirector* pDirector = CCDirector::sharedDirector();
        CCKeyboardDispatcher* dispatcher = pDirector->getKeyboardDispatcher();
        dispatcher->removeDelegate(this);

an example of one of the delegates implemented.
    void OverlayLayer::keyUp(CCKeyboard* pKeyboard)
    {
        CCLog("OverlayLayer::keyUp %s", pKeyboard->getKeySequence());
        CCLog("OverlayLayer::keyUp %d", pKeyboard->getKey());
        if (pKeyboard->getKey() == 12)   // 12 = q key
        {
            CCDirector::sharedDirector()->end();

            #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
            exit(0);
            #endif
        }

    }

I am not sure if this can be contributed to the cocos2d-x branch or not but if anyone is interested let me know.

Cheers.