要使精靈能夠接收到觸摸事件,無非要做三件事。
注冊觸摸事件;
接收觸摸事件;
處理觸摸事件。
下面就從這三點出發,來了解一下精靈如何響應觸摸事件。
1.注冊觸摸事件
精靈類Poker繼承Sprite和CCTargetedTouchDelegate,并重寫CCTargetedTouchDelegate的三個函數ccTouchBegan,ccTouchMoved,ccTouchEnded
同時加入輔助函數rect()和containTouchPoint(CCTouch* touch)用于後面的判斷。
poker.h檔案:
class Poker : public CCSprite ,public CCTargetedTouchDelegate
{
PokerState m_state;
public:
Poker(void);
CCRect rect();
virtual void onEnter();
virtual void onExit();
virtual ~Poker(void);
boolean containTouchPoint(CCTouch* touch);
virtual bool ccTouchBegan(CCTouch *touch ,CCEvent *event);
virtual void ccTouchMoved(CCTouch *touch ,CCEvent *event);
virtual void ccTouchEnded(CCTouch *touch ,CCEvent *event);
};
poker.cpp檔案:
這裡需要再poker.cpp中添加具體的注冊行為,onEnter和onExit函數分别是精靈建立和銷毀時調用,因為可以在這兩個函數中添加注冊和銷毀注冊。
//CCNode進入場景時調用
void Poker::onEnter()
{
CCDirector* pDirector = CCDirector::sharedDirector();
pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
CCSprite::onEnter();
}
//CCNode退出場景時調用
void Poker::onExit()
{
CCDirector* pDirector = CCDirector::sharedDirector();
pDirector->getTouchDispatcher()->removeDelegate(this);
CCSprite::onExit();
}
以上,我們的觸摸事件注冊流程就完成了。
2.接收觸摸事件
接收觸摸事件,實際上就是重寫CCTargetedTouchDelegate的三個函數ccTouchBegan,ccTouchMoved,ccTouchEnded。
bool Poker::ccTouchBegan(CCTouch *touch ,CCEvent *event)
{
CCLog("Poker ccTouchBegan ");
return false;
}
void Poker::ccTouchMoved(CCTouch *touch ,CCEvent *event)
{
CCLog("Poker ccTouchMoved ");
}
void Poker::ccTouchEnded(CCTouch *touch ,CCEvent *event)
{
CCLog("Poker ccTouchEnded ");
}
如此,接收流程已經完成,無意外的話,運作可以看到列印日志了。
3.處理觸摸事件
首先要擷取目前精靈所在的矩形。 也即是CCRect Poker::rect()需要做的事情。 請注意,這裡擷取的方式的前提是,精靈使用系統預設的錨點,也即是精靈的正中央,如果改變過精靈的錨點(setAnchorPoint),那麼就需要改變計算方法了。
CCRect Poker::rect()
{
CCSize size = getTexture()->getContentSize();
return CCRectMake(-size.width / 2 ,-size.height / 2, size.width ,size.height);
}
如果将目前精靈也看做一個坐标系,若精靈的長為100,寬為100,那麼擷取的矩形應該是x = -50 , y = -50 ,width = 100 ,height = 100 其次,将觸摸事件的點轉化為目前精靈内部坐标系的點。 (可能不是很好了解,但是我們每一個繼承自CCNode的結點都可以看做一個坐标系)
boolean Poker::containTouchPoint(CCTouch* touch)
{
return rect().containsPoint(convertTouchToNodeSpaceAR(touch));
}
在CCSprite内部使用convertTouchToNodeSpaceAR函數就可以将目前觸摸點轉化成精靈内部坐标系的點。 最後,判斷觸摸事件,并處理。
bool Poker::ccTouchBegan(CCTouch *touch ,CCEvent *event)
{
int x = getPositionX();
int y = getPositionY();
if (containTouchPoint(touch))
{
setPosition(ccp(x , y + 30));
return true;
}
CCLog("Poker ccTouchBegan ");
return false;
}
如果發現目前觸摸點在CCSprite的内部,則将目前CCSprite的Y坐标上移30個像素。