cocos2d-x

How to make Keyboard button to continuously call callback function when hold-pressed Cocos2d-x


I would like to ask how to make a particular sprite to move when the keyboard button is pressed?

I have this following code:

keyBoardListener->onKeyPressed = [](EventKeyboard::KeyCode keyCode, Event* event)
    {
        switch (keyCode)
        {
        case EventKeyboard::KeyCode::KEY_LEFT_ARROW:
        case EventKeyboard::KeyCode::KEY_A:
            xMovement--;
            break;
        case EventKeyboard::KeyCode::KEY_RIGHT_ARROW:
        case EventKeyboard::KeyCode::KEY_D:
            xMovement++;
            break;
        case EventKeyboard::KeyCode::KEY_UP_ARROW:
        case EventKeyboard::KeyCode::KEY_W:
            yMovement++;
            break;
        case EventKeyboard::KeyCode::KEY_DOWN_ARROW:
        case EventKeyboard::KeyCode::KEY_S:
            yMovement--;
            break;
        }
    };

The problem with this is that every time I pressed a button, it doesn’t perform this function again even though I hold-press a button.


Solution

  • First, add two methods to your scene class: (https://stackoverflow.com/a/43842348/13785815)

    class HelloWorld : public cocos2d::Scene
    {
        // ...
    private:
        // For scheduling
        void scheduleMotions(); // schedule checks
        void checkMotions();    // does the check
    };
    

    scheduleMotions() should be like:

    void HelloWorld::scheduleMotions() {
        auto sequence = Sequence::createWithTwoActions(
            DelayTime::create(0.4f), 
            CallFunc::create([&]() { checkMotions(); scheduleMotions(); })
        );
        runAction(sequence);
    }
    

    Every time the timer expires, checkMotions() will run before the action is registered again. checkMotions() should contain the logic of checking key status and adjust the sprites' positions.

    Second, call scheduleMotions() at the the end of init() method of your scene. This will trigger the call of checkMotions() every 400 ms (as is given in the code above).

    Third, modify keyBoardListener->onKeyPressed and keyBoardListener->onKeyReleased callbacks so that every relevant key press/release event is recorded. You can use a map or an array to keep track of that. The information can be used in checkMotions().