国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Actionscript 優(yōu)化指南
在這篇文章中,我們將討論多種優(yōu)化 Actionscript 代碼的方法.
此外我們也針對(duì)一些典型的游戲代碼進(jìn)行了系列測(cè)試,來最大限度的發(fā)掘、提高Flash播放器的性能。

代碼優(yōu)化簡介

在本文中,我們將向您展示一些通過技術(shù)手段得到了優(yōu)化的flash小游戲。代碼優(yōu)化之所以重要是因?yàn)樗軒湍?jié)約flash播放器的資源,還能讓您的游戲在不同的硬件環(huán)境下運(yùn)行得更加穩(wěn)定。本文主要討論基于flashplayer6.0的一些問題,以及如何通過可行的技術(shù)手段去解決它們!

隨著flashplayer7.0的發(fā)布,一些技術(shù)問題已經(jīng)得到解決了,而且性能大體地有所提高,然而在寫本文之時(shí),flashplayer6.0仍然有著廣泛的應(yīng)用。所以我們還是主要集中在6.0這個(gè)版本上。-aw猜測(cè):國外買盜版的很少,所以很多人可能都來不及使用7.0,尤其是那些非職業(yè)的flash設(shè)計(jì)者。

何時(shí)進(jìn)行優(yōu)化

對(duì)現(xiàn)有程序進(jìn)行優(yōu)化的過程,有時(shí)十分的冗長與困難,這與原始代碼的非優(yōu)化程度有關(guān),所以在投入大量時(shí)間進(jìn)行代碼優(yōu)化之前,最重要的是要估計(jì)出要在什么地方對(duì)代碼做出修改或替換。

一個(gè)游戲代碼的最重要的部分就是主循環(huán)體,通常情況下該循環(huán)體要在flash的每一幀上執(zhí)行,并控制游戲中的角色屬性和重要的數(shù)據(jù)參數(shù)。而對(duì)于主循環(huán)體以外的部分,也可能是次要循環(huán)部分,同樣要注意是給其否分配了過多的資源,而沒有分配給那些更需要資源的核心部分。

通過積累在各處節(jié)約出來的時(shí)間(可能每處僅僅是幾個(gè)毫秒),您會(huì)明顯發(fā)現(xiàn)自己的swf運(yùn)行得更加穩(wěn)定,并且游戲感也大大加強(qiáng)。

簡潔與高效的代碼

書寫出十分簡潔、可以再次調(diào)用的代碼(有時(shí)可能是面向?qū)ο蟮?是一項(xiàng)精細(xì)的工作,但這需要多年的編程經(jīng)驗(yàn)。對(duì)于OOP(object oriented programming, 面向?qū)ο蟮某绦蛟O(shè)計(jì)),有些場(chǎng)合根本利用不到它的優(yōu)勢(shì),這使得它顯得十分奢侈。 在有限的資源條件下(可能是flash播放器的原因),通過更先進(jìn)的方法,像剛剛提到的OOP,就可能反而導(dǎo)致令人不滿意的結(jié)果。

我們并不是說OOP對(duì)游戲編程不好,只是在某些場(chǎng)合它顯得過于奢侈和多余。畢竟有時(shí)候“傳統(tǒng)的方法”卻能得到更好的結(jié)果。

大體而言,用OOP是比較好的,因?yàn)樗尨a維護(hù)更加簡單。但在后文中,你會(huì)看到有時(shí)為了充分發(fā)揮flashplayer性能,而不采用OOP技術(shù)。例如:處理快速滾動(dòng)或者計(jì)算十分復(fù)雜的數(shù)學(xué)問題。

基本的優(yōu)化一提及代碼優(yōu)化,我們馬上會(huì)聯(lián)想到執(zhí)行速度的改進(jìn),而很少去考慮系統(tǒng)資源的分配。這是因?yàn)楫?dāng)今,即使是將被淘汰的計(jì)算機(jī),都有足夠的內(nèi)存來運(yùn)行我們大部分的flash游戲(128M的內(nèi)存足以滿足大多數(shù)情況的需要,況且,512M的內(nèi)存是當(dāng)今新電腦的基本配置)

--------------------------------------------------------------------------------

變量

在各種重要的代碼優(yōu)化手段中,有這么一條:在定義局部變量的時(shí)候,一定要用關(guān)鍵字var來定義,因?yàn)樵贔lash播放器中,局部變量的運(yùn)行速度更快,而且在他們的作用域外是不耗占系統(tǒng)資源的。

aw附:var變量僅僅在花括號(hào)對(duì)中才有“生命”,個(gè)人認(rèn)為沒有系統(tǒng)學(xué)過編程的人容易出錯(cuò)的一個(gè)地方:

awMC.onLoad = function(){
var aw = 1;
}
awMC.onEnterFrame = function(){
//不存在aw這個(gè)變量
}
一段非優(yōu)化代碼:

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
}
這段代碼中,并未聲明函數(shù)體內(nèi)的那些變量(那些僅僅在函數(shù)內(nèi)使用的變量)為局部變量,這使得這些變量被播放器調(diào)用的速度更慢,并且在函數(shù)執(zhí)行完畢的時(shí)候仍然耗占系統(tǒng)資源。

下面列出的是經(jīng)過改進(jìn)的同樣功能的代碼:

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
}這樣一來所有的變量均被定義為了局部變量,他們能夠更快地被播放器調(diào)用。這一點(diǎn)在函數(shù)大量(10,000次)循環(huán)運(yùn)行時(shí)顯得尤為重要!當(dāng)一個(gè)函數(shù)調(diào)用結(jié)束的時(shí)候,相應(yīng)的局部變量都會(huì)被銷毀,并且釋放出他們占有的系統(tǒng)資源。

onEnterFrame 事件

onEnterFrame事件對(duì)于游戲開發(fā)者而言是非常有用的,它使得我們能夠快速、反復(fù)地按照預(yù)設(shè)幀頻(fps)運(yùn)行一段程序?;叵朐贔lash5的時(shí)代,這(onEnterFrame實(shí)時(shí)監(jiān)控)是一種非常流行的技術(shù),用這樣的事件來控制機(jī)器游戲?qū)κ值倪壿?,又或者我們可以在每一個(gè)子彈上設(shè)置這樣的事件來監(jiān)測(cè)子彈的碰撞。

實(shí)際上,我們并不推薦給過多的MoveClip添加這樣的事件,因?yàn)檫@樣做會(huì)導(dǎo)致“無頭緒碼(spaghetti code)”的出現(xiàn),并且容易導(dǎo)致程序效率明顯降低。

大多數(shù)情況下,用單獨(dú)一個(gè)onEnterFrame事件就可以解決問題了:用這一個(gè)主循環(huán)來執(zhí)行你所需要的操作。

另一個(gè)簡單的辦法是設(shè)置一個(gè)合適的幀頻:要知道幀頻越高,CPU資源就越緊張。

在幀頻為25-35(fps)之間時(shí),onEnterFrame足以很好地執(zhí)行較復(fù)雜代碼,哪怕你的計(jì)算機(jī)配置較低。因此,在沒有特殊要求的場(chǎng)合,我們不推薦使用高于60(fps)的幀頻。

矢量圖與位圖

在處理圖形前,我們一定要做出正確的選擇。Flash能對(duì)矢量圖和位圖進(jìn)行完美的兼容,然而矢量圖和位圖在播放器中的表現(xiàn)實(shí)質(zhì)卻完全不同。

在用到矢量圖的時(shí)候,我們要盡可能簡化它們的形狀,去除多余的端點(diǎn)。這樣做將大大降低播放器用于呈現(xiàn)矢量圖所要進(jìn)行的計(jì)算量。另一個(gè)重要方面在于線條的運(yùn)用,盡量減少和避免冗陳的線條結(jié)構(gòu),因?yàn)樗鼈儠?huì)直接影響到flash的播放效率。

當(dāng)某個(gè)實(shí)例透明度小于100時(shí),也會(huì)對(duì)播放速率造成影響,所以如果你發(fā)現(xiàn)自己的Flash播放速率過慢,就去挑出這些透明的實(shí)例來吧!

那么,如果真的需要呈現(xiàn)比較復(fù)雜的場(chǎng)景時(shí),你就最好考慮使用位圖實(shí)現(xiàn)。雖然Flash在對(duì)位圖的渲染效率上并不是最優(yōu)越的(比如和Flash的“兄長”Director比起來),但豐富的視覺內(nèi)容呈現(xiàn)只能靠位圖(與位圖同復(fù)雜度的矢量圖形渲染速率非常低)了,這也是很多基于區(qū)塊的游戲中廣泛采用像素圖作為背景的原因。順便要提到的是,F(xiàn)lash雖然對(duì)GIF,JPG和PNG都有所支持,但是渲染速度上PNG還是占有絕對(duì)優(yōu)勢(shì),所以我們建議flash中的位圖都盡可能采用PNG格式。

影片剪輯(MovieClip)的可視性[下面將MovieClip簡稱為mc]

您可能會(huì)經(jīng)常碰到這樣一種情況:有大量不可見/屏幕外的mc等待出場(chǎng)(比如游戲中屏幕外的地圖、人物等等)。
要知道,播放器仍然要消耗一定的資源來處理這些不可見/屏幕外的mc,哪怕他們是單幀,非播放的狀態(tài)。

最好的解決辦法之一是給這些mc一個(gè)空白幀,當(dāng)他們不出現(xiàn)在屏幕上時(shí),你能用gotoAndStop()語句跳轉(zhuǎn)到這一幀,從而減少播放器對(duì)資源的需求。

請(qǐng)務(wù)必記住,這種情況下,簡單的設(shè)置可見度屬性為不可見( _visible = false )是無效的,播放器將繼續(xù)按照這些mc所停留或播放的幀的復(fù)雜度來分配資源 。

數(shù)組

數(shù)組在各種需要記錄數(shù)據(jù)的應(yīng)用程序和游戲中都被廣泛的使用。

一個(gè)典型的例子就是基于區(qū)塊的Flash游戲,在這樣一類的游戲中,地圖有時(shí)被存放成形如arr[y][x]的二維數(shù)組。雖然這是一種很常見的方法,但是如果用一維數(shù)組的話,卻能提高程序的運(yùn)行效率。另一個(gè)重要的方法來提高數(shù)組效率是在數(shù)組遍歷的時(shí)候使用for in 循環(huán)來代替?zhèn)鹘y(tǒng)的 for 或者while循環(huán)語法。
例如:

一段代碼如下

for (var i in arr)
{
  if (arr[i] > 50)
  {
    // 進(jìn)行某些操作
  }
}
它的執(zhí)行速度明顯高于這一段代碼:

for (var i=0; i<10000; i++)
{
  if (arr[i] > 50)
  {
    // 進(jìn)行某些操作
  }
}
前者的效率比后者提高了30%,這個(gè)數(shù)字在你的游戲要逐幀執(zhí)行這一段代碼的時(shí)候顯得更加寶貴!

高級(jí)優(yōu)化:

這里我們對(duì)一些游戲中的常用代碼進(jìn)行了效率測(cè)試,并給出了結(jié)果。其中有一些思路借鑒了本文最后所提到的一些個(gè)人或者團(tuán)體。

我們?cè)趦蓚€(gè)不同型號(hào)的電腦上進(jìn)行了測(cè)試。

AthlonXP 2.6Ghz 臺(tái)式機(jī) 512M內(nèi)存,Windows2000Pro

P4 2.0Ghz 筆記本 ,WindowsXP家庭版

每一項(xiàng)測(cè)試都分為三組,取平均值得到最后結(jié)果。

測(cè)試的結(jié)果單位為“毫秒”,反映了代碼執(zhí)行時(shí)間。顯然,數(shù)值越小,反映代碼的性能越好。

所有的代碼均由MX2004編譯生成的Flash6.0版本。有趣的是,我們可以看到由MX和MX2004編譯的差距。

所有的測(cè)試細(xì)節(jié)可以看這個(gè)PDF文件(aw注:未翻譯,很簡單的PDF文檔,都能看懂的)

我把測(cè)試的結(jié)果如下歸納出來,同大家分享:

1) for循環(huán) 和 while循環(huán)

用while循環(huán)將會(huì)得到比for循環(huán)更好的效率。然而,從數(shù)組中讀取數(shù)據(jù),用for in循環(huán)式最好的選擇!

所以我們不推薦使用:

for (var i=0; i<1000; i++)
{
  //進(jìn)行某些操作
}而推薦使用

var i=-1
while (++i < 1000)
{
  //進(jìn)行某些操作
}2) 從數(shù)組中讀取數(shù)據(jù)

我們通過測(cè)試發(fā)現(xiàn),for in循環(huán)的效率大大高于其他的循環(huán)方式。參看:

arr = []
MAX = 5000
// Fill an array
for (i=0; i < MAX; i++)
{
  arr[i] = i
}
var item = null
// For Loop
for (var i=0; i < MAX; i++)
{
  item = arr[i]
}
// For In Loop
for (var i in arr)
{
  item = arr[i]
}
// While Loop
i = -1
while(++i < MAX)
{
  item = arr[i]
}
3) 向數(shù)組中寫入數(shù)據(jù)(while , for)

可以看到while循環(huán)稍占優(yōu)勢(shì)。

4) _global(全局)變量同Timeline(時(shí)間軸)變量

我們猜測(cè)采用全局變量能提高變量調(diào)用速度,然而效果并不像預(yù)計(jì)的那樣明顯。

5) 單行、多行變量賦值

我們發(fā)現(xiàn)單行變量賦值效率大大高于多行。比如:



a = 0
b = 0
c = 0
d = 100
e = 100的效率就不如:

a = b = c = 0
d = e = 100
6) 變量名尋址

這個(gè)測(cè)試反映了變量名的預(yù)尋址是非常重要的,尤其是在循環(huán)的時(shí)候,一定要先給丁一個(gè)指向。這樣大大節(jié)約了尋址時(shí)間。

比如:

var num = null
t = getTimer()
for (var i=0; i < MAX; i++)
{
  num = Math.floor(MAX) - Math.ceil(MAX)
}
t1.text = "Always lookup: " + (getTimer() - t)
就不如:

t = getTimer()
var floor = Math.floor
var ceil = Math.ceil
for (var i=0; i < MAX; i++)
{
  num = floor(MAX) - ceil(MAX)
}
7) 短變量名和長變量名

變量名越短,效率越高??紤]到長變量名也有它的好處(比如,便于維護(hù)等),因此建議在關(guān)鍵部位(比如大量循環(huán)出現(xiàn)的時(shí)候)使用短變量名,最好就1-2個(gè)字符。

8) 循環(huán)前、后聲明變量

在測(cè)試前,我們認(rèn)為循環(huán)前聲明變量會(huì)更加節(jié)約時(shí)間,不料測(cè)試結(jié)果并不明顯,甚至還恰恰相反!

// 內(nèi)部聲明
t = getTimer()
for (var i=0; i < MAX; i++)
{
  var test1 = i
}
t1.text = "Inside:" + (getTimer() - t)
// 外部聲明
t = getTimer()
var test2
for (var i=0; i < MAX; i++)
{
  test2 = i
}9) 使用嵌套的if結(jié)構(gòu)

當(dāng)用到復(fù)雜的條件表達(dá)式時(shí)。把他們打散成為嵌套的獨(dú)立判斷結(jié)構(gòu)是最佳方案。下面的代碼我們進(jìn)行了測(cè)試,發(fā)現(xiàn)這種效果改進(jìn)明顯!

MAX = 20000
a = 1
b = 2
c = -3
d = 4
var i=MAX
while(--i > -1)
{
  if (a == 1 && b == 2 && c == 3 && d == 4)
  {
    var k = d * c * b * a
  }
}
//下面的判斷更加節(jié)省時(shí)間
var i=MAX
while(--i > -1)
{
  if (a == 1)
  {
    if (b == 2)
    {
      if (c == 3)
      {
        if (d == 4)
        {
          var k = d * c * b * a
        }
      }
    }
  }
}11) TellTarget語法同“點(diǎn)”語法比較

如果你從Flash5.0開始接觸Flash代碼,那么你一定會(huì)記得那時(shí),我們用“tellTarget”來控制MC。

這里測(cè)試表明,用tellTarget比點(diǎn)語法效率更高。所以必要的時(shí)候,可以考慮采用這種官方公開否認(rèn)的語法(aw注:個(gè)人覺得有點(diǎn)恍惚,不明白為什么會(huì)這樣。不過既然測(cè)試結(jié)果如此,那么也有可行性了……)

MAX = 10000
mc = _root.createEmptyMovieClip("test", 1000)
function test_dot()
{
  var i=MAX
  while(--i > -1)
  {
    mc._x = 10
    mc._y = 10
  }
}
function test_tellTarget()
{
  var i=MAX
  while(--i > -1)
  {
    tellTarget(mc)
    {
      _x = 10
      _y = 10
    }
  }
}
12) 尋找局部變量(this方法同with方法比較)

局部變量的定位方法很多。我們發(fā)現(xiàn)用with比用this更加有優(yōu)勢(shì)!

obj = {}
obj.a = 1
obj.b = 2
obj.c = 3
obj.d = 4
obj.e = 5
obj.f = 6
obj.g = 7
obj.h = 8
obj.test1 = useThis
obj.test2 = useWith
MAX = 10000
function useThis()
{
  var i = MAX
  while(--i > -1)
  {
    this.a = 1
    this.b = 2
    this.c = 3
    this.d = 4
    this.e = 5
    this.f = 6
    this.g = 7
    this.h = 8
  }
}
function useWith()
{
  var i = MAX
  while(--i > -1)
  {
    with(this)
    {
      a = 1
      b = 2
      c = 3
      d = 4
      e = 5
      f = 6
      g = 7
      h = 8
    }
  }
}
13) 循環(huán)監(jiān)聽鍵盤事件

同剛才所提到的尋址一樣,我們實(shí)現(xiàn)給一個(gè)指向會(huì)得到更好的效率,比如:

keyDown = Key.isDown
keyLeft = Key.LEFT
//我們?cè)儆?if (keyDown(keyLeft))
附:我們測(cè)試了按鍵代碼和鍵值常量的效率發(fā)現(xiàn)并無太大差別。

14) Math.floor()方法與int()

這個(gè)問題曾在Flashkit的論壇被提出討論過。測(cè)試表明,舊的int方法反而效率更高。我們的測(cè)試結(jié)果也反映了這一點(diǎn)。

15) eval表達(dá)式與中括號(hào)語法

我們并沒有發(fā)現(xiàn)明顯的差別,并不像剛才所述那樣,舊的eval表達(dá)式比起中括號(hào)方法并沒有太大的優(yōu)勢(shì)

var mc = eval("_root.myMc" + i)
var mc = _root["myMc" + i]
//兩者效率差不多16) 涉及MC的循環(huán):ASBroadcaster 同歡同循環(huán)的差別

測(cè)試反映,用未公開的ASBroadcaster 方法能大大提高對(duì)MC的循環(huán)操作的效率。我們的測(cè)試中,建立了500個(gè)MC,然后測(cè)試把它們清楚所花費(fèi)的時(shí)間。

傳統(tǒng)的循環(huán)式:

MAX = 500
SX = 550
SY = 330
MovieClip.prototype.onCustomEvent = function()
{
  this.removeMovieClip()
}
function init()
{
  var i=MAX
  var rnd = Math.random
  while(--i > -1)
  {
    var m = _root.attachMovie("enemy","e"+i,i)
    m._x = rnd() * SX
    m._y = rnd() * SY
  }
}
init()
function bench()
{
  var t = getTimer()
  var i=MAX
  while(--i > -1)
  {
    _root["e"+i].onCustomEvent()
  }
  res.text = "time: " + (getTimer() - t)
}
同樣的效果,用事件廣播(ASBroadcaster)

MAX = 500
evtManager = {}
ASBroadcaster.initialize(evtManager)
SX = 550
SY = 330
MovieClip.prototype.onCustomEvent = function()
{
  this.removeMovieClip()
}
function init()
{
  var i=MAX
  var rnd = Math.random
  while(--i > -1)
  {
    var m = _root.attachMovie("enemy","e"+i,i)
    m._x = rnd() * SX
    m._y = rnd() * SY
    evtManager.addListener(m)
  }
}
init()
function bench()
{
  var t = getTimer()
  evtManager.broadcastMessage("onCustomEvent")
  res.text = "time: " + (getTimer() - t)
}
用MX04為6.0播放器編譯、生成文件:

在MX04種,一件有趣的事是,腳本編譯器的性能在各方面提高不少。新的編譯器在局部、全局變量尋址效率方面有極大的提高,您還可以通過PDF文件發(fā)現(xiàn)很多有趣的結(jié)果:全局變量尋址比時(shí)間軸變量更快了,而嵌套循環(huán)也有所改進(jìn)。幾乎每一個(gè)用MX04編譯的代碼效率都高于MX版本。

awflasher.com附:為什么要為6.0編譯呢,國外還有相當(dāng)一部分用戶在使用MX6.0。雖然7.0Player是免費(fèi)的,但是在國外升級(jí)軟件似乎不像國內(nèi)這么火,什么東西馬上升到最高。我個(gè)人的一些猜測(cè)而已

結(jié)論:

我們從這些測(cè)試結(jié)果中發(fā)現(xiàn),對(duì)于不同的需求,采用不同的代碼,我們可以大大提高腳本的執(zhí)行效率。雖然我們?cè)谶@里羅列了許多的優(yōu)化代碼的方法,需要大家自己測(cè)試、實(shí)驗(yàn)的還有很多(考慮到每個(gè)人的需求不同).如果你想更加深入地討論這類問題。可以來我們的論壇。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
JavaScript中的所有循環(huán)類型
Javascript[0x06] -- 基于Javascript范疇代碼風(fēng)格和規(guī)范的總結(jié)
一段非常簡單的讓圖片自動(dòng)切換js代碼
javascript語言精粹 筆記
遍歷數(shù)組,對(duì)象和JSON
Flex通用克?。╟lone)方法
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服