天天看點

cocos2dx之觸摸事件

要使精靈能夠接收到觸摸事件,無非要做三件事。

注冊觸摸事件;

接收觸摸事件;

處理觸摸事件。

下面就從這三點出發,來了解一下精靈如何響應觸摸事件。

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個像素。

cocos2dx之觸摸事件