2011-10-03 40 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。