Toan Tran
Toan Tran

Reputation: 526

How to catch Press and Hold key board event in cocos2d-x?

I have a function here for moving a Sprite on every key pressed. Now I also want to move it on key hold instead of pressing the key repeatedly but I have no idea how to do it. Please guide me, your help is very much appreciated.

keyBoardListener->onKeyPressed = [](EventKeyboard::KeyCode keyCode, Event* event)
    {
        Vec2 location = event->getCurrentTarget()->getPosition();
        switch (keyCode)
        {
        case EventKeyboard::KeyCode::KEY_LEFT_ARROW:
        case EventKeyboard::KeyCode::KEY_A:
            event->getCurrentTarget()->setPosition(location.x - 10.0f, location.y);
            break;
        case EventKeyboard::KeyCode::KEY_RIGHT_ARROW:
        case EventKeyboard::KeyCode::KEY_D:
            event->getCurrentTarget()->setPosition(location.x + 10.0f, location.y);
            break;
        case EventKeyboard::KeyCode::KEY_UP_ARROW:
        case EventKeyboard::KeyCode::KEY_W:
            event->getCurrentTarget()->setPosition(location.x, location.y + 10.0f);
            break;
        case EventKeyboard::KeyCode::KEY_DOWN_ARROW:
        case EventKeyboard::KeyCode::KEY_S:
            event->getCurrentTarget()->setPosition(location.x, location.y - 10.0f);
            break;
        }
    };

Upvotes: 0

Views: 1836

Answers (1)

Boby
Boby

Reputation: 896

There's no event that triggers continuously when a key is pressed so one way to solve your problem is to have a global(or class or whatever) variable that tracks the movement on the x axis and one for the y axis.

To use only two variables and not a separate one for each key you could use 2 integers, let's say xMovement and yMovement and set their values to -1, 0 or 1, based on what keys are pressed. If xMovement is -1, move your sprite to the left, if it's 1 move it to the right and if it's 0 don't move it at all. Same thing for the y axis. To achieve this you should change your code like this:

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;
        }
    };

Now you should also add a key release event, where the incrementation/decrementation should be the opposite from the key pressed event:

keyBoardListener->onKeyReleased = [](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;
        }
    };

And now, to actually move you sprite, just do something like this in an update function that gets called every frame:

float newPosX = sprite->getPositionX() + (xMovement * 10.f);
float newPosY = sprite->getPositionY() + (yMovement * 10.f);
sprite->setPosition(newPosX, newPosY);

You'll also need some mechanism to ensure that xMovement and yMovement stay within the boundaries(in my example if you press both left arrow and the 'a' key the sprite will move twice as fast :P ), but this is just a rough example to demonstrate how to achieve continuous movement using keyboard events and an update function.

Upvotes: 2

Related Questions