首页 > 代码库 > 【Cocos2D-X 学习笔记】为精灵添加单点触控

【Cocos2D-X 学习笔记】为精灵添加单点触控

  由于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 cocos2dclass 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 instancebool 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引擎生命周期等不再详述。