无法在多平台cocos2d-x应用程序中使触摸生效

9

我正在尝试使用最新版本的cocos2d-x创建一个简单的应用程序,但是由于某种原因无法将我的触摸连接起来。以下是我的类:

class GameLayer : public cocos2d::Layer
{
public:
    static cocos2d::Layer* createLayer();
    void update(float dt);
    virtual bool init();
    CREATE_FUNC(GameLayer);
private:
    bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
    void onTouchMoved(cocos2d::Touch* touch, cocos2d::Event* event);
    void onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* event);
};

cocos2d::Layer* GameLayer::createLayer()
{
    GameLayer *layer = GameLayer::create();

    return layer;
}

bool GameLayer::init()
{
    if (!cocos2d::Layer::init())
    {
        return false;
    }

    this->schedule(schedule_selector(GameLayer::update));
    this->setTouchEnabled(true);

    return true;
}

void GameLayer::update(float dt)
{

}

bool GameLayer::onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event)
{
    cocos2d::log("You touched %f, %f", touch->getLocationInView().x, touch->getLocationInView().y);
    return true;
}
void GameLayer::onTouchMoved(cocos2d::Touch* touch, cocos2d::Event* event)
{

}
void GameLayer::onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* event)
{

}

我注意到当我调用setTouchEnabled函数时,内部标志_running会被设置为false,导致无法注册我的触摸事件。然而,我似乎无法弄清楚这是为什么。是我调用的方式不正确还是顺序不对?

1个回答

19

目前,cocos2dx正经历着库的重大改革,包括触摸注册和传播等方面都发生了很多变化。以下是现在的工作原理:

GameLayer.h

class GameLayer : public cocos2d::Layer
{
public:
    static cocos2d::Layer* createLayer();
    void update(float dt);
    virtual bool init();
    CREATE_FUNC(GameLayer);

private:
    virtual void onEnter();
    virtual void onExit();

    bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
    void onTouchMoved(cocos2d::Touch* touch, cocos2d::Event* event);
    void onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* event);
};

GameLayer.cpp

cocos2d::Layer* GameLayer::createLayer()
{
    GameLayer *layer = GameLayer::create();

    return layer;
}

bool GameLayer::init()
{
    if (!cocos2d::Layer::init())
    {
        return false;
    }

    this->schedule(schedule_selector(GameLayer::update));

    return true;
}

void GameLayer::onEnter()
{
    Layer::onEnter();

    // Register Touch Event
    auto dispatcher = Director::getInstance()->getEventDispatcher();
    auto listener = EventListenerTouchOneByOne::create();

    listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this);
    listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved, this);
    listener->onTouchEnded = CC_CALLBACK_2(GameLayer::onTouchEnded, this);

    dispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}

void GameLayer::onExit()
{
    // You don't need to unregister listeners here as new API
    // removes all linked listeners automatically in CCNode's destructor
    // which is the base class for all cocos2d DRAWING classes

    Layer::onExit();
}

void GameLayer::update(float dt)
{

}

bool GameLayer::onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event)
{
    cocos2d::log("You touched %f, %f", touch->getLocationInView().x, touch->getLocationInView().y);
    return true;
}

void GameLayer::onTouchMoved(cocos2d::Touch* touch, cocos2d::Event* event)
{

}

void GameLayer::onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* event)
{

}

希望这能帮到你!

看起来 registerWithTouchDispatcher 已经被弃用了,而且 getTouchDispatcher()Director 上也不再存在了。你有什么想法现在的等效方法是什么? - Kevin DiTraglia
API又被更新了。 :) 请看一下我更新的答案。 - nomann
感谢您的帮助,我正在使用他们主页上刚发布的3.0版本,而不是在Github上的版本(它也改变了一切)。因此,我的版本也没有eventListener。我将尝试升级到他们在Github上的版本,如果成功了,我会及时通知您。 - Kevin DiTraglia
网站上下载的内容和Github上的内容差别很大,终于把它搞定了,现在这段代码可以运行了。再次感谢你的帮助。 - Kevin DiTraglia
你说过库会在析构函数中自动注销节点,但是每次将节点添加到场景中时都会添加 EventListener。(例如,如果我们正在池化对象或其他操作,我们会不必要地替换已经存在的 eventLister,因为我们从未到达析构函数)。 - Mazyod
我确实这样做了,但对我来说不起作用 :/。我正在使用Cocos2d-x v3.7。 - user365314

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接