首页 > cocos2dx触摸事件问题

cocos2dx触摸事件问题

  1. 下面是教程中正确的代码

  2.    bool TowerPanleLayer::init()

    {

       if(!Layer::init())
       {
           return false;
       }
          //初始化缓存帧
       auto cache = SpriteFrameCache::sharedSpriteFrameCache();
       cache->addSpriteFramesWithFile("TArrow-hd.plist","TArrow-hd.png");
       cache->addSpriteFramesWithFile("TPin-hd.plist","TPin-hd.png");
       cache->addSpriteFramesWithFile("TSun-hd.plist","TSun-hd.png");
          //定义菜单精灵
       this->sprite = Sprite::createWithSpriteFrame(cache->spriteFrameByName("select_01.png"));
       this->addChild(sprite,0);
           //定义菜单项精灵
       this->sprite1 = Sprite::createWithSpriteFrame(cache->spriteFrameByName("Arrow01.png"));
       this->sprite1->setPosition(- this->sprite1->getContentSize().width,- this->sprite1->getContentSize().height);
       this->addChild(sprite1,1);
    
       this->sprite2 = Sprite::createWithSpriteFrame(cache->spriteFrameByName("Pin01.png"));
       this->sprite2->setPosition(0,- this->sprite2->getContentSize().height);
       this->addChild(sprite2,1);
    
       this->sprite3 = Sprite::createWithSpriteFrame(cache->spriteFrameByName("Sun01.png"));
       this->sprite3->setPosition(this->sprite3->getContentSize().width,- this->sprite3->getContentSize().height);
       this->addChild(sprite3,1);
       //监听器
       auto touchListener = EventListenerTouchOneByOne::create();
       touchListener->setSwallowTouches(true);
       touchListener->onTouchBegan = CC_CALLBACK_2(TowerPanleLayer::onTouchBegan,this);
       touchListener->onTouchEnded = CC_CALLBACK_2(TowerPanleLayer::onTouchEnded,this);
           //到下面这个位置,我就不懂了
       _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener,sprite1);
       _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener->clone(),sprite2);
       _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener->clone(),sprite3);    
       return true;

    }

    bool TowerPanleLayer::onTouchBegan(Touch touch,Event event)
    {

       auto target = static_cast<Sprite*>(event->getCurrentTarget());
       
       Point locationInNode = target->convertTouchToNodeSpace(touch);
       Size size = target->getContentSize();
       Rect rect = Rect(0, 0, size.width, size.height);
       
       if (rect.containsPoint(locationInNode))
       {
           target->setOpacity(180);
           return true;
       }
       return false;
       //return true;

    }

    void TowerPanleLayer::onTouchEnded(Touch touch,Event event)
    {

       auto tagert = static_cast<Sprite*>(event->getCurrentTarget());
       if(tagert == sprite1)
       {
           this->setChooseTower(ARROW);
       }
       else if(tagert == sprite2)
       {
           this->setChooseTower(PIN);
       }
       else if(tagert == sprite3)
       {
           this->setChooseTower(SUN);
       }
       else 
       {
           this->setChooseTower(ANOTHER);
       }

    }

3.当我修改代码后就不对了,无论我点哪个菜单选项,都会选在sprite3上

bool TowerPanleLayer::onTouchBegan(Touch* touch,Event* event)
{
    //auto target = static_cast<Sprite*>(event->getCurrentTarget());
    //Point locationInNode = target->convertTouchToNodeSpace(touch);
    //Size size = target->getContentSize();
    //Rect rect = Rect(0, 0, size.width, size.height);
    //if (rect.containsPoint(locationInNode))
    //{
    //    target->setOpacity(180);
    //    return true;
    //}
    //return false;
    return true;
}

我觉得我注释掉的代码可有可无,但为什么不能去掉。
我注释掉的代码的作用是什么?
谢谢您阅读到这。


auto target = static_cast<Sprite*>(event->getCurrentTarget());//获取到你点击的对象具体是哪个精灵
Point locationInNode = target->convertTouchToNodeSpace(touch);//获取到点击位置在你这个对象的相对位置
Size size = target->getContentSize();//对象内容大小,在后面用来判断是否点中了某对象的区域
Rect rect = Rect(0, 0, size.width, size.height);//包含这个对象的矩形区域
if (rect.containsPoint(locationInNode))//矩形局域检测,点是否在矩形内部
{//在内部就执行下面,设置透明度给你看到,并且前面设置了吞噬(setSwallowTouches),那么这里传递return true会传递消息到你的onTouchEnded,并且其他注册了精灵对象的会收不到点击事件了,被吞噬了。
    target->setOpacity(180);
    return true;
}
return false;

希望对你有用!


onTouchBegan返回值决定是否将按键响应延场景树往下传。原来的代码用于判断有没有按到sprite 上。按到了刚设置半透明并不再往下传了,去掉判断后强制响应场景中最后的sprite3并不再往下传事件了。

【热门文章】
【热门文章】