问题
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