转自:http://www.cnblogs.com/lancidie/archive/2013/04/01/2993890.html
我们常常需要判断用户的点击操作是否落于某个sprite之上,进而让这个sprite做出响应。
但是如果我们通过继承CCSprite类来实现自己的Sprite类的时候,产生的视图尺寸会充满屏幕。多个Sprite在同一层的时候会发生重叠,导致我们通过回调函数传递进的touch点是相对于最上层Sprite来说的。
好在我们可以通过CCDirector::sharedDirector()->convertToGL(CCTouch* touch->locationInView());的方法来获得touch point的绝对坐标。然后通过遍历屏幕上所有的sprite,依次检查落点来判断用户点击应该被哪个Sprite接受。
但其实Cocos2d-x已经为我们提供了一个非常方便的方法来判断用户点击了哪个Sprite。
假如在这里我们有一个MySprite继承了CCSprite,同时为了响应点击事件,我们还需要继承CCTargetedTouchDelegate。
后者这个类为我们提供了三个virtual的回调函数:
virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event); virtual void ccTouchMove(CCTouch* touch, CCEvent* event); virtual void ccTouchEnded(CCTouch* touch, CCEvent* event);
这三个函数分别在用户“点击”,“点击拖动”,“抬起手指”的时候被调用。
其中ccTouchBegan函数的返回值是bool类型,其原因就是系统会根据该回调函数的返回值来判断点击消息是否已经传递给用户需要的Sprite。
具体点儿:如果该回调函数返回true,说明程序员已经认为需要接受到这个触摸消息的Sprite已经接收到了这个触摸消息。那么程序的触摸消息传递就会到此为止,只在本层被使用(也会被本层的ccTouchMove,ccTouchEnded所使用)。如果返回false,说明这个触摸消息并没有传递到需要接受这个消息的Sprite中去,这时系统会将这个触摸消息传递到下一层Sprite,并且由这一层的ccTouchBegan来处理这个消息。
贴个示例代码:
bool MySprite::ccTouchBegan(cocos2d::CCTouch *touch, cocos2d::CCEvent *event){ if(containsTouchLocation(touch)){ cout<<"Touch:"<<this->getTag()<<endl; return true; } return false; }
其中containsTouchLocation是用户自己实现的:通过在该函数中获取position,并与传递进函数的touch作比较,判断用户的触摸操作是否落于该sprite区域之内。
如果落在该区域,则返回true,中断这个消息链。同时这个sprite会相应相应的ccTouchMove,ccTouchEnded
如果没有落在该区域,则返回false,并且将这个消息传递给下一层的sprite。