获得徽章 0
- #每天一个知识点#
2023/07/18
聊聊常驻节点
在 cocos ceater 中我们如何实现常驻节点呢?一般我们可以
cc.game.addPersistRootNode(node);
来使得该节点在场景切换时不会被销毁,什么场景下,我们会使用到常驻节点呢?一般是有
1. 全局数据存储,如果我们有一些在整个游戏中共享的全局数据,用户分数/游戏设置等等,我们把给数据存储到常驻节点中,就能在整个游戏中不同的场景都能使用到。
2.全局的节点访问,如果我们需要多个场景都会访问到的同一个节点,比如一个全局的音效设置等,这样能确保不会被销毁,爷方便访问。
总的来说,使用到常驻节点就是为了便于全局的访问,以及不会被销毁。但是我们得小心,因为全局的东西往往意味着不被销毁,一直占用,滥用导致游戏卡顿,内存占用过高。所以确保只将必要的数据和节点设置为常驻节点,并在不需要时及时释放。展开赞过评论2 - #每天一个知识点#
2023/07/16
单例是否要扩展继承自组件类? 为什么?
今天看到这个问题,感觉挺有趣的,并且之前工作中也遇到这个问题,来说说自己的看法吧。
之前做一个活动的的优化的时候,因为以前是异步加载资源的,改为同步加载资源,类似unity的加载方式,一进入游戏就加载相关的bundle,并且配置必要的资源表加载,同时为了便于资源的静态引入,所以把活动控制层继承组件,并且挂载到主视图中,同时设置该节点不会被随着场景切换移除,这里要注意,因为我们挂载在主场景中,这里的单例不能用懒汉式单例,必须使用饿汉式,避免单例调用的时候使用的指向不一致的问题。类似的还有,创建阶段利用组件的生命周期,销毁阶段,更新节点等,这里可以说是用利用到单例以及结合组件的,实现一些组件的初始化等操作。
同时挂载组件还能利用组件的特性,比如我们在空节点上挂载控制类,控制该节点的active 属性的开启等,节点事件,属性检查等便于开发。
其实具体的使用还得看你的使用场景,其实没有绝对的说法的。一种方案有便利的地方,往往也存在不适合的。比如我们使用单例来挂载组件的时候,因为组件是可以在多个游戏对象上添加和复用的,而单例通常只有一个实例,所有在将单例扩展为组件类时,需要确保在游戏中只存在一个该组件的实例。同时,当把单例扩展为组件的时候,我们需要留意好额外资源的引入等,做好相应的处理展开赞过13 - #每天一个知识点#
2023/07/15
随便聊聊最近一些心得,如今很多小游戏是用cocos ceater 做的,而cocos 使用 TS作为脚本语言,有其好处优点,便于跨平台,但也有它的局促,首先作为一门单线程语言,一崩溃游戏就没法进行了。其次缺少析构函数,宏等概念,在一些场景不够使用。
为了避免出错崩溃,一般首先我们游戏中要确保资源是都存在的,还有就是确保错误的收集,同时对值做处理,处理一些后端没有传递值发生的情况等。
另外,建议个人的经验,小游戏开发中应该做好MVC的写法,工作中有个同事很C语言的写法,面向过程,这会导致一旦我们的接口数据格式发生变化,那么就没发再使用了,基本需要重写实现了。所以把视图层 / 控制层 分开是很有必要的。同时还有就是,减少动态加载,在引擎中加载,因为引擎中导入的资源是属于静态加载,引擎会帮我们处理资源加载释放的问题,避免我们手动加载导致的一些问题。展开赞过评论2 - #每天一个知识点#
2023/07/10
优化Cocos Creator 包体积
优化这一步在游戏中可以说至关重要了,而优化的地方也方方面面,这里就看看再 cocos ceater 中对包体的优化
首先按需导入啦,在cocos ceater 项目 - 模块设置中,我们可以按需导入需要的模块,比如,如果单纯的2D游戏,就不需要物理系统
过来就是图片资源,图片资源首先是可以在不影响效果呈现的情况下做压缩,其次是尽量使用9宫格图片,打包图集。
字体资源体积优化,尽可能使用系统字体,移除不用的字体,性能上的优化也提一嘴吧,在场景中使用系统字体或 TTF 字体的 Label 会打断渲染合批,特别是 Label 和 Sprite 层叠交错的情况,每一个 Label 都会打断合批增加一个 DrawCall,对于游戏中的文本,特别是数字、字母和符号,都建议 使用 BMFont 来代替 TTF 或系统字体,并且 将 BMFont 与 UI 碎图打包到同一图集中(或 开启动态合图),可以免除大部分文本导致的 DrawCall。展开赞过评论2 - #每天一个知识点#
2023/07/09
游戏开发中的坐标
刚入行的时候坐标真的是个超级烦人的东西,实话说现在我都还不是特别的里的清楚,今天就大概梳理一下这块的东西吧
首先坐标都有哪些,首先分为两类,一类是世界坐标(绝对坐标),一类是本地坐标(相对坐标)。什么是世界坐标呢?那就是这个一整个游戏中的坐标系,采用的是笛卡尔右手坐标系。而本地坐标可以理解为每个节点自身的坐标系。
这也就导致为什么有些时候我们输出两个节点的坐标的时候,坐标值明明是一样的,但是实际中我们看到的确实是不一样,这是因为他们的父节点的坐标系是不同的。我们往往当想拿到某一个坐标的位置,然后把另一个节点的坐标设置到该位置的时候,就的得考虑到这一点
,也就是下面的转化公式:
本地坐标转换为世界坐标
世界坐标 = 父节点.convertToWorldSpaceAR(子节点坐标);
世界坐标转换为本地坐标
本地坐标 = 转换点.convertToNodeSpaceAR(世界坐标)展开等人赞过评论4 - #每天一个知识点#
2023/07/08
cocos assetManager 资源加载管理
在游戏中,资源的加载管理也是个大问题,没有好好清楚很容易导致各种比如热更新出问题,游戏卡顿的问题等。今天简单说个关于包的问题,首先我们一般会把独立的部门设置为一个包,比如活动/关卡,这样我们可以根据运营的计划,来安排那些被开启加载等。那么设置为bundle。这里面发生什么呢,来说说里面会有的问题:
首先我们的游戏构建之后,一般就是所有资源都被分到内置包( internal / main / resources / start-scene )以及我们设置的单独 bundle 中。
在构造阶段,配置为 bundle 的文件夹就会把文件夹中的资源,以及该文件夹中依赖的其他资源合并到该 bundle 中,文件中的资源会主要被分为三类,代码 / 资源 / 资源配置,放到四个文件夹中(import/ native / config.json / index.js),另一点需要说的是bundle的优先级问题,多个包引用一个资源,如果budle 的优先级都相等,就会把这份资源复制多分,每一个bundle里面都有一份,而要是有一个优先级更高,就会只在优先级高的bundle 保存一份,而其他包引用就会指向该bundle(所以如果低优先的包要使用该资源就需要先加载这个优先级更高的 bundle)
当我们加载 包(bundle)(loadBundle() )的时候,其实并没有把这个包的资源都加载到内存里面,而是只是把 config 以及脚本加入,需要加载资源的时候我们需要 (bundle.load())来载入我们需要的资源。这里也就是我们经常一进游戏卡顿的问题,因为一进入游戏,大量的资源进行 load,导致高额IO压力。(我们现在的处理是对所有该该操作做队列处理,避免一次性同时加载).高IO在网页调试中中能看到比较明显,但相反在手机上问题更大的是 包的下载花费的时间,所以cocos 提供预加载,我们可以先下载必须的部分,而在后面缓慢下载其他资源。
资源加载后当然也需要释放,引擎也有对该部分的处理,包含计数释放,静态资源和动态资源的处理等,以及我们主动释放,另外加载进入内存的资源不会被主动释放,也会导致内存越来越大等问题展开等人赞过314 - #每天一个知识点#
2023/07/07
单例模式中
饿汉式单例和懒汉式单例
虽然之前有学习过,这两者区别,但是还是得实际工作中遇到问题了才能比较深刻的体会出两者的区别。
饿汉式和懒汉式应该是我们比较常用的单例了,昨天在工作中做的操作是进入游戏就对一个活动的控制层做初始化下载资源的数据,然后交给资源管理层做下载处理。该活动之前是另一个人同事写的,采用懒汉式的写法,没有调用单例就不会创建。但是再我今天的改动中,变一进入游戏就会对数据做初始化,这时候其实已经创建了 this,但是因为没有调用获取单例,所以这个this是没有赋值给单例的,这就导致在别的地方调用单例的时候就又创建了一个单例,创建了一个新的 this。这时候其实也就不能说这个控制层是唯一的了;那么其实这里我们一进入游戏就需要做初始化的,因该改为饿汉式单例,一进入初始化的时候就赋值单例,样的话才能确保这个单例是惟一的。
两者简单来说,懒汉式是在调用的时候才会创建,而饿汉式是只要有就创建,前者可以说是能减少内存的浪费,以为只有在第一次调用的时候才会被创建。而后者是加载的时候就初始化创建了,问题就是相反的浪费内存了,有些时候即使可能一直没有使用也创建出来,产生垃圾对象展开赞过评论1