Cocos2dx(1)_CCLayer触屏事件研究

对于CCLayer子类,想响应触屏事件比较简单,init的时候调用setTouchEnable(true)并重载下列函数:

    virtual void registerWithTouchDispatcher(void);
    virtual bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent);
    virtual void ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent);
    virtual void ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent);
    virtual void ccTouchCancelled(CCTouch *pTouch,CCEvent *pEvent);

典型的registerWithTouchDispatcher实现是:

void XXLayer::registerWithTouchDispatcher()
{
    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,true);
}

做的事情就是注册触屏事件。

addTargetedDelegate的第一个参数是delegate,就是回调函数执行的对象;第二个参数priority和第三个参数bSwallowsTouches决定多个对象同时注册触屏事件时的行为。具体的意义是:

priority值越小,回调越早被调用。

bSwallowsTouches为true,则ccTouchBegan返回ture以后,其他的回调将不再被调用,就好像触屏事件被吃掉了一样。

 

ccTouchxx系列函数就是触屏事件的响应函数。

 

CCLayer提供了一个registerWithTouchDispatcher的默认实现,主要功能相当于

CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this,0)

也是注册触屏事件。但是addStandardDelegate和前面我们使用的addTargetedDelegate有诸多不同。

1.不支持bSwallowsTouches参数,在触屏动作发生时,所有注册了触屏事件的对象的回调函数都会被调用。

2.回调函数定义不同,它的回调函数定义是:

    virtualvoid ccTouchesBegan(CCSet *pTouches,CCEvent *pEvent);

    virtualvoid ccTouchesMoved(CCSet *pTouches,CCEvent *pEvent);

    virtualvoid ccTouchesEnded(CCSet *pTouches,CCEvent *pEvent);

    virtualvoid ccTouchesCancelled(CCSet *pTouches,CCEvent *pEvent);

 

回调函数的第一个参数是CCSet*,另外ccTouchesBegan也不像ccTouchBegan那样有一个bool型的返回值。

网上有人提到支持多点触摸时需要使用addStandardDelegate,暂时还没有研究过。

 

前面只说了注册事件,没有提注销。CCLayer是在onExit中帮我们做了这件事,子类就不用再处理了。

 

下面提供一个CCLayer子类响应触屏事件的实例,用cocos2dx template生成Hello world工程后,替换HelloWorldScene.h和HelloWorldScene.cpp即可测试这个例子,这个例子的重点在onEnter函数中,值得仔细思考下。

 

HelloWorldScene.h:

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"
#include "cocos-ext.h"

USING_NS_CC;
USING_NS_CC_EXT;

class HelloWorld : public cocos2d::CCLayer
{
public:
    // Here\'s a difference. Method \'init\' in cocos2d-x returns bool, instead of returning \'id\' in cocos2d-iphone
    virtual bool init();
    
    // there\'s no \'id\' in cpp, so we recommand to return the exactly class pointer
    static cocos2d::CCScene* scene();
    
    // a selector callback
    void menuCloseCallback(CCObject* pSender);
    
    // implement the "static node()" method manually
    CREATE_FUNC(HelloWorld);
    
public:
    virtual void onEnter();
    virtual void registerWithTouchDispatcher();
    
    virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
    
private:
    // 菜单回调
    void menu1Callback(CCNode *pSender);
    void menu2Callback(CCNode *pSender);
    
private:
    CCMenu *menu;
    CCScrollView *scrollView;
};

#endif // __HELLOWORLD_SCENE_H__

HelloWorldScene.cpp

#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"

using namespace cocos2d;
using namespace CocosDenshion;
USING_NS_CC_EXT;

CCScene* HelloWorld::scene()
{
    // \'scene\' is an autorelease object
    CCScene *scene = CCScene::create();
    
    // \'layer\' is an autorelease object
    HelloWorld *layer = HelloWorld::create();
    
    // add layer as a child to scene
    scene->addChild(layer);
    
    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !CCLayer::init() )
    {
        return false;
    }
    
    setTouchEnabled(true);
    
    /////////////////////////////
    // 3. add your codes below...
    
    // ask director the window size
    CCSize size = CCDirector::sharedDirector()->getWinSize();
    
    // CCScrollView
    scrollView = CCScrollView::create();
    CCLayer *layer = CCLayer::create();
    
    CCSprite *sprite1 = CCSprite::create("HelloWorld.png");
    CCSprite *sprite2 = CCSprite::create("HelloWorld.png");
    
    layer->setAnchorPoint(ccp(0, 0));
    layer->setPosition(ccp(0, 0));
    
    // Menu
    CCMenuItemSprite *menuItem1 = CCMenuItemSprite::create(sprite1, sprite1, this, menu_selector(HelloWorld::menu1Callback));
    float scale = 0.5;
    CCSize itemSize(sprite1->getTextureRect().size);
    menuItem1->setPosition(ccpAdd(CCPointZero, ccp(itemSize.width*scale / 2, itemSize.height*scale / 2)));
    menuItem1->setScale(scale);
    CCMenuItemSprite *menuItem2 = CCMenuItemSprite::create(sprite2, sprite2, this, menu_selector(HelloWorld::menu2Callback));
    //    menuItem2->setPosition(ccpAdd(ccp(480, 0), ccp(size.width / 2, size.height / 2)));
    menuItem2->setPosition(ccp(itemSize.width*scale*3/2, itemSize.height*scale / 2));
    menuItem2->setScale(scale);
    
    menu = CCMenu::create(menuItem1, menuItem2, NULL);
    menu->setPosition(CCPointZero);
    
    layer->addChild(menu);
    layer->setContentSize(CCSizeMake(itemSize.width*2*scale, 320));
    
    scrollView->setPosition(ccp(0,0));
    scrollView->setContentOffset(CCPointZero);
    scrollView->setContentSize(CCSizeMake(640, 320));
    scrollView->setContainer(layer);
    scrollView->setDirection(kCCScrollViewDirectionHorizontal);
    
    this->addChild(scrollView);
    return true;
}

void HelloWorld::onEnter() {
    CCLayer::onEnter();
    
    //这里是重点,尝试注释掉它然后再执行程序,看左右拖动图片时行为有什么变化。
    menu->setHandlerPriority(1);
}

void HelloWorld::menuCloseCallback(CCObject* pSender)
{
    CCDirector::sharedDirector()->end();
    
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
}

void HelloWorld::registerWithTouchDispatcher()
{
    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, false);
}

bool HelloWorld::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
    return true;
}

void HelloWorld::ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
    CCLOG("move");
}

void HelloWorld::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
}

void HelloWorld::ccTouchCancelled(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)
{
}

void HelloWorld::menu1Callback(cocos2d::CCNode *pSender)
{
    CCLOG("menu1Callback");
}

void HelloWorld::menu2Callback(cocos2d::CCNode *pSender)
{
    CCLOG("menu2Callback");
}

转自:http://blog.csdn.net/herain_cs/article/details/8627995

附:

版权声明:本文为akever原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/akever/articles/CCLayer_click.html