Posted by yamada on 2009/09/12 – 19:03
Filed under AS3, Flash
Tagged as AS3, Flash, tween, Tweener
今回のエントリは、Tweenerで自前パラメータをTweenさせる方法のメモです。
tween対象のAnimTextを定義
たとえばAnimTextというTextFieldを継承したクラスを考えてみます。
このクラスはX座標を設定すると同時にその値を自分の文字に置き換えるmyParamというパラメータを持っています。
このクラスのインスタンスのmyParamをtweenさせてみたい、というようなことをやってみます。
AnimTextは以下のように定義しておきます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| package {
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
public class AnimText extends TextField {
private var _myParam:Number = 0;
public function AnimText()
{
this.text = "DEFAULT";
this.autoSize = TextFieldAutoSize.LEFT;
}
public function get myParam():Number {
return _myParam;
}
public function set myParam(value:Number):void {
_myParam = value;
this.text = "PARAM[" + _myParam + "]";
this.x = _myParam;
}
}
} |
普通のやり方だけではNG
AnimTextのインスタンスを_animTextと定義します。
この_animTextのmyParamを1秒で300までtweenさせたい、と言う場合、以下のようなコードを書きたくなります。
1
2
| var _animText:AnimText = new AnimText();
Tweener.addTween( _animText, { myParam:300, time:1 } ); |
しかし、これだけでは実行できません。
Tweenerが、myParamというパラメータを理解できないからです。
Tweenerでは、自前のパラメータに対してtweenさせたい場合、tween時に呼び出す関数を用意する必要があるのです。
スペシャルプロパティの登録
自前プロパティをTweenerで使用可能なパラメータに設定する際に必要なのは次の3つの値です。
- Tweenerから呼び出すときのパラメータ名
- そのパラメータ名で値を返す関数 .. setter
- そのパラメータ名に値を設定したときに呼び出す関数 .. getter
これをTweener.registerSpecialPropertyというメソッドに渡します。
上記の例で言えば、以下のようなコードになります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| // 登録コード.
// Tweener.addTween するまえに1度だけ呼び出して設定.
Tweener.registerSpecialProperty(
"myParam",
get_myParam,
set_myParam
);
// 以下はsetter/getter関数.
public function get_myParam(
p_obj:AnimText,
param:Array,
extra:Object = null ) :Number
{
return p_obj.myParam;
}
public function set_myParam(
p_obj:AnimText,
value:Number,
param:Array,
extra:Object=null ) :void
{
p_obj.myParam = value;
} |
これで最初に書いたコードが使えるようになります。
公式ドキュメントの不備?
なんと、公式ドキュメントっぽい以下のリンク先にあるサンプルコードでは実行時エラーになるので注意が必要です。
set, getに使う関数の引数が間違っているのです。
今はsetter/getterそれぞれの引数の最後に、params:Array, extra:Object=null という2つを付け加えておく必要があります。
ちなみにこれらの引数については、Aquiouxさんのページのサンプルコードで知りました。
サンプルコード:yoyo text
最後に、上記AnimTextをアニメーションさせるサンプルコードを載せておきます。
Read More »
Posted by yamada on 2009/09/09 – 18:06
Filed under AS3, Flash
Tagged as AS3, Flash, tween, Tweener
Tweenerなどで色を変えたものをBitmapData.drawで描画しても、色変更が適用されない、という現象に悩んだので、ちょっと仕組みを調べてみました。
(2009/09/10夜:dskさんにコメントをいただき完全解決しましたので、その情報も下部に追記しました)
問題発生
「Tweenerで色を変更してもそれをBitmapDataにdrawしたら変更前の状態が描画される」という問題ですが、いろいろ調べていたら、どうやら「Tweenerなどで色を変える方法はtransform.colorTransformを使用している」ことが分かりました。
この問題のやっかいなところは、colorTransformが適用されないだけであり、別にエラーも出ないし、FlashPlayerも落ちたりしないので、何が悪いのか分からないところです。
処理の流れを想像してみる
描画対象はDisplayObjectの派生クラス(とBitmapDataクラス)なのですが、これらは「DisplayObjectのサイズと同じサイズの描画領域に現在の状態を描画しておくメソッド」と「最終的に描画メモリ領域に出力させるために呼ばれる描画メソッド」を持っていると思うのです。
仮に、前者をrender()、後者をtransfer() と呼ぶことにすると、次のような処理になっているのではないでしょうか。
- 毎フレームの処理というのは、描画リストにあるDisplayObjectのtransferを呼び出す処理、となる。
- そのときDisplayObjectにtransformが指定されていたら、renderで準備した画像に対してtransformを適用したものをtransferさせる。
まぁ、内部的にはもっと複雑だとは思いますが、何となくこうじゃないのかなぁ、と思っています。
「処理されない」を再現するコード
以上のテストは次のようにして再現してみました。
- 描画元となるMovieClipを用意し、それを_sourceと名付け、stage(下のあたり)に配置します。
- 描画先となるBitmapDataは _bmpdとして作成し、それを保持するBitmapインスタンスをstage(上部に広目)に配置します。
- 毎フレーム、_sourceにtransform.colorTransformを適用します。
- 毎フレーム、_bmpdに_sourceを描画します。(位置はカーソル位置)
- (具体的なソースコードはこのエントリ最後に載せておきます)

これで実行してみた結果は以下のようになり、colorTransformが適用されてない様子が分かるかと思います。(緑色のものがcolorTransformを適用している状態です)

colorTransform代替手法
以上で終わっても、あまり得にならないエントリになるので、colorTransformの代わりになり、BimapData.drawしてもそれが適用される、という方法を紹介しておきます。
それは、ColorMatrixFilterを使う方法で、具体的には以下のようになります。
1
2
3
4
5
6
7
8
9
10
11
| // [1] colorTransformを使う処理.
//_source.transform.colorTransform
// = new ColorTransform( 0.5, 0.5, 0.5, 1, 0, 120, 0, 0 );
// [2] [1]と同等の色変化があるColorMatrixFilter処理.
var cm:Array = [ 0.5, 0, 0, 0, 0,
0, 0.5, 0, 0, 120,
0, 0, 0.5, 0, 0,
0, 0, 0, 1, 0 ];
var cmf:ColorMatrixFilter = new ColorMatrixFilter( cm );
_source.filters = [cmf]; |
追記:Tweenerの変化を適用させることもできた!
この項目は2009/09/10追記しました。
コメント欄で、dskさんに「BitmapData.draw()ファンクションの第三引数にColorTransformを渡せます。」と教えていただきました。ありがとうございます!
で、早速検証してみました。
Tweenerで_sourceの色を変化させます。するとその変化は_source.transform.colorTransformに入っているはずなので、この値をそのままBitmapData.draw()の第3引数に渡してみたところ、問題なく、色の変化を描画することができました!
1
2
3
| var posmat:Matrix = new Matrix();
posmat.translate( mouseX, mouseY );
_bmpd.draw( _source, posmat, _source.transform.colorTransform ); // マウスの位置に描画. |

これにて完全解決!
Read More »