【问题标题】:Adobe AIR - How to optimize for MobileAdobe AIR - 如何针对移动设备进行优化
【发布时间】:2015-05-05 00:02:27
【问题描述】:

我正在使用 AIR 将 Flash 浏览器游戏转换为移动设备。使用 flash builder profiler 我发现我的瓶颈是

[渲染] - 42.31% [预渲染] - 41.41%

我的应用程序有超过 80% 的时间用于渲染。游戏目前对 UI 元素、角色和宠物使用矢量图形(最多可以有 15 个角色和 15 个宠物)。背景是位图。

我们在将矢量字符和宠物转换为位图时遇到了麻烦,发现在某些情况下,如果矢量艺术动画很多,我们会获得很大的收益,但对于其他动画很少的角色,它实际上运行速度较慢(我相信是因为重绘矢量图上的区域太小了)。

我相信我们可以在渲染方面获得的最大收益是删除矢量图,但我认为我们为位图制作动画的基本方法并不是在每种情况下都更好。是否有任何优化的 AS3 库来处理动画位图或转换矢量图?非常感谢您可以指出我研究这些主题的任何资源。

谢谢!

【问题讨论】:

标签: actionscript-3 mobile air


【解决方案1】:

这是一个非常广泛的问题,可能不太适合 Stack Overflow,但我会给你一些建议:

由于您使用矢量图形,我假设您在 CPU 模式下使用本机显示列表运行。像矩形这样的基本矢量形状在 CPU 模式下的 AIR for mobile 上具有良好的性能,但更高级的形状可能会很快压倒移动 CPU 并导致帧速率有所损失。

如果您有大量矢量图形,您最好在 GPU 模式下运行并使用 cacheAsBitmap 属性缓存矢量图形:http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00001283.html#374074 请注意,如果图形非常大或导致渲染,这可能会影响您的性能如果您在有子对象的对象上使用 cacheAsBitmap,则会出现工件。

真正的答案是你应该切换到像免费和开源的Starling这样的高性能库:http://gamua.com/starling/我已经好几年没有使用原生显示列表了,因为在Starling中的性能明显更好. Starling 非常容易与 AIR 集成,并尽可能模拟显示列表的行为,因此向 Starling 的过渡几乎毫不费力。

需要注意的是,它不支持矢量图形,但您可以将它们渲染为位图,然后将它们加载到 Starling 纹理中。更好的是,将您的图形渲染到精灵表中,然后将它们作为纹理图集导入 Starling,从而为您提供出色的性能和轻松的资产管理。

【讨论】:

  • 我从未听说过 Starling,谢谢您的提示。我一直在研究它并检查性能指标。我发现这篇文章esdot.ca/site/2012/… 似乎声称 Starling 并不比使用 GPU 模式快多少。
  • 我希望你不要把 3 年前的文章当成性能指标。在过去的 12 个月里,我在 Android 和 iOS 上发布了近十个 Starling 应用程序;它更加更快,更容易使用。
【解决方案2】:

。避免将矢量图形放在一起。

。保留 Starling 引擎和类似引擎,以应对图形显示性能必须达到最佳的绝境。使用这些引擎需要超精确的 GPU 内存管理 + 上传到 GPU 非常缓慢且 CPU 负担重(由于内存过载可能导致应用程序崩溃)。如果必须使用它,请仅将其用于需要性能的图形部分。

。大量使用 blittering 和 BitmapData。在大多数情况下,该技术足以获得非常快速和灵活的图形显示。

【讨论】:

  • 我在 GPU 内存管理方面从未遇到过严重问题。只要您不上传数十个 2048*2048 纹理,就应该没有问题。在大多数情况下,我可以将所有精灵放在不超过两个 2048*2048 的图集上,以及一到三个 2048*2048 背景。在一种情况下,我确实有更多的背景,但很容易根据需要将它们调入和调出资产管理器。首次启动时,上传到 GPU 只需片刻。在性能的巨大提升、减少您需要编写的代码量以及更好的内存管理之间,Starling 是一个非常强大的选择。
  • 不要让它听起来好像没有缺点,有很多缺点。 2 2048x2048 会使 iPad 1 崩溃。
  • 也许,但我从未遇到过任何严重的问题。 9 个月前,iPad 1 占据了苹果平板电脑 6% 的市场份额:cdn.macrumors.com/article-new/2014/09/… 在此期间,苹果拥有约 27% 的平板电脑市场份额(forbes.com/sites/davealtavilla/2014/10/17/…),iPad 1 占所有平板电脑的 1.6% 九个月前。您可以自行决定 iPad 1 是否值得。
  • 另一个想法 - 为了很少额外的头痛,您可以为不同分辨率的设备制作不同大小的精灵表。像 TexturePacker 这样的实用程序使这个过程几乎毫不费力。
  • 感谢大家提供的精彩信息!
【解决方案3】:

您可以创建常规 mcs(矢量、jpg、位图、动态文本等)、创建位图副本和删除常规 mcs。您可以将位图放在影片剪辑和子影片剪辑中,并以 60fps 的速度平稳移动它们,只要您使用的总内存合理(需要时使用池)。侦察兵会告诉你

这里有一些代码片段显示了将常规 mcs 转换为位图图块 - 您必须将位图的尺寸保持在设备的最大值以下,因此简单的解决方案是使用设备的屏幕尺寸作为最大值。

//  set the bmp dimensions to device screensize to prevent exceeding device's max bmp dimensions
if (bStagePortrait) {
    iTileWidth = Capabilities.screenResolutionX;
    iTileHeight = Capabilities.screenResolutionY;
} else {
    iTileWidth = Capabilities.screenResolutionY;
    iTileHeight = Capabilities.screenResolutionX;
}

//  mcList.mcListVector is the source mc - a regular mc containing mcs, jpgs, dynamic text, vector shapes, etc.
//  mcList.mcListBmp is an empty mc

aListTiles = new Array();
iNumberOfTiles = Math.ceil(mcList.height / iTileHeight);

for (i = 0; i < iNumberOfTiles; i++) {
    var bmpTile: Bitmap;
    //  move the source mc
    mcList.mcListVector.y = -(i * iTileHeight);
    bmpTile = fDrawTile(mcList, 0, 0, iTileWidth, iTileHeight);
    mcList.mcListBmp.addChild(bmpTile);
    bmpTile.x = 0;
    bmpTile.y = (i * iTileHeight);
    aListTiles.push(bmpTile);
}

//  remove the regular mc
mcList.mcListVector.removeChild(mcList.mcListVector.mcPic);
mcList.mcListVector.mcPic = null;
mcList.removeChild(mcList.mcListVector);
mcList.mcListVector = null;
}


function fDrawTile(pClip: MovieClip, pX: int, pY: int, pWidth: int, pHeight: int): Bitmap {
    trace("fDrawTile: " + pX + "," + pY + "  " + pWidth + "," + pHeight);
    var rectTemp: Rectangle = new Rectangle(pX, pY, pWidth, pHeight);
    var bdClip: BitmapData = new BitmapData(pWidth, pHeight, true, 0x00000000);
    var bdTemp: BitmapData = new BitmapData(pWidth, pHeight, true, 0x00000000);
    bdClip.draw(pClip, null, null, null, rectTemp, true);
    bdTemp.copyPixels(bdClip, rectTemp, new Point(0, 0));
    var bmpReturn: Bitmap = new Bitmap(bdTemp, "auto", true);
    return bmpReturn;
}

这种转换会使您的 fps 窒息一秒钟,但您可以使用常规代码(补间)以 60fps 移动 mcList。

【讨论】:

    【解决方案4】:
    • 正如大家所说,不要使用矢量或在位图数据中绘制它
    • 使用 GPU 渲染
    • 您不能在 GPU 模式下使用过滤器,因此如果您使用任何过滤器,则必须使用 BitmapData.applyFilter
    • 查看 Starling 或 Flixel
    • 尽可能使用 copyPixel 而不是 BitmapData.draw
    • 如果您要渲染大量内容,然后再制作动画,则在动画对象之前跳过一个 ENTER_FRAME 事件。这将使所有过渡和动画尽可能平滑(这实际上对我制作的所有应用程序产生了很大影响)

    【讨论】:

    • 有趣。我会试试最后一部分。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-02
    • 1970-01-01
    相关资源
    最近更新 更多