2013-05-27 23 views
4

有沒有辦法在不同的框架上得到一個MovieClip(它有一個名字)的寬度?我試圖用.WIDTH.getBounds(空).WIDTH,但是,他們都可以給我只將當前幀的寬度。我試圖做gotoAndStop(frameiwant),但信息似乎是不正確的,直到至少下一幀如何立即獲取不同幀的MovieClip寬度?

我想立即獲得幀的寬度,所以我不必等到下一幀的寬度。

回答

0

你要聽一個特定的事件,然後才能索要信息。

clip.addEventListener(Event.FRAME_CONSTRUCTED, frameReadyHandler); 
clip.gotoAndStop(frame); 

function frameReadyHandler(event:Event):void 
{ 
    clip.removeEventListener(Event.FRAME_CONSTRUCTED, frameReadyHandler); 
    var width = clip.width; 
} 

Frame構造事件是第一個被調度的事件。它在幀腳本執行之前得到調度。您也可以等待輸入框架事件。

+0

將提供寬度或信息(略)後點的即時信息?我需要立即獲得這些信息。 – chadb

+0

nope。半幀後你會得到答案。這取決於您在設置事件偵聽器之後需要執行多少代碼以及創建幀需要多長時間。 – Larusso

+2

我不認爲這是可能的。 gotoAndStop和gotoAndPlay不會立即改變框架。他們爲下一個幀渲染週期設置了一個標誌。如果您可以在正在運行的腳本下切換框架,那將是致命的。您必須預先測量您的動畫片段並將數據保存在數組中,或者使用我描述的方法。 – Larusso

0

,如果你已經存儲在previousWidth是不同您可以添加的事件偵聽器1毫秒和測試。如果是,那麼你去。如果不是,它可能會聽同一幀。

A 1毫秒定時器是沒有這樣一個大問題,停止它,如果你不需要它,恢復它如果你這樣做,否則,保持持續運行。當它改變時,派遣一個事件或任何需要發生的事情。

+0

與我的解決方案相比,此解決方案更像是一種破解。計時器和事件處理器都是異步的。我更喜歡事件解決方案,因爲在這裏我確信一切都已經完成! – Larusso

+0

我想要這些賞金點:) – Discipol

+0

保持1ms定時器不斷運行? –

4

我能想到這樣做的唯一辦法是有一個初步的階段,你的項目,該項目將:通過都在你的時間軸中的幀的

  1. 運行。創建一個對象,該對象將保存關於該框架中的子項的信息。它可以被稱爲Frame
  2. 迭代添加到該框架中的舞臺上的所有子項並添加描述該子項的定義對象。描述可以是基本的,也可以是你需要的。我們可以稱這個類爲ObjectDefintion

這個過程的缺點是您需要等待@Larusso這樣的FRAME_CONSTRUCTED事件在他的答案中指出。這意味着,在您能夠獲取有關其子項的信息之前,該框架實際上必須完成渲染,這當然意味着您必須在此階段執行並渲染時間線中的每一幀。所有你真的可以做的減輕這個問題是設置frameRate到一個很高的水平,然後在你完成評估所有的幀後將其設置回來。

我已經設置和它工作得很好 - 我會粘貼每個類和嘗試解釋他們所做的事情。

因此,對於您的文檔類(或任何影片剪輯持有你想看看幀),我有這樣的:

public class Main extends MovieClip 
{ 

    private var _userFrameRate:int; 
    private var _frames:Vector.<Frame> = new <Frame>[]; 


    public function Main() 
    { 
     _userFrameRate = stage.frameRate; 
     stage.frameRate = 120; 

     addEventListener(Event.FRAME_CONSTRUCTED, _assess); 
    } 


    public function getFrame(index:int):Frame 
    { 
     return _frames[index - 1]; 
    } 


    private function _assess(e:Event):void 
    { 
     var frame:Frame = new Frame(this); 
     _frames.push(frame); 

     if(currentFrame === totalFrames) 
     { 
      removeEventListener(Event.FRAME_CONSTRUCTED, _assess); 
      gotoAndStop(1); 
      stage.frameRate = _userFrameRate; 

      ready(); 
     } 

     else play(); 
    } 


    public function ready():void 
    { 
     // Start here. 

     // There is a MovieClip on frame 10 with the instance name 'test'. 
     // We can get the width of it like this. 
     trace(getFrame(10).define("test").property("width")); 
    } 

} 

這基本上初始化中,我們將通過在影片剪輯每幀運行階段並評估其子女。 ready()方法用作代碼後評估的入口點。

接下來我們有Frame類,它用來保持約相關的框架兒童的信息:

public class Frame 
{ 

    private var _main:Main; 
    private var _content:Object = {}; 


    public function Frame(main:Main) 
    { 
     _main = main; 
     update(); 
    } 


    public function update():void 
    { 
     _content = {}; 
     for(var i:int = 0; i < _main.numChildren; i++) 
     { 
      var target:DisplayObject = _main.getChildAt(i); 

      // This will be explained below. 
      var definition:ObjectDefinition = new ObjectDefinition(target, "x", "y", "width", "height"); 

      _content[target.name] = definition; 
     } 
    } 


    public function define(name:String):ObjectDefinition 
    { 
     return _content[name]; 
    } 

} 

它是非常簡單的 - 你給Main的引用,以便它可以檢查是存在的孩子在每個框架內。

ObjectDefinition類也是非常簡單的,純粹充當數據要跟蹤對框架的每個孩子一個倉庫:

public class ObjectDefinition 
{ 

    private var _definition:Object = {}; 


    public function ObjectDefinition(target:DisplayObject, ...properties) 
    { 
     for each(var i:String in properties) 
     { 
      _definition[i] = target[i]; 
     } 
    } 


    public function property(property:String):* 
    { 
     return _definition[property]; 
    } 

} 

你會注意到,此構造函數接受的目標將被定義的DisplayObject以及任何你想要作爲字符串跟蹤的屬性數量(參見上面Frame中的實現)。

完成後,你可以鏈中的方法Main.getFrame()Frame.define()ObjectDefinition.property()獲得將在整個時間軸存在兒童性。例如,如果您有實例的MovieClip名字框架15 square和你想獲得它的寬度和高度,你可以在.ready()做到這一點,像這樣:

var square:ObjectDefinition = getFrame(15).define("square"); 
trace(square.property("width"), square.property("height")); 

當然這個過程是不理想 - 但不幸的是,這是我能看到你想要實現的唯一途徑。

0

如果你知道影片剪輯的最大尺寸,可以試試這個:

// Create movie clip 
var movie :MovieClip = new MovieClipWith3Frames(); 

// Move to second frame 
movie.gotoAndStop(2); 

// Create bitmap witch magenta background 
var bd :BitmapData = new BitmapData(200, 200, false, 0xFF00FF); 

// Draw second frame 
bd.draw(movie); 

// Found the bounds of shape 
var movieBounds:Rectangle = bd.getColorBoundsRect(0xFFFFFF, 0xFF00FF, false); 

trace(movieBounds); // (x=42, y=15, w=32, h=33) 
+0

如果第二幀上有一個對象需要初始化,或者通過腳本創建,則大小將會錯誤。這是主要問題。這也是爲什麼你不應該在gotoAndStop調用之後直接訪問新添加的顯示對象的原因。因爲它們可能沒有初始化。唯一可以確定的方法是等待幀構建事件。只要您的MovieClip中的所有內容都很簡單,您可以在gotoAndStop之後獲得正確的尺寸。 Textfields也存在同樣的錯誤。 – Larusso