cocos2d-xcocos2d-x-3.0

How to retrieve the visible texture from a png image in cocos2d-x


I am making a question answer game in which the answer images are made as sprites from png images.

The answer image is like this:

enter image description here

I am making rect on the image like this:

Rect rect = Rect(answerSprites.at(i)->getBoundingBox().origin.x,
                    answerSprites.at(i)->getBoundingBox().origin.y,
                    answerSprites.at(i)->getBoundingBox().size.width,
                    answerSprites.at(i)->getBoundingBox().size.height);

Then i am detecting touch on the rect as :

void HelloWorld::onTouchesBegan(const std::vector<Touch*>& touches,
        Event *unused_event) {
    auto target = static_cast<Sprite*>(unused_event->getCurrentTarget());
    auto touchPointBegan = (Touch*) touches.front();
    Vec2 locationBegan = touchPointEnded->getLocation();
    Point locationInNode = target->convertToNodeSpace(locationEnded);
    Size s = target->getContentSize();
        if (rect.containsPoint(locationInNode)) {
            log(“Correct Touch”);
        }
}

The code is working fine but the problem is that it is detecting the touch on the full png, but i want to detect the touch on the flower only. The flower can be at any position on the png.

How can i make the rect only on the flower?


Solution

  • Check the transparency of the touch location with this code:

    // Answer sprite
    m_sprite = Sprite::create("answer-1.png");
    m_sprite->setPosition( Vec2(winSize.width*.5, winSize.height*.5)  );
    addChild(m_sprite);
    
    bool HelloWorld::onTouchBegan(const cocos2d::Touch *touch, cocos2d::Event *event)
    {
        _originPoint = touch->getLocation();
        _destinationPoint = _originPoint;
    
        Vec2 locationInNode = m_sprite->convertToNodeSpace(touch->getLocation());
    
        Rect rect = Rect(m_sprite->getBoundingBox().origin.x,
                         m_sprite->getBoundingBox().origin.y,
                         m_sprite->getContentSize().width,
                         m_sprite->getContentSize().height);
    
    
        if (rect.containsPoint(touch->getLocation() )) {
    
            if (tapsOnNonTransparent(locationInNode, "answer-1.png" )) {
                log("Correct Touch");
            }
    
        }
    
        return true;
    }
    
    const bool HelloWorld::tapsOnNonTransparent( const cocos2d::Point& tap, const std::string &spritePath )
    {
        auto imgPtr = std::make_unique<cocos2d::Image>();
        imgPtr->initWithImageFile( spritePath );
    
        const int width = imgPtr ->getWidth();
        const int height = imgPtr ->getHeight();
    
        unsigned x = unsigned( tap.x ) % width;
        /// Don't forget to invert y coordinate.
        unsigned y = unsigned( height - tap.y ) % height;
        unsigned index = x + y * width;
        unsigned dataLen = imgPtr ->getDataLen();
        CCAssert( index < dataLen, "index is bigger than image size." );
        unsigned char* pixel = imgPtr->getData() + (4 * index);
        return !isZeroPixel( pixel );
    }
    
    const bool HelloWorld::isZeroPixel( const unsigned char* pixel )
    {
        return 0 == pixel[0] && 0 == pixel[1] && 0 == pixel[2] && 0 == pixel[3];
    }