本篇主要討論如何在cocos2d-x中處理事件回應之完全實作概念,筆者會整理此概念最主要是其作法與使用Java略有不同,即某些環節部份要扣好才會產生動作,之前曾因此部份花了很多時間去分析示例代碼才找出其原因,故在此提出以作為參考。如欲在HelloWorld 示例中點擊某一相應位置以出現水波效果,其實現作法如下:
首先於 HelloWorld添加了一個構造函式:
HelloWorld::HelloWorld()
{
  setTouchEnabled(true);
}
在構造函式裡宣告啟用點擊按下之事件,然後實現其點擊按下後具有之回應函式ccTouchesEnded()
void HelloWorld::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)
{
  CCSetIterator it = pTouches->begin();
  CCTouch* touch = (CCTouch*)(*it);

  CCPoint location = touch->getLocation();

  CCNode* s = getChildByTag(1);
  CCActionInterval* effect =CCRipple3D::create(ccp(location.x, location.y), 128, 12, 120, ccg(128,128), 5);
  s->runAction(effect);
}
此時若運行程式會發覺點擊按下時並無回應,經調試發現isTouchEnabled()返回值是false,故並無啟用點擊按下之功能。在cocos2d-x中還須一道程序:CCLayer::init()中調用setTouchEnabled(true)函式,其意為將設定回應事件通知CCLayer才可於畫面中被操作,代碼添加如下:
bool HelloWorld::init(){
…………..
CC_BREAK_IF(! CCLayer::init());
setTouchEnabled(true);
           ………..
           }

順道提一下cocos2d-x處理觸摸事件之作法,cocos2d-x具備之觸摸事件有多種型式,底下以單點觸摸拖拽Sprite為例作說明:
須於構造函式中宣告啟用觸模事件之功能,如下代碼:
CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this,INT_MIN+1,true);
然後到HelloWorldScene.h標頭中之最上邊添加using namespace cocos2d;,並在public裡添加一個cocos2d::CCSprite* player;
之後在HelloWorldScene.cpp類之public裡邊添加如下之函式宣告:
virtual bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
virtual void registerWithTouchDispatcher(void);
接著再於HelloWorld .cpp類中init()函式的迴圈裡的最前邊添加如下代碼:
player=CCSprite::spriteWithFile("CloseNormal.png");
CC_BREAK_IF(! player);
this->addChild(player,0,1);
CCSize screenSize = CCDirector::sharedDirector()->getWinSize();
float imageHeight=player->getTexture()->getContentSize().height;
player->setPosition(CCPointMake(screenSize.width/2,imageHeight/2));
並註冊如下之函式定義:
void HelloWorld::registerWithTouchDispatcher() {
}
bool HelloWorld::ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent) {
return true;
}
void HelloWorld::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) {
}
void HelloWorld::ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent) {
}
void HelloWorld::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent) {
}
再於ccTouchBegan函式和ccTouchMoved函式裡邊的頂部添加如下代碼:
player->setPositionX(pTouch->locationInView(pTouch->view()).x);
player->setPositionY(CCDirector::sharedDirector()->getWinSize().height-pTouch->locationInView(pTouch->view()).y);
此處要用視窗高度減去pTouchy值是因cocos2d-xy坐標系是自下向上遞增的,最下邊是0,最上邊是最大,注意ccTouchBegan最後一定要有一個return true;,調試運行,點擊並移動Sprite會跟著點擊走。


如何實作cocos2d-x之回應事件
本篇主要討論如何在cocos2d-x中處理事件回應之完全實作概念,筆者會整理此概念最主要是其作法與使用Java略有不同,即某些環節部份要扣好才會產生動作,之前曾因此部份花了很多時間去分析示例代碼才找出其原因,故在此提出以作為參考。如欲在HelloWorld 示例中點擊某一相應位置以出現水波效果,其實現作法如下:
首先於 HelloWorld添加了一個構造函式:
HelloWorld::HelloWorld()
{
  setTouchEnabled(true);
}
在構造函式裡宣告啟用點擊按下之事件,然後實現其點擊按下後具有之回應函式ccTouchesEnded()
void HelloWorld::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)
{
  CCSetIterator it = pTouches->begin();
  CCTouch* touch = (CCTouch*)(*it);

  CCPoint location = touch->getLocation();

  CCNode* s = getChildByTag(1);
  CCActionInterval* effect =CCRipple3D::create(ccp(location.x, location.y), 128, 12, 120, ccg(128,128), 5);
  s->runAction(effect);
}
此時若運行程式會發覺點擊按下時並無回應,經調試發現isTouchEnabled()返回值是false,故並無啟用點擊按下之功能。在cocos2d-x中還須一道程序:CCLayer::init()中調用setTouchEnabled(true)函式,其意為將設定回應事件通知CCLayer才可於畫面中被操作,代碼添加如下:
bool HelloWorld::init(){
…………..
CC_BREAK_IF(! CCLayer::init());
setTouchEnabled(true);
           ………..
           }

順道提一下cocos2d-x處理觸摸事件之作法,cocos2d-x具備之觸摸事件有多種型式,底下以單點觸摸拖拽Sprite為例作說明:
須於構造函式中宣告啟用觸模事件之功能,如下代碼:
CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this,INT_MIN+1,true);
然後到HelloWorldScene.h標頭中之最上邊添加using namespace cocos2d;,並在public裡添加一個cocos2d::CCSprite* player;
之後在HelloWorldScene.cpp類之public裡邊添加如下之函式宣告:
virtual bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
virtual void registerWithTouchDispatcher(void);
接著再於HelloWorld .cpp類中init()函式的迴圈裡的最前邊添加如下代碼:
player=CCSprite::spriteWithFile("CloseNormal.png");
CC_BREAK_IF(! player);
this->addChild(player,0,1);
CCSize screenSize = CCDirector::sharedDirector()->getWinSize();
float imageHeight=player->getTexture()->getContentSize().height;
player->setPosition(CCPointMake(screenSize.width/2,imageHeight/2));
並註冊如下之函式定義:
void HelloWorld::registerWithTouchDispatcher() {
}
bool HelloWorld::ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent) {
return true;
}
void HelloWorld::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) {
}
void HelloWorld::ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent) {
}
void HelloWorld::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent) {
}
再於ccTouchBegan函式和ccTouchMoved函式裡邊的頂部添加如下代碼:
player->setPositionX(pTouch->locationInView(pTouch->view()).x);
player->setPositionY(CCDirector::sharedDirector()->getWinSize().height-pTouch->locationInView(pTouch->view()).y);
此處要用視窗高度減去pTouchy值是因cocos2d-xy坐標系是自下向上遞增的,最下邊是0,最上邊是最大,注意ccTouchBegan最後一定要有一個return true;,調試運行,點擊並移動Sprite會跟著點擊走。