上一篇文章介绍了webgame客户端开发的一些优化技巧,github上面看一些列表老是不正常,于是我就网上找资料。其实网上的资料是有误的,反正我试过放在上面是无效,放在下面就立即奏效了。
这段时间面试了两三家公司,有大公司也有小团队,他们都问了我关于flash的垃圾回收机制和我平时在项目里面怎么做到内存管理优化和CPU性能优化。其实我之前一直有去看着一块,开发过程中也刻意去关注这块,只是最近做逻辑功能比较多,把很多底层的知识都忘记了,说出来也是一块一块的。趁着现在有空就总结一下,有可能写不全或者不对,以后还会陆续修正和添加。
我之前负责的两个项目都是MMOARPG,两个项目整体的架构都是一致的,可能最大的不同就是前者没有模块化而后者有模块化。其实模块化最好的好处就是减少了主文件的大小,把一部分可以拆分的模块代码分别编译到不同模块的swf里面去,当需要某个功能模块的时候才去加载这个模块对应的swf文件。迟些我会特意写一篇文章去总结后者项目模块化的做法。
说到游戏的资源加载,可以划分为两个阶段,分别是“游戏准备阶段”和“游戏运行时”。
“游戏准备阶段”是指从玩家进入游戏、选定角色、填写名字、等待加载、角色正式在场景。这个过程一般是由外壳去加载游戏的主文件和游戏开始前必须加载的资源(譬如常用皮肤、配置表等),完成这部分加载之后角色其实已经正式进入场景,部分UI界面已经初始化完毕了,在这个时间我们还可以进行背后加载。为了不影响玩家的体验,这个时候是看不到loading的图标的,所以我们才叫背后。我们可以用这个方法去加载一些功能模块的皮肤(譬如好友皮肤、邮件皮肤等),因为游戏刚开始玩家一般都不会去操作这些功能。
在“游戏运行时”这个阶段较优的加载策略主要是按需加载,需要什么则去加载什么,等加载完成我们再去初始化该部分。上面提到的模块化也是用这个思想去实现的。
这里提的到cache包括了浏览器的cache、sharedObject实现的本地cache、对象池。有些玩家可能先去N服玩了一下,然后又跑去N+1服完,这个时候浏览器的cache就起到作用了,只要保证不同服的资源是从相同的CDN地址下获取的则可。不过这个有时候还得看运维的同事怎么去安排,这一个cache就不是我们客户端同志所需要花心思的地方。现在几乎所有flash的页游都有做本地缓存的机制,如果这个都没用就真的不好意思拿出来卖了。说到sharedobject,我推荐.minerva这个air工具,它可以用来查看本机保存下来的.sol文件。建议对象池用Vector去实现,因为它在某种情况下是优于Array的。对象池的实现方法和原理网上找找就有很多。
要做CPU的相关优化必须清楚认识flash的渲染机制。
昨天晚上去一家相熟的公司面试手游客户端开发,面试官想了解我最近在研究什么技术,我只有不好意思地说在看《C和指针》这本书,刚好看到数组这一章。哎呀呀,没想到他居然问我const char*和char const*的区别,还好我有印象,但后来他又问了一下const char* const,这下我就懵了。。偶不会。
常量指针,就是这个指针指向的数据类型必须是一个常量,但这个指针的值是可以改变的,只要指向的是常量则可。
指针常量,就是这个指针指向的内容是char类型,且这个地址是不变的。但这个指针指向的内容是可以改变的。
指向常量的指针常量,就是这个指针是指向常量且地址不可改变。