2011-03-02 12 views
3

我們的客戶已經責成我們(好吧,我一個人......)動態地生成具有不同尺寸框的網格。網格不應該已定義的邊緣,但每個movieclip應具有一定的邊界。我對AS3還很陌生,但除了這種巨大的數學問題之外,幾乎可以處理任何事情。我有100個不同大小的電影剪輯隨機制作一個網格,我將如何優化?

這裏有一個簡單的佈局我正在尋找一個規模要小得多:http://i.stack.imgur.com/Pnikm.png

有任何你們能夠有效地做到這一點?

我幾乎可以模仿這個,但有時候我的盒子會重疊,這是一個瑕疵。如果我開始測試它,直到我用55個以上的動畫片段嘗試它,然後我擔心劇本可能會凍結。

這裏的代碼有效,但有時可能會凍結。我怎樣才能優化這個,使堆棧溢出錯誤不會發生?

package 
{ 

import flash.display.MovieClip; 
import flash.display.Sprite; 
import flash.utils.getDefinitionByName; 


public class box_builder extends MovieClip 
{ 

    private var _path:MovieClip; 
    private var mc_holder:Sprite; 
    private var box_ar:Array; 
    private var box_spacing:int = 5; 
    private var mc_ar:Array = new Array(); 
    private var placed_box_ar:Array = new Array(); 
    private var p_step:int = 0; 

    public function box_builder() 
    { 
     _path = this; 
     mc_holder = new Sprite(); 
     _path.addChild(mc_holder); 
     getBoxArray(); 
     startBoxDistribution(); 
    } 
    private function getBoxArray() 
    { 
     box_ar = new Array("box_1","box_2","box_3","box_4","box_3","box_3","box_1","box_2","box_4","box_1","box_1","box_2","box_3","box_4","box_3","box_3","box_1","box_2","box_4","box_1","box_1","box_2","box_3","box_4","box_3","box_3","box_1","box_2","box_4","box_1", 
      "box_1","box_2","box_3","box_4","box_3","box_3","box_1","box_2","box_4","box_1","box_1","box_2","box_3","box_4","box_3","box_3","box_1","box_2","box_4","box_1","box_1","box_2","box_3","box_4","box_3","box_3","box_1","box_2","box_4","box_1"); 
    } 
    private function startBoxDistribution():void 
    { 
     var i = 0; 
     var len = box_ar.length; 
     createBoxes(); 
    } 
    private function createBoxes():void 
    { 
     var len = box_ar.length; 
     for (var i=0; i<len; i++) 
     { 
      var tMC:Class = getDefinitionByName(box_ar[i]) as Class; 
      var newMc:MovieClip = new tMC() as MovieClip; 
      mc_ar.push(newMc); 
      mc_holder.addChild(newMc); 
     } 
     executeQueue(); 
    } 

    private function executeQueue():void 
    { 
     if (p_step < box_ar.length) 
     { 
      var mc = mc_ar[p_step]; 

      p_step++; 
      try{ findPlacement(mc); } 
      catch(e:Error){ trace("ERROR!",e) }; 
     } 
     else centerAll(); 
    } 
    private function findPlacement(mc:MovieClip,prev_seed:int = 0):void 
    { 
     var mc_len:int = mc_ar.length; 
     var rN:int = randomNumber(0,mc_len - 2); 
     if (prev_seed == 0) 
     { 
      rN = rN; 
     } 
     else if (prev_seed == mc_len-1) 
     { 
      rN = 0; 
     } 
     else 
     { 
      rN = prev_seed + 1; 
     } 
     trace(rN,mc); 
     var seed = mc_ar[rN]; 
     var d = randomNumber(1,8); 

     if (d == 1) 
     { 
      mc.x = seed.x - seed.width - box_spacing; 
      mc.y = seed.y - seed.height - box_spacing; 
     } 
     else if (d==2) 
     { 
      mc.x = seed.x + seed.width/2 - mc.width/2; 
      mc.y = seed.y - seed.height - box_spacing; 
     } 
     else if (d==3) 
     { 
      mc.x = seed.x + seed.width + box_spacing; 
      mc.y = seed.y - seed.height - box_spacing; 
     } 
     else if (d==4) 
     { 
      mc.x = seed.x + seed.width + box_spacing; 
      mc.y = seed.y + seed.height/2 - mc.width/2; 
     } 
     else if (d==5) 
     { 
      mc.x = seed.x + seed.width + box_spacing; 
      mc.y = seed.y + seed.height + box_spacing; 
     } 
     else if (d==6) 
     { 
      mc.x = seed.x + seed.width/2 - mc.width/2; 
      mc.y = seed.y + seed.height + box_spacing; 
     } 
     else if (d==7) 
     { 
      mc.x = seed.x - mc.width - box_spacing; 
      mc.y = seed.y - mc.height - box_spacing; 
     } 
     else if (d==8) 
     { 
      mc.x = seed.x - mc.width - box_spacing; 
      mc.y = seed.y + seed.height/2 - mc.width/2; 
     } 


     var isGood:int = 0; 
     for (var c=0; c<placed_box_ar.length; c++) 
     { 
      if (mc.hitTestObject(placed_box_ar[c]) && mc != placed_box_ar[c]) 
      { 
       trace("overlap, retrying"); 
       findPlacement(mc,rN);//Retry placing this box. 
      } 
      else 
      { 
       isGood++; 
      } 
     } 
     if (isGood == placed_box_ar.length) 
     { 
      placed_box_ar.push(mc); 
      executeQueue();//Moves to next box to be placed. 
     } 
    } 

    private function centerAll():void 
    { 
     _path.addChild(mc_holder); 
     mc_holder.x = _path.stage.stageWidth/2; 
     mc_holder.y = _path.stage.stageHeight/2; 
    } 
    private function randomNumber(low:Number=0, high:Number=1):Number 
    { 
     return Math.floor(Math.random() * (1+high-low)) + low; 
    } 
} 

}

回答

1

這個答案可能是有點與衆不同,但我會離開這裏也無妨,誰可能碰巧來的其他人着想。

毫無疑問,有很多方法可以動態生成並隨機安排一組邊界框(查找bin包裝算法),但可能會有一種令人難以置信的低技術方法來達到同樣的效果,假設其意圖是模擬UI中的隨機性或動態性。

只需創建20個左右的預製佈置並隨機挑選其中一個。除非接口絕對依賴於隨機化或隨機化的說明,否則傳入的數據確實是不可預知的,最終用戶的感知結果應該與在運行時實際以編程方式創建佈局沒有區別。

0

首先:我同意alemay的回答。

如果你不能去一組佈局或只是不想,你應該看看Force-based algorithms。說實話,你需要一些數學,但結果往往是令人驚訝的好!

您可以確定最大或最重要的Sprite作爲主節點,它是居中和固定的。現在連接其他每個Sprite與一個彈簧它(這是數學)。經過幾次迭代(精靈被拖拽到它們的主節點上),它看起來與草圖相似。

您還可以通過將元素與另一個彈簧連接來對元素進行分組。

相關問題