正如Adobe's Scout的许多用户已经注意到的那样,解压缩图像可能是对帧速率敏感的应用程序(例如游戏)的最大性能打击。
我的游戏中遇到了问题(2D侧卷轴)。帧率非常平滑(50+),除非侦察显示图像解压缩事件,然后降至2 - 15 fps。太可怕了。我添加的图像越多(屏幕上的图块)就越多。
如果您对此不熟悉,请注意闪存播放器会从内存中删除不需要的图像,而不会显示在屏幕上,并在移动到图像后重新解压缩它们屏幕再次。据报道,大约每10秒发生一次。
我想分享我的解决方案并询问你自己的一些解决方案,因为我认为目前的情况远非令人满意。
让我们从明显和我的评论开始:
评论:这有帮助,但减压仍然会发生,导致通常的滞后问题。
评论:由于显而易见的原因,这也有很大帮助。图像较大,因此显示在所有屏幕上,或者在任何给定时间显示更多,因此Flash无法摆脱它。这实际上是一个丑陋的解决方案,原因显而易见:导入大图像时Flash崩溃,存在尺寸限制,并且在设计关卡或图形应用程序而非图块时通常很难处理大图像。但是,有时这可行。
评论:它确实有用,但它甚至比上面的解决方案更糟糕(如果它甚至可以称之为),它实际上只是一种解决方法,可以防止Flash在导入大图像时崩溃或者如果你达到最大尺寸。它可以做到这一点。如果您只使用下面的位图作为形状对象的填充,您可以将这些图像隐藏在其他闪光层或图像下面,有时只有很少的性能命中。
评论:在我的游戏中,这本身几乎没有任何区别,但是当我将它与解决方案一混合时,它似乎有点帮助。这是代码:
var loaderContext:LoaderContext = new LoaderContext();
loaderContext.imageDecodingPolicy = ImageDecodingPolicy.ON_LOAD
var loader:Loader = new Loader();
loader.load(new URLRequest("gameLevel.swf"), loaderContext);
我知道这通常用于加载位图,但它适用于swf,尽管只是略有不足。
评论:我读过这对某些人有用,但对我来说绝对没有。这是非嵌入资产(Keeping Bitmaps Decompressed)代码中最重要的部分:
var bmd:BitmapData;
var timer:Timer = new Timer(1000);
timer.start();
timer.addEventListener(TimerEvent.TIMER, onTimer);
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
loader.load(new URLRequest("Adobe_Flash_Professional_CS5_icon.png"))
function onLoaded(ev:Event): void
{
bmd = ((ev.target as LoaderInfo).content as Bitmap).bitmapData;
}
function onTimer(ev:TimerEvent): void
{
bmd.getPixel(0, 0);
}
如果你像我一样,并使用嵌入式图像,你可以使用以下内容调整代码:
//be sure to set the library item on Flash Pro to be exported to ActionScript 3,
//and give it a class name, in this case Artwork.
var Artwork:Class;
Artwork = getDefinitionByName(Artwork) as Class;
bmd = new Artwork();
然后只需每隔10秒调用一次getPixel()函数将图像回收到内存中。
太糟糕了,它对我来说没什么意义!!
评论:这非常有效,几乎与伪解决方案" 2-3。帧速率不是很好,但它可以非常顺利地消除由于减压引起的打嗝。这当然可以通过代码来完成,例如instance.cacheAsBitmap = true;或者直接在渲染选项下直接使用Flash Pro。
评论:也没为我做过一件事。我也不明白为什么它应该:
var loadedBitmapData = event.target.content.bitmapData;
var newBitmapData:BitmapData = new BitmapData(loadedBitmapData.width,loadedBitmapData.height);
newBitmapData.copyPixels(loadedBitmapData,new Rectangle(0,0,loadedBitmapData.width, loadedBitmapData.height),new Point(0,0));
这就是我所尝试过的,但正如你所能想象的那样,我对这些管道录音带很不满意。对我来说,这些看起来都是平庸的补丁,可能除了解决方案4和5之外,除了它们并不能为我做任何事情。
所以,这是我的问题:
您能否帮助我探索为什么解决方案5和7不会出现问题的答案。为我工作?我在代码中使用嵌入式图像选项,而不是使用计时器,在enterFrame调用的计数器++变量上50个刻度后调用它。
您能提供其他解决方法吗?
答案 0 :(得分:-1)
1)你显然没有在你的项目中使用Stage3D,否则你可以使用Adobe Texture Format,这在UI冻结问题上更加方便。
2)"如果您对此不熟悉,请注意Flash播放器会从内存中删除不需要"的图像,屏幕上不显示,并重新解压缩一旦你再次将它们移动到屏幕上。据报道,大约每10秒发生一次。"这看起来很怪异。将压缩图像解压缩为BitmapData后,由于您引用了BitmapData,因此GC无法收集它,因此世界上没有任何东西可以让您根据自己的意愿对其进行解压缩。从未听说过Flash Player这样做。
3)如果您从本地文件系统而不是从远程文件服务器加载图像,请尝试使用FileStream.openAsync将文件加载为bytearray,然后使用第三方PNGDecoder对其进行解码。不确定嵌入式资产。