由於Cocos2d-x處於新學的階段,因此最近也無法進行系統地更新,只會選擇一些典型的Demo貼上來,一來是與大家分享,而來也可以作為以后回顧時的參考。
今天介紹一下Cocos2d-x的觸摸事件處理,了解Android開發的朋友們知道,Android里會用一個OnClickListener()進行事件監聽,而在J2SE中也會有Event類實現專門的監聽處理。在Cocos2d-x中,因為是游戲引擎,用戶在玩游戲時總是要通過屏幕與游戲進行交互,可想而知觸摸事件是主要處理的事件。這里主要講一下如何為精靈添加觸控事件,最終的效果是做一個可以拖動的小球,內容很簡單。
cocos2d-x提供的CCSprite (或者Sprite)類並沒有添加觸控監聽接口,這就要求我們需要自己創建一個類繼承CCSprite並且添加單點觸控接口CCTargetedTouchDelegate (多點觸控同理),並且實現三個虛方法bool ccTouchBegan() ccTouchMoved() ccTouchEnded() , 然后需要響應觸摸事件還需要把該對象添加進CCTouchDispatcher中。
下面是具體的代碼:
首先是Ball類的聲明:
ball.h
#include "cocos2d.h" USING_NS_CC; //using namespace cocos2d class Ball: public CCSprite,public CCTargetedTouchDelegate{ public: virtual void onEnter(); //新創建一個Ball對象並顯示時就會調用onEnter方法,在onEnter中把該對象添加進CCTouchDispatcher(觸摸事件管理器)中 virtual void onExit(); //該對象終結時會調用onExit方法,在該方法中,把該對象從CCTouchDispatcher中刪除 static Ball* create(char *imageName); //重寫了父類的create()方法,使得可以喝CCSprite一樣通過create方法創建一個Ball精靈 public: virtual bool isPointInside(CCPoint point); //判斷當前觸摸到的點是否剛好在精靈上 //觸摸事件必須要實現的三個接口 public: virtual bool ccTouchBegan(CCTouch *touch,CCEvent *pevent); virtual void ccTouchMoved(CCTouch *touch,CCEvent *pevent); virtual void ccTouchEnded(CCTouch *touch,CCEvent *pevent); };
然后是各個虛函數的具體實現部分
ball.cpp
#include "cocos2d.h" #include "ball.h" USING_NS_CC; //在類聲明里面出現的靜態成員必須在定義的時候進行外部引用聲明!! void Ball::onEnter(){ CCDirector *director=CCDirector::sharedDirector(); director->getTouchDispatcher()->addTargetedDelegate(this,0,true); //將該對象添加進事件處理序列 CCSprite::onEnter(); //調用其父類的構造方法保證精靈能夠正常初始化 CCLog("On Enter!"); } void Ball::onExit(){ CCDirector *director=CCDirector::sharedDirector(); director->getTouchDispatcher()->removeDelegate(this); //將該對象從事件處理序列中移除 CCSprite::onExit(); CCLog("On Exit!"); } Ball* Ball::create(char *imageName){ Ball *ball=new Ball(); //采用new方法創建一個對象,並設置自動釋放 ball->autorelease(); ball->initWithTexture(CCTextureCache::sharedTextureCache()->addImage(imageName));
//CCTextureCache是一個單例模式,同CCDirector類似,addImage()方法回返回一個Texture2D對象供精靈初始化使用 //addIamge方法回返回一個設定圖像的Texture2D對象 return ball; } bool Ball::ccTouchBegan(CCTouch *touch,CCEvent *pEvent){ CCPoint point=touch->getLocation(); if(!isPointInside(point)) return false; //ccTouchBegan返回false時表示不再執行ccTouchMoved 和ccTouchEnded函數,否則返回true時會執行上述兩個方法 return true; } void Ball::ccTouchMoved(CCTouch *touch,CCEvent *pEvent){ CCPoint point=touch->getLocation(); this->setPosition(point); } void Ball::ccTouchEnded(CCTouch *touch,CCEvent *pEvent){ } //因為使用了new 方法,所以必須把所有的虛函數都實現,這是C++自身的語法 bool Ball::isPointInside(CCPoint point){ CCPoint nodePoint=this->convertToNodeSpace(point); CCSize size=this->getContentSize(); if(nodePoint.x>size.width ||nodePoint.x<0 ||nodePoint.y>size.height ||nodePoint.y<0 ) return false; else return true; }
然后在CCLayer中像添加一個普通精靈一個添加即可,create()創建對象,設置位置,通過addChild()添加進圖層即可:
#include "HelloWorldScene.h" #include "ball.h" using namespace cocos2d; CCScene* HelloWorld::scene() { CCScene * scene = NULL; do { // 'scene' is an autorelease object scene = CCScene::create(); CC_BREAK_IF(! scene); // 'layer' is an autorelease object HelloWorld *layer = HelloWorld::create(); CC_BREAK_IF(! layer); // add layer as a child to scene scene->addChild(layer); } while (0); // return the scene return scene; } // on "init" you need to initialize your instance bool HelloWorld::init() { bool bRet = false; do { ////////////////////////////////////////////////////////////////////////// // super init first ////////////////////////////////////////////////////////////////////////// CC_BREAK_IF(! CCLayer::init()); ////////////////////////////////////////////////////////////////////////// // add your codes below... ////////////////////////////////////////////////////////////////////////// // 1. Add a menu item with "X" image, which is clicked to quit the program. // Create a "close" menu item with close icon, it's an auto release object. CCMenuItemImage *pCloseItem = CCMenuItemImage::create( "CloseNormal.png", "CloseSelected.png", this, menu_selector(HelloWorld::menuCloseCallback)); CC_BREAK_IF(! pCloseItem); // Place the menu item bottom-right conner. pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20)); // Create a menu with the "close" menu item, it's an auto release object. CCMenu* pMenu = CCMenu::create(pCloseItem, NULL); pMenu->setPosition(CCPointZero); CC_BREAK_IF(! pMenu); // Add the menu to HelloWorld layer as a child layer. this->addChild(pMenu, 1); Ball *ball=Ball::create("ball.png"); ball->setPosition(ccp(100,100)); this->addChild(ball); bRet = true; } while (0); return bRet; } void HelloWorld::menuCloseCallback(CCObject* pSender) { // "close" menu item clicked CCDirector::sharedDirector()->end(); }
關於資源文件配置,cocos2d-x引擎生命周期等不再詳述。