【问题标题】:Cocos2d-x 3.2 EventListener not working in child SpriteCocos2d-x 3.2 EventListener 在子 Sprite 中不起作用
【发布时间】:2014-07-31 14:49:40
【问题描述】:

简而言之,我有两个精灵,其中一个是另一个的孩子。 每个精灵都与事件侦听器相关,如there 所述。

如果两个精灵都是图层的子节点,那么一切都很好。

现在我需要第二个精灵是第一个精灵的子节点。 但在这种情况下,第二个精灵一般不会响应事件。

我很恐慌,不知道出了什么问题以及如何解决它。请帮忙。

这是一个简化的例子:

.h

    #ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::Layer
{
public:
    // there's no 'id' in cpp, so we recommend returning the class instance pointer
    static cocos2d::Scene* createScene();

    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();  

    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);

    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);
};

class PlaySprite : public cocos2d::Sprite
{
public:
    virtual bool init();

    CREATE_FUNC(PlaySprite);

    void addEvent();

    bool touchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
};

class InPlaySprite : public cocos2d::Sprite
{
public:
    virtual bool init();

    CREATE_FUNC(InPlaySprite);

    void addEvent();

    bool touchBegan(cocos2d::Touch* touch, cocos2d::Event* event);
};

#endif // __HELLOWORLD_SCENE_H__

.cpp

    #include "HelloWorldScene.h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();

    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }

    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

    // add a "close" icon to exit the progress. it's an autorelease object
    auto closeItem = MenuItemImage::create(
                                           "CloseNormal.png",
                                           "CloseSelected.png",
                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
    closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                                origin.y + closeItem->getContentSize().height/2));
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1);

    /////////////////////////////
    // 3. add your codes below...


    auto sprite1 = PlaySprite::create();
    this->addChild(sprite1);

    auto sprite2 = InPlaySprite::create();

    // !!!
    sprite1->addChild(sprite2);

    return true;
}


void HelloWorld::menuCloseCallback(Ref* pSender)
{
    Director::getInstance()->end();
}


bool PlaySprite::init()
{
    if(!Sprite::init())
        return false;

    // to do

    Size visibleSize = Director::getInstance()->getVisibleSize();

    this->setTexture("1.png");
    this->setPosition(visibleSize.width / 2, visibleSize.height / 2);

    this->addEvent();

    return true;
}

void PlaySprite::addEvent()
{
    auto listener = EventListenerTouchOneByOne::create();

    listener->setSwallowTouches(true);

    listener->onTouchBegan = [=](Touch* touch, Event* event)
        {
            return this->touchBegan(touch, event);
        };

    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}

bool PlaySprite::touchBegan(Touch* touch, Event* event)
{
    auto target = (Sprite* ) event->getCurrentTarget();

    auto rect = this->getBoundingBox();

    if(rect.containsPoint(touch->getLocation()))
    {
        this->setTexture("1d.png");

        return true;
    }

    return false;
}


bool InPlaySprite::init()
{
    if(!Sprite::init())
        return false;

    // to do

    Size visibleSize = Director::getInstance()->getVisibleSize();

    this->setTexture("2.png");
    this->setPosition(150.0f, 150.0f);

    this->addEvent();

    return true;
}

void InPlaySprite::addEvent()
{
    auto listener = EventListenerTouchOneByOne::create();

    listener->setSwallowTouches(true);

    listener->onTouchBegan = [=](Touch* touch, Event* event)
        {
            return this->touchBegan(touch, event);
        };

    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}

bool InPlaySprite::touchBegan(Touch* touch, Event* event)
{
//  auto target = (Sprite* ) event->getCurrentTarget();

    auto rect = this->getBoundingBox();

    if(rect.containsPoint(touch->getLocation()))
    {
        this->setTexture("2d.png");

        return true;
    }

    return false;
}

PlaySprite 和 InPlaySprite 类非常相似,因为这是一个非常简化的示例。

【问题讨论】:

    标签: c++ cocos2d-x cocos2d-x-3.0


    【解决方案1】:

    我认为您的问题是您在调用时正在吞噬父精灵中的触摸事件

    listener->setSwallowTouches(true);
    

    如果您在 PlaySprite::addEvent() 内部使用 false 进行调用,我怀疑事情会为您解决。

    【讨论】:

    • 很抱歉迟到了,由于硬盘驱动器故障,我的计算机无法使用。非常感谢您的帮助 !!它确实解决了问题!))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-12
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多