この記事のURL

http://www.dango-itimi.com/blog/archives/2014/001223.html


FLASH FLASH tips 特定の条件で OpenFL swf assets 内 DisplayObject プロパティ値がおかしくなる不具合への対処

現在 OpenFL では 以下の(a)~(c)の条件がそろった時、DisplayObject の rotation, scaleX, scaleY 各値に異常が発生します。

(a) DisplayObject の scaleX or scaleY 値に特定の値を設定する
(b) (a)の DisplayObject に対し更に DisplayObject.transform.matrix にて変形を行う
(c) neko or cpp ターゲット出力を行う

以下の環境で不具合が発生する事を確認しています。

actuate: [1.7.5]
hxcpp: [3.1.39]
lime-tools: [1.5.7]
lime: [1.0.1]
openfl: [2.0.1]
swf: [1.5.2]

この問題に対する対処策としまして、OpenFL github に以下の方法(setMatrix メソッド)が挙げられています。

https://github.com/openfl/openfl/issues/341

以下引用

public function setMatrix(mtx:Matrix) {

    var sx = Math.sqrt(mtx.a * mtx.a + mtx.b * mtx.b);
    var sy = Math.sqrt(mtx.c * mtx.c + mtx.d * mtx.d);
    var r = Math.atan2(mtx.b, mtx.a) * 57.2957795130823;
    var signX = (mtx.a < 0 ? -1 : 1);
    var signY = (mtx.d < 0 ? -1 : 1);

    // use determinant to deal with improper rotations
    var det = mtx.a * mtx.d - mtx.b * mtx.c;
    if (det < 0) {
        if (signX < 0 || signY < 0) {
            sy *= -1;
        } 
    }

    this.x = mtx.tx;
    this.y = mtx.ty;
    this.scaleX = sx;
    this.scaleY = sy;
    this.rotation = r;
}

this は DisplayObject インスタンスを示します。この setMatrix メソッドを利用する事で、DisplayObject.transform.matrix プロパティに matrix 値を適用するのと同様の変形を行うことが可能になります。

OpenFL swf ライブラリへの対処

OpenFL swf ライブラリ内には DisplayObject.transform.matrix を利用して変形を行っている箇所があります。私が確認したのは三箇所で、その内の一箇所が原因で swf assets から取得した MovieClip.rotation 値がおかしい、という状況に遭遇しました。

修正対象ソースコードは format.swf.instance.MovieClip クラスとなります。私の Windows の環境では 以下に修正対象のソースコードが配置されています。

C:\HaxeToolkit\haxe\lib\swf\1,5,2\format\swf\instance\MovieClip.hx

修正手順は以下となります。

(1)setMatrix メソッドを追加

format.swf.instance.MovieClip 内に以下の setMatrix メソッドを追加します。

public function setMatrix(displayObject:DisplayObject, mtx:Matrix) {

	var sx = Math.sqrt(mtx.a * mtx.a + mtx.b * mtx.b);
	var sy = Math.sqrt(mtx.c * mtx.c + mtx.d * mtx.d);
	var r = Math.atan2(mtx.b, mtx.a) * 57.2957795130823;
	var signX = (mtx.a < 0 ? -1 : 1);
	var signY = (mtx.d < 0 ? -1 : 1);

	// use determinant to deal with improper rotations
	var det = mtx.a * mtx.d - mtx.b * mtx.c;
	if (det < 0) {
		if (signX < 0 || signY < 0) {
			sy *= -1;
		}
	}

	displayObject.x = mtx.tx;
	displayObject.y = mtx.ty;
	displayObject.scaleX = sx;
	displayObject.scaleY = sy;
	displayObject.rotation = r;
}
(2)DisplayObject.transform.matrix 利用箇所を修正

transform.matrix でソースコード内を検索すると DisplayObject.transform.matrix に対し matrix 値を適用している箇所が三箇所見つかるので、コメントアウトして setMatrix メソッドを利用するように変更します。

//displayObject.transform.matrix = matrix;
setMatrix(displayObject, matrix);
//mc.transform.matrix = mt;
setMatrix(mc, mt);

以上で修正は完了です。

[ FLASH ] [ FLASH ] [ tips ] 投稿者 siratama : 2014年10月13日 09:46

トラックバック

http://www.dango-itimi.com/blog/mt-tb.cgi/1183

コメント

以下コメントを書き込むだけでは、管理人には通知が行われません。通知を行いたい場合、管理人の書き込みに「返信」を押してコメントをしていただくか、あるいは Google+, Twitter へご連絡ください。




[EDIT]