我们经常须要推断用户的点击操作是否落于某个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。