【三】CocosCreator-CCDirector.js源码分析

2024-01-04 21:12

本文主要是介绍【三】CocosCreator-CCDirector.js源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

PS:只是看源码学习过程中把认为重要的内容以笔记的形式记录下来。

【1】cc.director:cc.Director的一个单例对象。
        如果需要用到导演类的内容,统一通过cc.director这个单例对象来调用。

【2】init():对导演类的成员变量进行初始化操作。
        在构造函数对此init函数注册了消息监听,当接收到来自CCGame的EVENT_ENGINE_INITED事件后才执行导演类的init函数。
        在init里面会new大量的manager,动作管理器、事件管理器、动画管理器、物理管理器、3D物理管理器等,并且设置他们的scheduleUpdate,所以这些manager的update函数就是从这里设置的了。这些new出来的管理器通过成员变量保存下来了,所以如果通过导演类这个单例去调用这些管理器,这些管理器也成为单例使用了。

【3】calculateDeltaTime():用于计算每次update的时间差。
        每次游戏的主循环都会调用这个函数,用于计算这次update与上次update的时间差,保存到this._deltaTime当中,在主循环内调用update时作为参数传递过去。 我们平时常用的update(dt)的dt时间差就是这样产生的了。
        

【4】convertToGL():把屏幕坐标转成webGL坐标

【5】convertToUI():把webGL坐标转成屏幕对应坐标

【6】end():关闭导演类。
        此方法只是设置了一个布尔值,等下一次主循环时才真正调用purgeDirector函数来关闭导演类,purgeDirector内部会清空_scheduler和_compScheduler、停止事件管理器、烧毁当前场景、清理renderer,清理内建资源、暂停game的主循环、重置资源管理器。

【7】getWinSize()和getWinSizeInPixels():获取视图大小
        两个方法内部实则都是通过cc.winSize获取大小……如果需要获取分辨率应该使用cc.view.getFrameSize()

【8】_paused:暂停游戏逻辑
        与game的_paused不同,导演类的_paused只会暂停游戏逻辑,不会暂停渲染、音频、事件等

【9】purgeCachedData():调用cc.assetManager.releaseAll()释放资源管理器内的所有资源。

【10】reset():重置导演类。
        先调用purgeDirector()清除导演类的相关内容(在【6】里面说过),然后再重新设置各大管理器的scheduleUpdate,再调用game的resume()恢复主循环。

【11】runSceneImmediate():立即切换场景。具体流程如下:
1.scene._load():初始化scene
2.处理常驻节点:从game中拿出常驻节点数组,然后遍历数组,把所有的常驻节点的parent指向新的scene,如果新的scene里面已经包含了与常驻节点相同uuid的对象,则删除scene里面的node再把常驻节点的node加进scene里面来。
3.cc.assetManager._releaseManager._autoRelease():释放assetManager里面oldScene的资源。
4.oldScene.destroy():销毁oldScene。
5.onBeforeLoadScene():处理切换scene之前需要处理的内容。
6.scene._activate():激活节点。
7.cc.game.resume():恢复主循环
8.onLaunched(null, scene); 加载完成场景后的时间回调
PS:切换scene前和后都有对应的消息推送,我们只需监听对应的事件即可收到对应消息并处理我们想要处理的逻辑。

【12】runScene():运行指定的场景。
        大致就是在当前帧绘制结束后调用【11】runSceneImmediate()来进行场景切换。

【13】loadScene():通过场景的名字来加载场景。
        在assetManager里面通过场景名字来查找对应的bundle,如果有对应的bundle,就通过bundle.loadScene来加载场景,顺利获得scene后再调用【11】runSceneImmediate()来进行场景切换。

【14】preloadScene():预加载场景
        通过assetManger来查找bundle,找到后调用bundle.preloadScene来预加载场景资源。

【15】setDepthTest():是否开启深度测试。
        开启深度测试后,会把深度信息存贮在一个深度缓冲中,在进行渲染时,会从深度缓冲获取Z值进行比较,把最靠近屏幕的片段保存下来,其他片段则会被丢弃(简单来讲就是显示最前面的,后面被前面挡住那些反正看不到,就把他丢弃掉得了)。

扩展延伸-深度冲突:当两个平面或者三角形非常非常接近的时候,深度缓冲精度不足导致判断不了两个三角形哪个在前面时,两个三角形就会不断变换前后顺序导致最后出来奇怪的花纹。解决方案:1.别把两个物体摆太靠近……2.牺牲性能用更高精度的缓冲区…… 个人喜欢方案1,当物体太靠近时,我们人工设置一点偏移值让其避免深度冲突。

【16】_scene:当前正在运行的场景。
getScene()和getRuningScene()在源码里都是返回这个值。

【17】_deltaTime:上一帧和当前帧的时间差。

【18】_startTime:游戏开始的时间(导演类init的时间)

【19】_totalFrames:游戏启动以来运行的总帧数(在每一次主循环+1)

【20】_scheduler:定时器对象,在这里面设置了各大管理器的update。

【21】startAnimation()和stopAnimation():其实调用的是game的pause,暂停主循环。

【22】mainLoop:主循环。具体流程如下(只讨论正式模式下):
1.执行上面说到的【4】,检测布尔值,如果为true则清理导演类
2.this.calculateDeltaTime(now);:计算dt
3.this._compScheduler.startPhase();:执行start函数(component-scheduler.js内部保证start只执行一次)
4.this._compScheduler.updatePhase(this._deltaTime);:执行update函数。
5.this._scheduler.update(this._deltaTime);执行各大管理器的update函数。
6.this._compScheduler.lateUpdatePhase(this._deltaTime);:执行lateUpdate函数。
PS:3,4,6三个步骤也可以看出这3个生命周期函数的执行顺序。
7.Obj._deferredDestroy();:销毁被移除的实体。
8.renderer.render(this._scene, this._deltaTime);:渲染场景
9.eventManager.frameUpdateListeners();:更新事件处理器,检测是否有新的监听需要增加或者有旧的监听需要移除。
10.this._totalFrames++;:总帧数+1
以上过程中间涉及到某些步骤的消息分发,此处跳过不提了……需要用到时去看看有什么相关消息可以监听即可。

这篇关于【三】CocosCreator-CCDirector.js源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/570623

相关文章

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

解决1093 - You can‘t specify target table报错问题及原因分析

《解决1093-Youcan‘tspecifytargettable报错问题及原因分析》MySQL1093错误因UPDATE/DELETE语句的FROM子句直接引用目标表或嵌套子查询导致,... 目录报js错原因分析具体原因解决办法方法一:使用临时表方法二:使用JOIN方法三:使用EXISTS示例总结报错原

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

python中Hash使用场景分析

《python中Hash使用场景分析》Python的hash()函数用于获取对象哈希值,常用于字典和集合,不可变类型可哈希,可变类型不可,常见算法包括除法、乘法、平方取中和随机数哈希,各有优缺点,需根... 目录python中的 Hash除法哈希算法乘法哈希算法平方取中法随机数哈希算法小结在Python中,

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

关于MyISAM和InnoDB对比分析

《关于MyISAM和InnoDB对比分析》:本文主要介绍关于MyISAM和InnoDB对比分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录开篇:从交通规则看存储引擎选择理解存储引擎的基本概念技术原理对比1. 事务支持:ACID的守护者2. 锁机制:并发控制的艺

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis