【三】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

相关文章

Nginx分布式部署流程分析

《Nginx分布式部署流程分析》文章介绍Nginx在分布式部署中的反向代理和负载均衡作用,用于分发请求、减轻服务器压力及解决session共享问题,涵盖配置方法、策略及Java项目应用,并提及分布式事... 目录分布式部署NginxJava中的代理代理分为正向代理和反向代理正向代理反向代理Nginx应用场景

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

在Node.js中使用.env文件管理环境变量的全过程

《在Node.js中使用.env文件管理环境变量的全过程》Node.js应用程序通常依赖于环境变量来管理敏感信息或配置设置,.env文件已经成为一种流行的本地管理这些变量的方法,本文将探讨.env文件... 目录引言为什么使php用 .env 文件 ?如何在 Node.js 中使用 .env 文件最佳实践引

MyBatis Plus大数据量查询慢原因分析及解决

《MyBatisPlus大数据量查询慢原因分析及解决》大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次... 目录大数据量查询慢的常见原因优化方案高级方案配置调优监控与诊断总结大数据量查询慢的常见原因MyBAT

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

使用Node.js和PostgreSQL构建数据库应用

《使用Node.js和PostgreSQL构建数据库应用》PostgreSQL是一个功能强大的开源关系型数据库,而Node.js是构建高效网络应用的理想平台,结合这两个技术,我们可以创建出色的数据驱动... 目录初始化项目与安装依赖建立数据库连接执行CRUD操作查询数据插入数据更新数据删除数据完整示例与最佳

Java中最全最基础的IO流概述和简介案例分析

《Java中最全最基础的IO流概述和简介案例分析》JavaIO流用于程序与外部设备的数据交互,分为字节流(InputStream/OutputStream)和字符流(Reader/Writer),处理... 目录IO流简介IO是什么应用场景IO流的分类流的超类类型字节文件流应用简介核心API文件输出流应用文