flash.utils.Proxyが使えない件〜Filter型の謎
Bitmamap操作の練習にDisplacementMapFIlterを使ってみることにした。
使っていくうちに、いくつかの提携処理をクラス化出来ないかと考えた。
放射状のグラデーョンビットマップを使ったもの
格子上に二色のタイルを敷き詰めたもの
などなど
フィルターの使い方が、Spriteなどの表示オブジェクトのfiltersプロパティに渡す
という使い方なので、例えば、
var sprite:Sprite = new Sprite(); addChild(sprite); sprite.filters = [ new GradientRadialFilter(width, height, scaleX, scaleY), new GridFilter(width, height, gridWidth, gridHeight, scaleX, scaleY) ];
みたいに出来たら簡単だなと思って、クラスを書いてみたら、
「基本クラスはfinalです。」とか言われてしまう。
というわけで、継承は使えない。
まあそもそもは、DisplacementMapFilterに渡す
mapBitmapを作る部分が違うくらいなので、
var sprite:Sprite = new Sprite(); addChild(sprite); sprite.filters = [ new DisplacementMapFilter( new GradientRadialBitmap(width, height), null, 0, 0, scaleX, scaleY), new DisplacementMapFilter( new GridBitmap(width, height, gridWidth, gridHeight), null, 0, 0, scaleX, scaleY) ];
とか書けば良いのでしょうが、どうもイマイチ。。
あるいは委譲を使って、
var filterFactory:FilterFactory = new FilterFactory(); var sprite:Sprite = new Sprite(); addChild(sprite); sprite.filters = [ filterFactory.create(new GradientRadialFilter(width, height, scaleX, scaleY)), filterFactory.create(new GridFilter(width, height, gridWidth, gridHeight, scaleX, scaleY)) ];
とか?
うーむ、、どれもイマイチだな。
flash.utils.Proxyを使ってみたらどうだろう。
ということで試してみた。
package jp.seagirl.filters { import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.display.GradientType; import flash.display.Sprite; import flash.filters.DisplacementMapFilter; import flash.filters.DisplacementMapFilterMode; import flash.geom.Matrix; import flash.geom.Point; import flash.utils.Proxy; import flash.utils.flash_proxy; public dynamic class GradientRadialFilter extends Proxy { //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- public function GradientRadialFilter(width:Number = 0.0, height:Number = 0.0, scaleX:Number = 0.0, scaleY:Number = 0.0, mapBitmap:BitmapData = null, mapPoint:Point = null, componentX:uint = BitmapDataChannel.BLUE, componentY:uint = BitmapDataChannel.RED, mode:String = DisplacementMapFilterMode.COLOR, color:uint = 0, alpha:Number = 0.0 ) { if (mapBitmap == null) mapBitmap = createMapBitmap(width, height, [100, 255]); displacementMapFilter = new DisplacementMapFilter(mapBitmap, mapPoint, componentX, componentY, scaleX, scaleY, mode, color, alpha ); } //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- private var displacementMapFilter:DisplacementMapFilter; //-------------------------------------------------------------------------- // // Overridden methods // //-------------------------------------------------------------------------- override flash_proxy function callProperty(methodName:*, ... args):* { return displacementMapFilter[methodName].apply(displacementMapFilter, args); } override flash_proxy function getProperty(name:*):* { return displacementMapFilter[name]; } override flash_proxy function setProperty(name:*, value:*):void { displacementMapFilter[name] = value; } //-------------------------------------------------------------------------- // // Methods // //-------------------------------------------------------------------------- private function createMapBitmap(width:Number, height:Number, ratio:Array):BitmapData { var matrix:Matrix = new Matrix(); matrix.createGradientBox(width, height, 0, 0, 0); var map:Sprite = new Sprite(); map.graphics.beginGradientFill(GradientType.RADIAL, [0xff0000, 0x0000ff], [1, 1], ratio, matrix); map.graphics.drawRect(0, 0, width, height); map.graphics.endFill(); var mapBitmap:BitmapData = new BitmapData(width, height, true, 0); mapBitmap.draw(map); return mapBitmap; } } }
で、これをfiltersに入れてみる
sprite.filters = [new GradientRadialFilter(width, height, scaleX, scaleY)];
コンパイルは普通に出来たので、実行してみる。
するとランタイムエラー
「ArgumentError: Error #2005: パラメータ 0 の型が正しくありません。正しい型は Filter です」
となって、型チェックに弾かれてしまった。
必ずProxyクラスを継承しないといけないので、この場合Filterクラスに見せることは出来ない。
これでは、Proxyする意味がない
ところで、Filterなんてクラスどこにもいないことになってるけど何者…??
実はAS3のコアな部分ではこれらが抽象クラスとして存在してたりするの?
ASは手を出せば出すほど、コアな部分のソースを読みたいと思うようになる。