Andengine 学习笔记 - 山寨保卫萝卜的总结

出于练手的目的,山寨了一个保卫萝卜,过程中有一些经验和教训,记录一下,备忘。

一、框架设计
对于游戏来说,引擎已经替我们完成了底层绘图的操作,而我们只需要管理图片的加载和生成逻辑上的各个实体,这样整个游戏很好模块化:资源模块、实体模块、管理模块。

1、模块之间的访问会比较频繁,所以使用的是中介者模式,以减少模块之间的耦合;
2、管理模块中对于被管理的所有实体,必须池化以减少内存开销;
3、各个模块必须有完整的初始化和销毁的逻辑,因为游戏不同于应用没有Activity的概念,游戏中有很多切换相当于局部的销毁和重新初始化,这块的逻辑不完成引起的后果不是内存问题就是性能问题;
4、对于不同场景的资源,切换一个场景就应该释放当前场景的资源,因为资源是由引擎来管理的,实际上也是受GPU限制的,就算不主动释放也不能像普通的缓存一样一直存在在内存里,并没有太多益处,而在reload和一些特定的场景里还会引起内存问题,所以实际上释放资源是更好的实践;

二、性能调优的实践
游戏的原型开发完成之后不可避免的遇上了很多性能瓶颈,也学到了很多经验

1、池化的对象管理和工厂类统一生成对象。严格的控制对象的生成是很重要的,因为在游戏中,一不小心就会产生大量的对象,随后引发的gc问题也好OOM问题也好都会比较棘手,所以在实践中干脆窄化对象的生成,所有的对象一律从工厂中生产并且池化,最大限度的减少这块的内存消耗,提高性能;
2、一切疑似的耗时算法都应该异步进行。这里的疑似,就是应该保持对耗时算法的警惕性,因为并不是每个耗时算法都那么明显。在开发过程中,就发现风扇塔的子弹在行进过程中可以攻击多个怪,每次都扫描一次怪物堆,因为存活的怪物堆里的怪物不多,所以当时完全没有考虑异步的问题,结果就是当风扇多起来之后游戏变得巨卡,才发现到不停的搜索遍历还是会导致性能问题。解决方案也很简单,把多次攻击的子弹搜索逻辑加入到异步的任务里,游戏界面立马就不卡了;
3、摒弃一切卡主线程的行为。有一个性能问题,源自于一个小小的synchronized关键字,开始都没有注意到这个关键字,后来证明,即使那个方法没有多线程访问,加上了synchronized关键字以后jvm在处理上还是会引起效率问题,去掉synchronized以后性能问题解决,再次证明,主线程只需要处理逻辑,而其他同步或耗时的都要用异步的方案来处理。
4、遇上一个问题,切换场景gc时间略长且不等,导致绘制完成后的第一帧的间隔时间很长,引起一系列问题,后来想到一个解决方案:跳帧,直接跳过不正常的那一帧,目前正常,但是不确定会有什么问题。
5、实际上移除Entity的操作是一个开销较大的操作,因为要对引擎加锁,如前所释,实践中应该尽量避免加锁的行为,这里加锁可能导致移除大量对象时会卡主线程导致黑屏之类的问题,所以尽量的少移除,可以用隐藏的方式来替代移除
6、load资源是一个耗时的动作,是采用异步的方法来加载,但是在实践中遇到的一个问题是,游戏进入loading界面和加载资源是并发进行的,而加载资源这个动作可能引起大规模的gc,导致stop the world,从界面上表现就是黑屏而不显示loading界面,这样是比较难看的,于是想到一个办法:在每一次启动加载资源线程的时候先sleep一个很短的时间,这样可以保证loading界面先被绘制出来再开始加载,之后就算是gc引发stop the world在界面上也完全看不出来,这是在实践中解决问题的一个很好的方案。

你可能感兴趣的:(游戏,Andeinge)