文档章节

9秒分享 Cocos2d-X2.2版本框架源码分析第二讲

扶殊88
 扶殊88
发布于 2014/04/01 14:06
字数 1644
阅读 114
收藏 0
接着最开始的,我们继续来分析Cocos2d-x的框架源码 

接下来,我们来玩什么呢?  对了,定时器..我们现在开始..刚才多少来着,哦,对了,第四个了..我们开始


4cocos2d-x定时器机制


问题1:定时器回调函数,添加到cocos2d-x框架哪里去了。
问题2:定时器回调函数是如何被cocos2d-x回调用起来的
问题3:cocos2d-x框架式如何管理定时器的。

定时器的应用基础cocos2d-x 
Cocos2d-x提供两种定时器 
1)update定时器,每帧被调用,使用scheduleUpdate方法启用。
2)schedule定时器,可设置时间间隔来触发,使用schedule方法启用。
框架与应用界面接口如下:
void scheduleUpdate(void);
void unscheduleUpdate(void);
void schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay);
void schedule(SEL_SCHEDULE selector, float interval);
void scheduleOnce(SEL_SCHEDULE selector, float delay);
void schedule(SEL_SCHEDULE selector);
void unschedule(SEL_SCHEDULE selector);
void unscheduleAllSelectors(void);

问题1:定时器回调函数,添加到cocos2d-x框架哪里去了?
1)        CCNode类注入了调度器对象;
2)        通过schedule()函数,上层应用对象及对象的回调函数入口地址,被添加到调度器CCScheduler中。
3)        调度器为每一个定时器设置CCTimer对象,并保存定时器类目标、回调函数、触发周期,重复次数;在把对应信息保存到m_pHashForTimers链表中。以便后续调度。
代码如下:






问题2:定时器回调函数是如何被调用起来的
顺序如下:
1)AppDelegate对象run函数,按照帧频率调用 void CCDisplayLinkDirector::mainLoop(void)

   


2)mainLoop 函数调用,void CCDirector::drawScene(void)



4)        调度器的update函数发起如下调度






   
同时,如果在调度过程中,有删除定时器操作时,在调度完毕以后再删除。
删掉定时器,只做标记。 



结论1:普通定时器调用顺序:1、系统的事件驱动游戏主循环;2、游戏主循环调用CCScheduler的update方法。3、CCScheduler调用普通定时器对应的CCTimeer对象的update方法;4、CCTime类的updata方法调用定时器对应的回调函数。
结论2:updata定时器,调用顺序比较简单,直接在CCScheduler的update方法中调用。


5coco2d-x触屏实现机制

问题1:触屏的目标对象被加到cocos2d-x框架的什么地方?
问题2:cocos2d-x框架是如何调用目标对象的回调函数?
问题3:CCTouchDispatcher类触屏分发器原理是什么?

1触屏事件基础知识
基本步骤,1)开启触屏功能2);重写registerWithTouchDispatcher方法;3)重写触屏协议函数
例子如下:
  1. // on "init" you need to initialize your instance
  2. bool HelloWorld::init()
  3. {
  4.     //////////////////////////////
  5.     // 1. super init first
  6.     if ( !CCLayer::init() )
  7.     {
  8.         return false;
  9.     }

  10.         //做一个鼠标跟随的效果
  11.         CCSprite *sprite = CCSprite::create("CloseNormal.png");
  12.         sprite->setPosition(ccp(200, 200));
  13.         this->addChild(sprite, 0, 100);

  14.         //开启层触屏支持
  15.         this->setTouchEnabled(true);
  16. }

  17. void HelloWorld::registerWithTouchDispatcher(void)
  18. {
  19.         CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
  20. }

  21. public:
  22.         virtual void registerWithTouchDispatcher(void);

  23.         bool HelloWorld::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) ;
  24.         void HelloWorld::ccTouchMoved(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) ;
  25.         void HelloWorld::ccTouchEnded(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) ;
  26.         void HelloWorld::ccTouchCancelled(cocos2d::CCTouch *pTouch,cocos2d:: CCEvent *pEvent) ;
  27.                 
  28. bool HelloWorld::  (CCTouch *pTouch, CCEvent *pEvent) 

  29.         CCLOG("ddddddd");
  30.         //获取精灵 获取鼠标点击位置,移动精灵到此位置
  31.         CCSprite *sprite = (CCSprite *)this->getChildByTag(100);
  32.         if (sprite == NULL)
  33.         {
  34.                 return false;
  35.         }
  36.         //CCPoint point  = pTouch->getLocationInView();
  37.         //CCPoint glpoint = CCDirector::sharedDirector()->convertToGL(point);
  38.         CCPoint glpoint = pTouch->getLocation();

  39.         sprite->setPosition(glpoint);
  40.         //CCMoveTo* moveto = CCMoveTo::create(3, point);
  41.         //sprite->runAction(moveto);
  42.         return true;
  43. };
复制代码
问题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进行调用。
代码运作过程参考下图







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



结论:
1)        CCEGLView:: WindowProc过程回调函数处理触屏消息,比如鼠标点击、滑屏。
2)        调用消息派发器类CCTouchDispatcher,进行消息处理。
3)        在CCTouchDispatcher类的touches函数中进行各种消息机制的处理及用户重载鞋业函数的调用。
问题3:CCTouchDispatcher类是如何处理消息派发的?也可以这么问: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类相关源码,深入细腻的实验内容在9秒课堂。

by:Net Fly

本文转载自:http://www.9miao.com/thread-46198-1-1.html

扶殊88
粉丝 28
博文 154
码字总数 35546
作品 0
浦东
程序员
私信 提问
cocos2d-x横版动作手游《口袋仙侠》商用版正式开源

【9秒原创】Firefly + cocos2d-x的横版rts手机网游《口袋仙侠》alpha V1.0 商用版本完整源码下载 特别声明: 1、《口袋仙侠》项目基于MIT协议,9秒社团团队允许任何厂商及个人对其进行修改和...

大鸡蛋
2014/03/19
15K
69
原创 cocos2d-x 横版手游《打小三》源码下载!

感谢9秒社团的 9秒北京-lonely的mzplay团队~这次开源的手游作品《打小三》是他们无私奉献的产物~~ 这个产品的详细信息如下: 游戏名称:打小三 游戏类型:横版动作类(ACT) 游戏版本:V1.0 ...

大鸡蛋
2013/12/26
8.4K
14
原创cocos2d-x横版手游《打小三》源码下载!

感谢9秒社团的 9秒北京-lonely 的 mzplay 团队~这次开源的手游作品《打小三》是他们无私奉献的产物~~另外也感谢OSchina,提供本次中国杯 游戏极限开发大赛的支持,还有CSDN团队,他们在中国杯...

大鸡蛋
2013/12/26
1K
2
cocos2dx 手游《口袋仙侠》alpha1.1 完整开源

游戏名称:《口袋仙侠》 游戏类型:横版RTS 游戏版本:Alpha V1.1 服务器框架:Firefly V1.3.1 客户端引擎:Cocos2d-x 2.2.0 服务器运行环境:CentOS 5.0+ 开源时间:2014年4月4日 完整服务器...

大鸡蛋
2014/04/04
5.6K
9
历数2013年优秀的开源游戏引擎与开源游戏项目

2013年是移动游戏爆发的一年,也是开源游戏爆发的一年!在这里,我们历数一下2013年都有哪些优秀的开源游戏诞生,还有哪些优秀的开源游戏技术解决方案诞生! 开源跨平台2D客户端引擎 Cocos2...

大鸡蛋
2014/01/15
25
0

没有更多内容

加载失败,请刷新页面

加载更多

Java8

package com.shi.lambda;import java.util.Arrays;import java.util.List;import org.junit.Test;import com.shi.model.Employee;/** * 初始化案例 * @author xiaosh......

小小小施爷
16分钟前
1
0
c# 动态编译代码

有时候做计算一些东西时候,算法一直变更,写在程序需要一直调整,因此算法写在cs文件,然后动态调用内部的方法去计算判断,只需变更cs文件即可。 static void Main() { Stopwatch watch = n...

朝如青丝暮成雪
17分钟前
1
0
好程序员技术分享html5和JavaScript的区别

好程序员技术分享html5和JavaScript的区别,HTML5广义上讲是前端开发学科的代名词,包含HTML5、CSS3及JavaScript三个重要的部分,是运行在浏览器上应用的统称。如PC端网站、管理系统、手机网...

好程序员IT
19分钟前
1
0
tomcat 与 spring boot 设置虚拟路径

tomcat 设置虚拟路径 <Context path="/uploadDir" docBase="/data"/>path是请求访问的路径docBase是服务器存储文件的路径,Linux 根目录下 data spring boot 虚拟路径设置 registry.addRe......

kdy1994
22分钟前
1
0
var ,let ,const 的区别和共同点

一、let和var区别 1.关于变量提升,var能变量提升,let不能 // 关于var 如下所示console.log(a); //输出undefined,此时就是变量提升var a = 2; console.log(a); //2 //相当于下面...

MrBoyce
27分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部