性能优化 虽然Starling模仿了Flash传统显示列表,但您要知道屏幕背后发生的事情是有很大不同的。要得到应用的最佳性能,您需要了解关于Starling体系结构的一些关键概念。下面是一些您可以遵循的,让您的游戏尽可能的快速的最佳实践。
如您所知,Starling使用Stage3D来渲染所有的可见对象。这就意味着所有的绘制都是GPU完成的。 现在,Starling可以一个接一个的发送四边形到GPU,然后一个接一个的绘制。实际上,这也是最初版本的Starling的工作方式。然而,为了更好的执行效率,GPU希望能得到大量的数据,然后在一次调用中绘制所有的对象。 这也是为什么Starling的最新版本要在发送数据到GPU之前要包含尽可能多的四边形。然而它只能批量处理那些拥有相似属性的四边形。每当遇到一个具备不同“状态”的四边形,就会触发“状态改变”,上一个批次的四边形就会被绘制。 这篇文章中,我将使用“Quad”和“Image”来代表相似的概念。请记住,Image只是Quad的一个添加了纹理的子类。 下面这些是促使状态发生改变的关键特性:
一些移动设备硬件(比如第一代的iPad)处理纹理的“着色”时非常困难,包括:
这里有个简单的技巧来避免状态变更:只需要设置您的根对象(root object)的透明度为“0.999”或一个近似的值。由于这个透明度会向下影响到子元件的渲染,Starling会将任何对象都按照“着色”对象来对待,这样就不会触发过多的状态的变更了。
和传统Flash类似,Starling也采用了一种“画家算法”来处理显示列表。这个算法的意思就是,就像一个画家所做的那样,来绘制您的场景:首先绘制最底部的对象(比如一个图片背景),然后再绘制上一层的对象(以此类推)。 如上图所示,如果您想在Starling中创建这样的场景,您可以创建3个Sprite容器:一个用来包含远处的山脉,一个包含地面,一个包含植被。山脉的排序肯定在最底部(索引是0),植被的排序是在最顶部(排序是2)。每一个Sprite会包含有实际内容的图片。 在渲染的时候,Starling会先渲染最左侧的”Mountain 1″,并向右继续渲染,直到到达 “Tree 2”。现在,如果所有的对象都有不同的状态,那么就会造成6次绘制调用。如果您从每一个单独的图像来加载每一个对象的纹理,就会发生这样的情况。
这就是纹理图集是如此重要的原因之一。如果从一个单一的图集加载所有这些纹理,Starling就可以在一次调用中完成所有的绘制! (假如上面列出的其他属性没有改变的话。) 在这里,每个图像都使用相同的图集(用所有节点具有相同的颜色来表示)。这样的后果就是您应该总是让您的所有纹理使用同一个纹理图集。
然后,有时候,并非所有的纹理都能融合到一个单一的图集上。一个纹理图集的限制是2048*2048像素(这是一些移动设备硬件的限制),所以您早晚都会碰到这种所需纹理为空的情况。但是这也没什么问题—只要您用一种聪明的方式来安排您的纹理。
如上图所示,这两个例子都是使用了两个纹理图集(同样,每一个纹理图集用一个颜色表示)。但是左侧的显示列表,将强迫每个对象发生状态改变,而右侧的版本则可以只需要两次批处理就能绘制所有的对象。
为了摆脱这些限制,您可以去使用Starling的一个底层类:QuadBatch。它的工作原理是这样的: 您是不是已经注意到了?如果您愿意,您可以重复添加相同的图像!此外,它不会引发任何事件调度。然而事务都有两面性,这
文本框支持两种不同的字体:True Type字体和位图字体。 TrueType字体最容易使用:只需嵌入所需的“ttf”文件,您就大功告成了。为静态文本框包含数百个字符,这是一个很好的和快速的选 择。Starling会将文本渲染成位图,显示文本的时候就像一个纹理一样。对于重复改变的短文本(比如分行显示),这样处理还是挺慢的。
如果您的游戏需要显示的文本中包含许多非ASCII字符(如中文或阿拉伯文),TrueType字体可能是您唯一的选择。位图文本只是受限于它们的纹理大小。
使用位图字体的文本框,创建和更新都是非常快速的。另一个优点是,它们不会占用任何额外的纹理内存,除了它们所需的原始纹理。这是在Starling中显示文本的首选方式,我的建议是尽可能的使用它们。
如果您有完全不透明的矩形纹理,可以帮助GPU禁用那些纹理混合。这对于大背景图像特别有用。不要害怕这将导致额外的状态变化,这是值得的!
backgroundImage.blendMode = BlendMode.NONE;
如果您的游戏背景是一个单独的颜色,请设置stage的颜色来代替添加一个纹理或一个着色的四边形。反正Starling每一帧都要做stage的清理工作—如果您改变了stage的颜色,那么也没有额外的消耗。这简直就是免费的午餐哦,记得享用。
[SWF(backgroundColor="#ff2255")] public class Startup extends Sprite { // ... }
避免重复调用width和height 获取宽度和高度属性是一个昂贵的性能开销,特别是对于Sprite容器(首先矩阵进行计算,然后每一个子元件的每个顶点都和该矩阵相乘)。 出于这个原因,请避免重复访问它们,比如在一个循环里面。在某些情况下,使用一个恒定的值来代替它们更有意义。
当您在屏幕上移动您的光标/手指的时候,Starling就会寻找哪一个对象被点击了。这可能是一项昂贵的操作,因为它需要遍历所有的显示对象,并调用hitTest方法。 因此,如果您不需要一个对象被触碰,将它设置为“untouchable”是非常有帮助的。最好是在容器上进行禁用:这样,Starling就不会遍历它的子元件。
使用新的事件模型 从Starling 1.2开始, 有一个新的方法来派发事件:
以下的优化方式是通用的(并不特指Starling),对于所有的ActionScript项目都是最佳实践。但是别太高估它们:您的首要任务是保证代码的优良结构和可读性。这些优化在一些每帧都调用的代码中最有效。 循环 避免“for each”. 用传统的 “for i”是最快的. 此外需要注意的是,将一些变量事先保存,在每次循环中调用,也是非常有用的。
避免创建对象 避免产生大量的临时对象。它们占用内存,并且需要由垃圾收集器进行清理,这可能会导致运行时的”卡壳”。
访问数组或向量数组元素 当您从一个数组或一个向量数组中引用一个对象的时候,要小心:当对象索引是一个计算结果的时候,请转换为int类型。出于某种原因,这样可以让AS3计算更快。
|
Starling性能优化技巧
最新推荐文章于 2024-03-28 19:09:44 发布