众所周知,Java在运行效率方面本身就无法和C/C++或是Objectice-C相比,且Java语言处理内存也很不自由。这就导致由Java语言设计的AndEngine游戏引擎在效率上无法和Cocos2d媲美,但是只要在编码时注意效率方面的问题,AndEngine引擎完全可以胜任我们绝大部分需求。接下来就谈一下在项目期间实践与阅读中的关于提高效率方面的一些问题,仅供参考,也希望批评指正。
声明:基于opengl-es2。
1. 首先是纹理(texture)加载方面,尽量将图片贴到一张纹理上,通过load方法向内存加载一次,反之则会多次向内存加载,效率也会随之降低。这里讲图片贴到一张纹理有两种途径。简单提示一下,首先是用BitmapTextureAtlas,初始化时需要赋予图片贴到纹理上的具体坐标(我是用计算的笨方法,应该可以在PS之类的工具上快速实现吧),且要保证不能重叠。另一种方法使用BulidableBitmapTextureAtlas(推荐),这里初始化的时候就不需要传递具体坐标参数的,但在load()之前记得build()一下,如下所示:
1 try { 2 mBuildableBitmapTextureAtlas.build(new BlackPawnTextureAtlasBuilder< 3 IBitmapTextureAtlasSource, BitmapTextureAtlas>(0, 1, 1)); 4 } catch (TextureAtlasBuilderException e) { 5 e.printStackTrace(); 6 } 7 mBuildableBitmapTextureAtlas.load();
2. 打开AndEngine引擎源码,会发现有PVR与ETC1类型的textures类,他们是compressed的texture,利用他们可以降低load()的时间,且在游戏时增加帧率。
3. 重载onCreateEngine()方法设置engine类型,有以下几种:Engine、FixedStepEngine、LimitedFPSEngine、SingleSceneSplitScreenEngine、DoubleSceneSplitScreenEngine。以FixedStepEngine为例:强制设置engine更新的速度。
@Override public Engine onCreateEngine(EngineOptions pEngineOptions) { // Create a fixed step engine updating at 60 steps per second return new FixedStepEngine(pEngineOptions, 60); }
4. 对于一些无需更新的Entity(Engine、Scene、Layer、Sprite等的父类)做一些处理如下:
Entity entity = new Entity(); // Ignore updates for this entity entity.setIgnoreUpdate(true);
这里关键即是“无需更新”,例如:背景Sprite、运行至终点的Bullet Sprite等等。
接下来再引申一下AndEngine的更新机制(电脑上没装visio,所以就不提供流程图了),首先是engine去updates,去调用main scene的update相关方法,然后main scene去调用其子entity的onUpdate()方法,以此类推。
5. Disabling background window rendering.第一步在res/values/目录下创建theme.xml文件,添加代码:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<style name="Theme.NoBackground" parent="android:Theme">
<item name="android:windowBackground">@null</item>
</style>
</resources>
然后在 AndroidManifest.xml文件中做如下设置:
<application android:theme="@style/Theme.NoBackground" android:icon="@drawable/ic_launcher" android:label="@string/app_name" >
6. 对于需要在同一时刻播放大量音频流的游戏,则有必要设置同一时刻音频流的数量(默认为5),如下:
@Override public EngineOptions onCreateEngineOptions() { mCamera = new Camera(0, 0, 800, 480); EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new FillResolutionPolicy(),mCamera); engineOptions.getAudioOptions().setNeedsSound(true); engineOptions.getAudioOptions().getSoundOptions(). setMaxSimultaneousStreams(2); return engineOptions; }
7. 尽量少的创建对象可以有效保证游戏的流畅运行,为满足这一要求,可以利用object pools(引擎中主要是sprite pools)来循环利已创建的对象。有人可能会想创建后用完detach()不就可以了,但是这样会使GC有机会回收此entity,这就有可能造成画面停滞一下。此方法仅提供思路,具体代码科参考这本书《Packt AndEngine for Android Game Development》,下载:http://download.csdn.net/detail/e6mail/6354795。随书代码有需要的可以要。