2011-10-03 38 views
1

我正在JSFL中編寫導出器,將Flash動畫導出爲可在自定義播放器中重播的格式。導出器基本上遍歷時間軸和每個關鍵幀的所有元素,並寫出元素的名稱,位置,旋轉,縮放和本地偏移量。這些被讀入自定義播放器,該播放器將數據饋送給精靈引擎以重新創建動畫的每個幀。JSFL:檢測元素翻轉的時間

我想要做的是檢測給定元素是否已翻轉(即在Flash中選擇元素(符號),然後修改 - >變換 - >翻轉水平),以便導出器可以包含這些信息也可以讓玩家的Sprite引擎翻轉紋理的UV以複製Flash中發生的事情。這對於(比方說)使用一個符號作爲一個角色的右手,並將其翻轉爲他們的左手是有用的,而不是必須創建一個全新的符號。

不幸的是我看不到任何找到這些信息的方法。我沒有提供的關於元素的信息似乎意味着發生了任何類型的翻轉。我如何檢測翻轉?如果無法通過算法實現,那麼我會向動畫師說明一個符號已被翻轉(通過創建某種插件來給它們一個用SetPersistentData將值寫入Element的插件) ),例如),但我不知道如何製作這種插件。幫幫我!

+0

如果它在JSFL API中不可用,另一種方法是直接從FLA中提取元素設置。首先,確保您的FLA以Flash CS5(11.0)格式保存,將文件擴展名從.fla重命名爲.zip,提取XML,然後在XML中查找元素以查看您需要的信息是否存在。 – milkplus

回答

3

scaleX不起作用,它似乎總是給一個正面的價值。最後,我必須對矩陣做這件事才能得出答案。這是基於這樣一個想法,即我們知道矩陣總是包含2D旋轉,並且我們知道角度,所以我們可以擺脫矩陣元素的旋轉,讓我們留下比例。這很可怕,但它似乎工作。

此外,旋轉有時以NaN形式出現,特別是當元素翻轉時。使用skewX的值似乎適用於你知道沒有偏斜的事情,但我希望我的出口商能夠處理傾斜的元素,所以我認爲這可能是此處另一個問題的基礎。

var rotationRadians; 
if(isNaN(someElement.rotation)) { 
    rotationRadians = someElement.skewX * Math.PI/180; 
} 
else { 
    rotationRadians = someElement.rotation * Math.PI/180; 
} 

var sinRot = Math.sin(rotationRadians); 
var cosRot = Math.cos(rotationRadians); 
var SOME_EPSILON = 0.01; 
var flipScaleX, flipScaleY; 

if(Math.abs(cosRot) < SOME_EPSILON) { 
    // Avoid divide by zero. We can use sine and the other two elements of the matrix instead. 
    flipScaleX = (someElement.matrix.b/sinRot); 
    flipScaleY = (someElement.matrix.c/-sinRot); 
} 
else { 
    flipScaleX = someElement.matrix.a/cosRot; 
    flipScaleY = someElement.matrix.d/cosRot; 
} 

flipScaleX出來的〜-1,如果它的水平翻轉,1〜如果不是。 flipScaleY如果垂直翻轉則爲-1,否則爲1。

+0

這很有幫助。當旋轉是NaN時,我不會想到檢查偏斜!不禁想着一定有更好的辦法。 – Aranda

0

這裏的electrodruid的溶液包裝在幾個方便的功能:

function isFlippedHorizontally (element) { 
    return Math.round(getFlip(element)[0]) == -1; 
} 

function isFlippedVertically (element) { 
    return Math.round(getFlip(element)[0]) == -1; 
} 

function getFlip (element) { 
    var rotationRadians; 
    if(isNaN(element.rotation)) { 
    rotationRadians = element.skewX * Math.PI/180; 
    } 
    else { 
    rotationRadians = element.rotation * Math.PI/180; 
    } 

    var sinRot = Math.sin(rotationRadians); 
    var cosRot = Math.cos(rotationRadians); 
    var SOME_EPSILON = 0.01; 
    var flipScaleX, flipScaleY; 

    if(Math.abs(cosRot) < SOME_EPSILON) { 
    // Avoid divide by zero. We can use sine and the other two elements of the matrix instead. 
    flipScaleX = (element.matrix.b/sinRot); 
    flipScaleY = (element.matrix.c/-sinRot); 
    } 
    else { 
    flipScaleX = element.matrix.a/cosRot; 
    flipScaleY = element.matrix.d/cosRot; 
    } 
    return [flipScaleX, flipScaleY]; 
} 

使用例:

var element = currentDoc.getTimeline().layers[0].frames[0].elements[0]; 
trace("Element is flipped:" + isFlippedHorizontally(element)); 

感謝您的代碼electrodruid。