2009-09-21 62 views
9

我目前正在研究一个非常大型的Flash平台游戏(数百个课程),并且处理游戏慢慢磨砺到停止的问题,如果你足够长的时间。我没有写游戏,所以我只是模糊地熟悉它的内部。一些神秘的症状包括,随着时间的推移,AS3的游戏性能大幅下降

  • 游戏将运行良好的时间(在给定的水平),当突然它会成倍地开始泄漏内存。
  • 当屏幕上有更多精灵时,游戏达到指数级泄漏的时间会缩短。
  • 即使没有任何东西被显示在屏幕上,游戏也会变慢。
  • 随着更频繁的精灵碰撞,游戏变慢。
  • 完全禁用冲突代码的确会减缓降级,但不会阻止游戏最终丢弃帧。在源

寻找和使用Flex分析器,我的首要嫌疑人,

  • 还有许多游荡的对象,尤其是WeakMethodClosure,占用了大量的内存。
  • 该软件对弱事件监听器进行了非常广泛的使用(每帧调度数十次)。
  • 每次创建新的精灵时都会复制BitmapData。这些是50x50像素精灵,每秒产生大约8个精灵。

我知道几乎不可能在没有看到源代码的情况下告诉我问题,所以我只是在寻找可能帮助我缩小范围的小花絮。有没有人在他们自己的项目中体验到这种回避性能下降?你的情况是什么原因?

回答

7

我最近完成了一个大型项目的优化。 ,我可以给你一些建筑建议:

  1. 主要原则 - 尽量做到尽可能少的函数/事件调用
  2. 摆脱掉所有,但一个 的onEnterFrame/onInterval /计时器触发周期。尽你所能 需要一个一般事件调用。 您可能需要很多静态数组来存储处理的对象 引用。
  3. 做图形/还可能导致东西在一个主循环,而不是
  4. 尝试使用大(可能是分段的)帆布小精灵/位图。 通常它可用于背景。但也工作好一个更小的物体 (如树,平台等)
  5. 破除小位图资源,它组装到一个砖片,并直接从中得出你的东西 ,通过源rect属性

我希望它能帮助你!内存泄漏 - 这种头痛。

P.S.在不同的浏览器中测试你的游戏,IE浏览器 - 大部分都是漏掉的,有时在刷新后不会清除内存。

+0

我认为这对于刚开始一个大型游戏项目并想知道如何最好地构建它的人来说是一个很好的建议。 – Kai 2009-09-22 16:13:14

0

听起来像你需要分析你的应用程序,看看发生了什么。

该主题提出了一些建议,但最终只需要输入代码来帮助确定发生了什么。

Profiling ActionScript-3 Code

你可能想看看你是否可以运行一段时间一些较小的部分,看看如果你看到一个放缓。

您可能希望单元测试您的应用程序,以便您可以快速运行各个部分,查找内存泄漏。 一个框架是:http://asunit.org/,另一种是:http://opensource.adobe.com/wiki/display/flexunit/

单元测试是我使用的分析很大,这样你就可以在你的游戏的顶级测试,运行数千次,寻找问题,然后运行每个部件并查看哪些部件有问题,然后按照自己的方式进行。这是一个手动过程,但如果开始列出的SO线程中的两个想法不起作用,这可能是您最好的方法。

您使用的内存太多吗?或者你的CPU使用率太高?

+0

这个问题提到内存泄漏,所以我猜cpu使用率不是问题。 – 2009-09-21 22:00:51

+0

我想知道除了猜测之外是否还有其他问题。不幸的是,当我猜测我的程序出现问题时,我倾向于错误,这就是为什么我非常依赖分析。 – 2009-09-21 22:16:22

+0

我想知道如果过多的垃圾回收会导致程序退化,原因是生成的对象太多太快。 – 2009-09-21 22:18:07

0

首先确定您的存储器或处理器限制是否达到。听起来像后面的,似乎有很多对象在做些什么......可能这些额外的精灵没有被很好地释放。在这些事件中查找对象/变量/任何事物之间的依赖关系,确保删除精灵,注意EnterFrame的任何处理程序或循环事件。

3
  • 避免匿名方法 - 将它们改为类级方法。
  • 使用addEventListener中的弱引用和/或确保删除对象的所有侦听器,然后使用removeChild删除对象
  • 确保您removeChild所有的精灵,而不是让它们飞离屏幕。另外,如果可能的话,重复使用精灵而不是创建新的精灵。
1

如果您有大量的创建/破坏正在进行,您应该考虑对象池,特别是对于像bitmapdata这样的重物。

看到Object Pool class

+0

一旦我确定哪些资源导致瓶颈,这是一个好主意。 – Kai 2009-09-22 16:16:17

0

这听起来更有可能的是,你是在比内存处理器速度达到上限。你必须额外努力去限制Flash应用程序的内存。

幸运的是有很多简单的事情可以做,以保持CPU下来...

1)严格管理事件侦听一切,尤其是鼠标的听众。你的所有精灵对象都有$ texas事件监听器吗?这可能是一个问题。

2)使用int或uint而不是Number访问数组。这是巨大的,这是Adobe的诡计之一。使用int和uint访问数组对象比使用Number更快,如果你进行了大量的迭代(听起来就像你这样做),这可能会减少帧执行时间的宝贵毫秒数。

3)与#2一样,监视您的数学运算以及您在某些操作中使用的类型。在AS3的数学运算中可以做的最慢的事情是重复投射(将ints提供给返回Number的函数),或者执行基本操作,如在Number而不是int上进行加法和减法。

在Flash中使用wtfhuge程序的好处是,即使是较小的优化更改也会对性能产生重大影响。我曾经在AS3玩过一个光线追踪引擎,在那里我宣布了一个额外的变量,它将我的FPS从30杀死到23.

+0

我相信我的游戏至少在几个地方打破了这些规则。我希望它就这么简单! – Kai 2009-09-22 16:13:58

0
Flash有一个相当臭名昭着的问题(许多人认为它是一个错误),导致定时器的事件侦听器和ENTER_FRAME事件不会被垃圾收集,即使它们被弱引用。因此,尽管使用弱引用事件是一种很好的做法,但仍然应当在不再需要时删除所有事件侦听器。
+0

在快速搜索Event.ENTER_FRAME后,我找到了18场比赛,所以可以肯定的是这个问题也可以在这里。 – Kai 2009-09-22 16:15:25

相关问题