Created many CCSprits but when triggering ccTouchBegan gives the last one allways

时光总嘲笑我的痴心妄想 提交于 2019-12-12 21:26:22

问题


UPDATE i changed to more simpler example

Ok , now i really puzzled i simplified the class as as i was reading on the net the suggestion was to extend CCNode better then CCSprite and keep it as member of the CCNode so here is the very simpleminded example based on the Hello cpp.
the problem remine the same , when touching any of the Gem instances i get printed the last Gem added , why ??
i expect that each Touchwill give me the correct instance that have bean touched ( i print id and name )

Im using cocos2d-2.1rc0-x-2.1.3 c++ , and i have something strange i created 10 CCSprites. i have class that extend CCSprite and CCTargetedTouchDelegate like this :

Gem.cpp

#include "Gem.h"
Gem::Gem()
{

   ;

}
Gem::~Gem()
{
    ;
}

void Gem::onEnter()
{

    CCDirector* pDirector = CCDirector::sharedDirector();
    pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
    CCNode::onEnter();

}
void Gem::onExit()
{  
    CCDirector* pDirector = CCDirector::sharedDirector();
    pDirector->getTouchDispatcher()->removeDelegate(this);
    CCNode::onExit();    
} 
bool Gem::ccTouchBegan(CCTouch* touch, CCEvent* event)
{       
    CCPoint touchPoint = touch->getLocation();   
    CCLOG("Gem Touched! ImageName:%s |GemId:%s  x:%f ,y:%f myspriteX:%f, myspriteY:%f nodePosX:%f nodePosY:%f",this->getImageName().c_str(),this->getGemId().c_str(),touchPoint.x,touchPoint.y,getGemSprite()->getPositionX(),getGemSprite()->getPositionY(),this->getPositionX(),this->getPositionY());
    return true;
}
void Gem::ccTouchMoved(CCTouch* touch, CCEvent* event)
{
    CCPoint touchPoint = touch->getLocation();  
}
void Gem::ccTouchEnded(CCTouch* touch, CCEvent* event)
{

}

Gem.h

class Gem :public CCNode , public CCTargetedTouchDelegate 
{
public:
    Gem();

    virtual ~Gem();

    CC_SYNTHESIZE(std::string,imageName,ImageName)
    CC_SYNTHESIZE(std::string,gemId,GemId)
    CC_SYNTHESIZE(CCPoint,gemPos,GemPos)
    CC_SYNTHESIZE(CCSprite*,gemSprite,GemSprite)

    virtual void onEnter();
    virtual void onExit();
    virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);
    virtual void ccTouchMoved(CCTouch* touch, CCEvent* event);
    virtual void ccTouchEnded(CCTouch* touch, CCEvent* event);


};

The helloWorldScene.cpp init() method

bool HelloWorld::init()
{
       bool bRet = false;
        //////////////////////////////////////////////////////////////////////////
        // super init first
        //////////////////////////////////////////////////////////////////////////

       if(!CCLayer::init())
        return false;

        CCSize m_winSize;
        CCSize visibleSize;
        CCPoint origin;
        m_winSize = CCDirector::sharedDirector()->getWinSize();
        visibleSize = CCDirector::sharedDirector()->getVisibleSize();
        origin = CCDirector::sharedDirector()->getVisibleOrigin();

        CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("sprites.plist","sprites.png");
        CCSpriteBatchNode* gameBatchNode  = CCSpriteBatchNode::create("sprites.png"/*,200*/);
        CCSprite *bg= CCSprite::create("grideFinal.png");
        //bg->setAnchorPoint(ccp(0,0));
        bg->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
        this->addChild(bg,1);

        Gem* gem1 = new Gem();
        gem1->retain();
        gem1->setGemId("gem1");
        gem1->setImageName("img_1");
        gem1->setGemSprite(CCSprite::createWithSpriteFrameName("gem1.png"));
        Gem* gem2 = new Gem();
        gem2->retain();
        gem2->setGemId("gem2");
        gem2->setImageName("img_2");
        gem2->setGemSprite(CCSprite::createWithSpriteFrameName("gem2.png"));

        gem1->setAnchorPoint(ccp(0,0));
        gem2->setAnchorPoint(ccp(0,0));

        gem1->setPosition(ccp(0,0));
        gem2->setPosition(ccp(gem1->getGemSprite()->getContentSize().width,40));

        gem1->getGemSprite()->setAnchorPoint(ccp(0,0));
        gem2->getGemSprite()->setAnchorPoint(ccp(0,0));
        gem1->getGemSprite()->setPosition(ccp(0,0));
        gem2->getGemSprite()->setPosition(ccp(gem1->getGemSprite()->getContentSize().width,40));
        //gameBatchNode->addChild(gem1->getGemSprite(),4,44);
        //gameBatchNode->addChild(gem2->getGemSprite(),4,45);
        this->addChild(gameBatchNode);

        bg->addChild(gem1->getGemSprite(),50);
        bg->addChild(gem2->getGemSprite(),50);
        bg->addChild(gem1,50);
        bg->addChild(gem2,50);

        bRet = true;


    return bRet;
}

Every thing is woring fine except when i touch the screen and trigger Gem::ccTouchBegan method. its always gives me the last CCSprite ( and i have like 50 on the screen why is that ? what im missing here ?


回答1:


Because every Gem instance extend CCTargetedTouchDelegate and register touch dispatcher, only the highest or latest added will be triggered.

So what the correct way is implement CCTargetedTouchDelegate in HelloWorld class, and when touch occur, check which Gem is touched by touch point.

Here is a method used for checking if touch is in some node:

bool Gem::isTouchInside(CCTouch* pTouch)
{
    CCPoint touchLocation = pTouch->getLocation();
    CCRect rect =
    CCRectApplyAffineTransform(CCRectMake(0 ,
                                          0 ,
                                          this->getContentSize().width,
                                          this->getContentSize().height),
                               this->nodeToWorldTransform());
    return rect.containsPoint(touchLocation);
}


来源:https://stackoverflow.com/questions/18188095/created-many-ccsprits-but-when-triggering-cctouchbegan-gives-the-last-one-allway

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!