Touch on sprite

Hi. This code is supposed to handle touches and call a function but it does not.

auto dispatcher = Director::getInstance()->getEventDispatcher();
    auto listener = EventListenerTouchOneByOne::create();
    listener->onTouchBegan = [&](Touch* touch, Event* event){
        auto sprite = event->getCurrentTarget();
        Point pt = touch->getLocation();
        Rect recTemp = sprite->boundingBox();
        if (recTemp.containsPoint(pt)) {
            CC_CALLBACK_1(GameScene::onKeyReleased, this);
        }
        return false;
    };
    dispatcher->addEventListenerWithSceneGraphPriority(listener, pauseSprite);

onKeyReleased is:

void GameScene::onKeyReleased(cocos2d::EventKeyboard::KeyCode keycode, cocos2d::Event *event)
{
    auto scene = PauseScene::createScene();
    Director::getInstance()->replaceScene( TransitionFade::create( TRANSITION_TIME, scene ) );
}

Those all are in GameScene.cpp, in the same file. The sprite isn’t responding to the touches. What is wrong with it? I appreciate your help.

so I do this:

auto listener = cocos2d::EventListenerTouchOneByOne::create();
    listener->setSwallowTouches(true);

    listener->onTouchBegan = [&](cocos2d::Touch* touch, cocos2d::Event* event)
    {
        cocos2d::Vec2 p = touch->getLocation();
        cocos2d::Rect rect = this->getBoundingBox();

        if(rect.containsPoint(p))
        {
            PurpleKernel::touchEvent(touch);
            return true;
        }

        return false;
    };

    listener->onTouchEnded = [=](cocos2d::Touch* touch, cocos2d::Event* event)
    {
    };

    cocos2d::Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);

You could change this line

CC_CALLBACK_1(GameScene::onKeyReleased, this);

to something like this:

onKeyReleased(EventKeyboard::KeyCode::KEY_ESCAPE, nullptr);

But be careful in case you want to use event in onKeyReleased in the future… :wink:

1 Like

Thank you very much. Why should i be careful using it? Can you explain?

Well, you’re (kind of) misusing onKeyReleased here. onKeyReleased's task is to handle keyboard input. It takes a keycode representing the key that was pressed and an event with additional info about the event that triggered onKeyReleased. In your case, there is no event, so you’re passing nullptr. If you decide to use event in the future you might not remember this fact and could run in some access violation if you don’t check for nullptr…

Actually, I don’t think, using onKeyReleased the way you do is a good design choice. You should create a new method for this… for example:

void GameScene::startPauseScene()
{
    auto scene = PauseScene::createScene();
    Director::getInstance()->replaceScene( TransitionFade::create( TRANSITION_TIME, scene ) );
}

Then you can call this function in onKeyReleased and in your lambda:

void GameScene::onKeyReleased(cocos2d::EventKeyboard::KeyCode keycode, cocos2d::Event *event)
{
   startPauseScene();
}

and

if (recTemp.containsPoint(pt)) {
    startPauseScene();
}

Then you don’t have to worry about future changes… :wink:
And it’s cleaner code.

1 Like

Right. Thank you again :slight_smile:

Also remember to return true from

if (recTemp.containsPoint(pt))[
...
}
2 Likes