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

posted @ 2014-07-22 21:11  Carlos.V  阅读(1773)  评论(4编辑  收藏  举报