创建了许多CCSprits,但触发时ccTouchBegan提供了最后一个 [英] Created many CCSprits but when triggering ccTouchBegan gives the last one allways
问题描述
UPDATE 我改为更简单的例子
好的,现在我真的很困惑,我简化了类,因为我在网上阅读建议是扩展CCNode更好,然后CCSprite
并保持它作为CCNode
的成员,这里是基于Hello cpp的非常simpleminded示例。
问题还原相同,当触摸任何宝石实例,我打印最后一个宝石添加,为什么?
i期望每个Touchwill给我正确的实例,有豆接触(我打印id和名称)
Im使用cocos2d-2.1rc0-x-2.1.3 c ++,我有一些奇怪,我创建了10个CCSprites。
i有类扩展CCSprite和CCTargetedTouchDelegate像这样:
Gem.cpp
#includeGem.h
pre>
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:%sx:%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() > 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 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);
};
helloWorldScene.cpp init()方法
bool HelloWorld :: init()
{
bool bRet = false;
//////////////////////////////////////////////// ////////////////////////////
// super init first
///////// ////////////////////////////////////////////////// ///////////////
if(!CCLayer :: init())
return false;
CCSize m_winSize;
CCSize visibleSize;
CCP origin 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;
}
每一件事情都很好,除非我触摸屏幕并触发Gem :: ccTouchBegan方法。它总是给我最后一个CCSprite(和我有50在屏幕上
为什么是这里?这里丢失了什么?解决方案因为每个
Gem
实例扩展CCTargetedTouchDelegate
并注册触摸调度器,所以只会触发最高或最新添加。
那么正确的方法是在
中实现
class,当触摸发生时,检查哪个CCTargetedTouchDelegate
HelloWorldGem
被触摸点触摸。
用于检查触摸是否在某个节点:
bool Gem :: isTouchInside(CCTouch * pTouch)
{
CCPoint touchLocation = pTouch-> getLocation();
CCRect rect =
CCRectApplyAffineTransform(CCRectMake(0,
0,
this-> getContentSize ,
this-> getContentSize()。height),
this-> nodeToWorldTransform());
return rect.containsPoint(touchLocation);
}
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 ?
解决方案Because every
Gem
instance extendCCTargetedTouchDelegate
and register touch dispatcher, only the highest or latest added will be triggered.So what the correct way is implement
CCTargetedTouchDelegate
inHelloWorld
class, and when touch occur, check whichGem
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); }
这篇关于创建了许多CCSprits,但触发时ccTouchBegan提供了最后一个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!