日期:2013-11-27  浏览次数:20779 次

原著 Marco Lapi, aw[特别感激好友杨鑫]

在这篇文章中,我们将讨论多种优化 Actionscript 代码的方法.
此外我们也针对一些典型的游戏代码进行了系列测试,来最大限制的发掘、提高Flash播放器的功用。

代码优化简介

在本文中,我们将向您展现一些通过技术手段得到了优化的flash小游戏。代码优化之所以重要是由于它能帮您节约flash播放器的资源,还能让您的游戏在不同的硬件环境下运转得愈加稳定。本文次要讨论基于flashplayer6.0的一些问题,以及如何通过可行的技术手段去处理它们!

随着flashplayer7.0的发布,一些技术问题曾经得到处理了,而且功用大体地有所提高,然而在写本文之时,flashplayer6.0仍然有着广泛的使用。所以我们还是次要集中在6.0这个版本上。-aw猜测:国外买盗版的很少,所以很多人可能都来不及使用7.0,尤其是那些非职业的flash设计者。

何时进行优化

对现有程序进行优化的过程,有时十分的冗长与困难,这与原始代码的非优化程度有关,所以在投入大量时间进行代码优化之前,最重要的是要估量出要在什么地方对代码做出修正或替换。

一个游戏代码的最重要的部分就是主循环体,通常情况下该循环体要在flash的每一帧上执行,并控制游戏中的角色属性和重要的数据参数。而对于主循环体以外的部分,也可能是次要循环部分,同样要留意是给其否分配了过多的资源,而没有分配给那些更需求资源的核心部分。

通过积累在各处节约出来的时间(可能每处仅仅是几个毫秒),您会明显发现本人的swf运转得愈加稳定,并且游戏感也大大加强。

简约与高效的代码

书写出十分简约、可以再次调用的代码(有时可能是面向对象的)是一项精细的任务,但这需求多年的编程经验。对于OOP(object oriented programming, 面向对象的程序设计),有些场合基本利用不到它的优势,这使得它显得十分奢侈。 在无限的资源条件下(可能是flash播放器的缘由),通过更先进的方法,像刚刚提到的OOP,就可能反而导致令人不满意的结果。

我们并不是说OOP对游戏编程不好,只是在某些场合它显得过于奢侈和多余。毕竟有时候“传统的方法”却能得到更好的结果。

大体而言,用OOP是比较好的,由于它让代码维护愈加简单。但在后文中,你会看到有时为了充分发挥flashplayer功用,而不采用OOP技术。例如:处理快速滚动或者计算十分复杂的数学问题。

基本的优化

一提及代码优化,我们马上会联想到执行速度的改进,而很少去考虑系统资源的分配。这是由于当今,即便是将被淘汰的计算机,都有足够的内存来运转我们大部分的flash游戏(128M的内存足以满足大多数情况的需求,况且,512M的内存是当今新电脑的基本配置)


变量

在各种重要的代码优化手段中,有这么一条:在定义局部变量的时候,一定要用关键字var来定义,由于在Flash播放器中,局部变量的运转速度更快,而且在他们的作用域外是不耗占系统资源的。

aw附:var变量仅仅在花括号对中才有“生命”,团体认为没有系统学过编程的人容易出错的一个地方:

awMC.onLoad = function(){  var aw = 1;}awMC.onEnterFrame = function(){ //不存在aw这个变量}

一段非优化代码:

function doSomething(){ mx = 100 my = 100 ar = new Array()  for (y=0; y < my; y++) {  for (x=0; x < mx; x++)  {   i = (y * mx) + x   arr[i] = i     } } return arr}

这段代码中,并未声明函数体内的那些变量(那些仅仅在函数内使用的变量)为局部变量,这使得这些变量被播放器调用的速度更慢,并且在函数执行完毕的时候仍然耗占系统资源。

下面列出的是经过改进的同样功用的代码:

function doSomething(){ var mx = 100 var my = 100 var ar = new Array()  for (var y=0; y < my; y++) {  for (var x=0; x < mx; x++)  {   var i = (y * mx) + x   arr[i] = i     } } return arr}

这样一来所有的变量均被定义为了局部变量,他们能够更快地被播放器调用。这一点在函数大量(10,000次)循环运转时显得尤为重要!当一个函数调用结束的时候,相应的局部变量都会被销毁,并且释放出他们占有的系统资源。

onEnterFrame 事件

onEnterFrame事件对于游戏开发者而言是非常有用的,它使得我们能够快速、反复地按照预设帧频(fps)运转一段程序。回想在Flash5的时代,这(onEnterFrame实时监控)是一种非常流行的技术,用这样的事件来控制机器游戏对手的逻辑,又或者我们可以在每一个子弹上设置这样的事件来监测子弹的碰撞。

实际上,我们并不推荐给过多的MoveClip添加这样的事件,由于这样做会导致“无头绪码(spaghetti code)”的出现,并且容易导致程序效率明显降低。

大多数情况下,用单独一个onEnterFrame事件就可以处理问题了:用这一个主循环来执行你所需求的操作。

另一个简单的办法是设置一个合适的帧频:要知道帧频越高,CPU资源就越紧张。

在帧频为25-35(fps)之间时,onEnterFrame足以很好地执行较复杂代码,哪怕你的计算机配置较低。因此,在没有特殊要求的场合,我们不推荐使用高于60(fps)的帧频。

矢量图与位图

在处理图形前,我们一定要做出正确的选择。Flash能对矢量图和位图进行完满的兼容,然而矢量图和位图在播放器中的表理想质却完全不同。

在用到矢量图的时候,我们要尽可能简化它们的外形,去除多余的端点。这样做将大大降低播放器用于呈现矢量图所要进行的计算量。另一个重要方面在于线条的运用,尽量减少和避免冗陈的线条结构,由于它们会直接影响到flash的播放效率。

当某个实例通明度小于100时,也会对播放速率形成影响,所以如果你发现本人的Flash播放速率过慢,就去挑出这些通明的实例来吧!

那么,如果真的需求呈现比较复杂的场景时,你就最好考虑使用位图实现。虽然Flash在对位图的渲染效率上并不是最优越的(比如和Flash的“兄长”Director比起来),但丰富的视觉内容呈现只能靠位图(与位图同复杂度的矢量图形渲染速率非常低)了,这也是很多基于区块的游戏中广泛采用像素图作为背景的缘由。顺便要提到的是,Flash虽然对GIF,JPG和PNG都有所支持,但是渲染速度上PNG还是占有绝对优势,所以我们建议flash中的位图都尽可能采用PNG格式。

影片剪辑(MovieClip)的可视性[下面将MovieClip简称为mc]

您可能会经常碰到这样一种情况:有大量不可见/屏幕外的mc等待出场(比如游戏中屏幕外的地图、人物等等)。
要知道,播放器仍然要耗费一定的资源来处理这些不可见/屏幕外的mc,哪怕他们