【三】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中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

JS 实现复制到剪贴板的几种方式小结

《JS实现复制到剪贴板的几种方式小结》本文主要介绍了JS实现复制到剪贴板的几种方式小结,包括ClipboardAPI和document.execCommand这两种方法,具有一定的参考价值,感兴趣的... 目录一、Clipboard API相关属性方法二、document.execCommand优点:缺点:

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步