Cocos2d-x 3.2 EventListener在子Sprite中不起作用

时间:2014-07-31 14:49:41

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

简单地说,我有两个精灵,其中一个是另一个的孩子。 每个精灵都与事件监听器相关,如there所述。

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

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

我惊慌失措,不知道出了什么问题以及如何解决问题。请帮忙。

这是一个简单的例子:

·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非常相似,因为这是一个非常简单的例子。

1 个答案:

答案 0 :(得分:1)

我认为您的问题是,当您致电

时,您正在吞下父精灵中的触摸事件
listener->setSwallowTouches(true);

如果您使用PlaySprite::addEvent()false内拨打电话,我怀疑一切都会为您解决。