cocos2d-x核心类剖析-coco2d-x触屏实现机制

12 篇文章 0 订阅

问题1:触屏的目标对象被加到cocos2d-x框架的什么地方?

问题2cocos2d-x框架是如何调用目标对象的回调函数?

问题3CCTouchDispatcher类触屏分发器原理是什么?

 

1触屏事件基础知识

基本步骤,1)开启触屏功能2);重写registerWithTouchDispatcher方法;3)重写触屏协议函数

例子如下:

// on "init" you need to initialize your instance

bool HelloWorld::init()

{

    //

    // 1. super init first

    if ( !CCLayer::init() )

    {

        return false;

    }

 

//做一个鼠标跟随的效果

CCSprite *sprite = CCSprite::create("CloseNormal.png");

sprite->setPosition(ccp(200, 200));

this->addChild(sprite, 0, 100);

 

//开启层触屏支持

this->setTouchEnabled(true);

}

 

void HelloWorld::registerWithTouchDispatcher(void)

{

CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);

}

 

public:

virtual void registerWithTouchDispatcher(void);

 

bool HelloWorld::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) ;

void HelloWorld::ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) ;

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

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

bool HelloWorld::  (CCTouch *pTouch, CCEvent *pEvent) 

CCLOG("ddddddd");

//获取精灵 获取鼠标点击位置,移动精灵到此位置

CCSprite *sprite = (CCSprite *)this->getChildByTag(100);

if (sprite == NULL)

{

return false;

}

//CCPoint point  = pTouch->getLocationInView();

//CCPoint glpoint = CCDirector::sharedDirector()->convertToGL(point);

CCPoint glpoint = pTouch->getLocation();

 

sprite->setPosition(glpoint);

//CCMoveTo* moveto = CCMoveTo::create(3, point);

//sprite->runAction(moveto);

return true;

};

问题1:重载的函数void HelloWorld::registerWithTouchDispatcher(void),何时被框架执行的?

 

结论:HelloWorld层被第一次载入场景是,会被执行onEnter函数。onEnter函数执行重载函数registerWithTouchDispatcher的调用。

问题2:问题1:触屏的目标对象及目标回到函数加到cocos2d-x框架的哪里了?

当然,也可以这么问:registerWithTouchDispatcher执行了哪些功能?

1、 CCTouchDispatcher类是cocos2d-x的触屏分发器,通过组合的方式由大管家CCDirector初始化;(参考CCDirector类的创建章节介绍。)

2、 CCTouchHandler类负责初始化把实现触屏协议类对象、优先级、触屏信息记录下来。

3、 初始化好的CCTouchHandler类对象,被CCTouchDispatcher类保存在成员变量CCArray* m_pHandlersToAdd中。以便cocos2d-x进行调用。

代码运作过程参考下图

 

 

 

问题2cocos2d-x框架是如何回到目标对象的回调函数

 

结论:

1) CCEGLView:: WindowProc过程回调函数处理触屏消息,比如鼠标点击、滑屏。

2) 调用消息派发器类CCTouchDispatcher,进行消息处理。

3) 在CCTouchDispatcher类的touches函数中进行各种消息机制的处理及用户重载鞋业函数的调用。

问题3CCTouchDispatcher类是如何处理消息派发的?也可以这么问:CCTouchDispatcher类触屏分发器原理是什么?

1) CCTouchDispatcher类能处理单点、多点触屏协议事件

2) CCTouchDispatcher类通过 void addStandardDelegate(CCTouchDelegate *pDelegate, int nPriority)和    void addTargetedDelegate(CCTouchDelegate *pDelegate, int nPriority, bool bSwallowsTouches)函数完成用触屏协议实现对象的注册。

3) CCTouchDispatcher类把注册信息存入到CCArray* m_pTargetedHandlers和CCArray* m_pStandardHandlers成员变量中。为保证不再循环时改变容器内容,CCTouchDispatcher类又引入了CCArray* m_pHandlersToAdd和 struct _ccCArray *m_pHandlersToRemove成员变量,用于暂时保存分发事件时目标对象的增删。

4) CCTouchDispatcher类的两个协议CCTargetedTouchDelegate /CCStandardTouchDelegate派发顺序

首先派发事件给CCTargetedTouchDelegate, 再派发事件给CCStandardTouchDelegate

5) CCTouchDispatcher类是触屏传递顺序描述如下:

1.CCLayer 只有一层的情况:

virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);

a.返回false,则ccTouchMoved(),ccTouchEnded()不会再接收到消息

b.返回true,则ccTouchMoved(),ccTouchEnded()可以接收到消息

2.CCLayer 有多层的情况:

virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);

a.返回false,则本层的ccTouchMoved(),ccTouchEnded()不会再接收到消息,但是本层之下的其它层会接收到消息

b.返回true,则本层的ccTouchMoved(),ccTouchEnded()可以接收到消息,但是本层之下的其它层不能再接收到消息

3.有自定义接收触摸消息的精灵的情况:

virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);

a.返回false,则此精灵的ccTouchMoved(),ccTouchEnded()不会再接收到消息,而此精灵所在的层会接收到触摸消息(如果精灵所在层没有设置接收触摸消息,则向下传递)

b.返回true,则此精灵的ccTouchMoved(),ccTouchEnded()会继续接收消息,并消耗此消息(即不再向所在层和其他层传递)

感兴趣的读者可以再仔细阅读CCTouchDispatcher类相关源码,深入细腻的实验内容在bombing课堂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值