|
JaGra PROFESSIONAL SCHOOL Seminar
Flash 8特別セミナー「新機能とスクリプティング」
Date: 2005年12月6日 |
Product: Flash |
Platform: All
Viersion: 8.0
1. ぼかしとドロップシャドウフィルタ
スクリプトによるフィルタの基本的な使い方について、詳しくは「スクリプトでフィルタを使う − BlurFilter」を参照してほしい。
サンプル001■DropShadowFilterとBlurFilter(SWFのみ[*1])
フィルタを適用するには、第1にフィルタインスタンスを、new演算子で作成。フィルタクラス名は、フルネームで指定する。BlurFilterクラスのフルネームは、flash.filters.BlurFilter。「ActionScript 2.0リファレンスガイド」(図001)で確認する。
図001■BlurFilterクラス
import宣言すれば、そのスクリプトペイン(ウィンドウ)内は、クラス名だけでアクセスできる。
// importでBachのフルネームを宣言
import johann.sebastian.Bach;
// 以下Bach
var myMusician:Bach = new Bach();
第2に、作成したフィルタインスタンスを配列に入れて、その配列をMovieClip.filtersプロパティに適用する。つぎのフレームアクション(スクリプト001)は、スクリプトを記述したMovieClipインスタンスに、BlurFilterを適用。関数BlurFilter()に引数を指定していないので、デフォルト値として水平・垂直のぼかし量にはともに4が設定される。
スクリプト001■MovieClipにBlurFilterを適用
import flash.filters.BlurFilter;
var myBlur:BlurFilter = new BlurFilter();
this.filters = [myBlur];
|
BlurFilter(水平方向ぼかし, 垂直方向ぼかし, クォリティ)
指定した設定でBlurFilterインスタンスを生成する。クォリティは整数で、通常1から3までの値を使う(数値が大きいほどぼけ幅も大きい。0はぼかしなし)。デフォルト値(引数省略時の値)はぼかし量が4、クォリティは1。
|
サンプル002は、楕円軌道を回転するMovieClipに対してBlurFilter()を適用し、ぼかし量0から4までの数値で、Y座標が上(マイナス方向)になるほど高い値を指定している。
サンプル002■3DRotation
サンプル001のスクリプトはつぎのとおり(スクリプト002)。楕円軌道を回転する3D風のアニメーションについては、F-siteセミナー「はじめの一歩のアクションスクリプト」レジュメの「4. Mathクラスを使う」の項を参照。
スクリプト002■3D風に楕円軌道を回転するMovieClipにBlurFilterを適用
// タイムライン: _root
// [ライブラリ]にリンケージ識別子"Pen"を設定したMovieClipが格納
// 第1フレームアクション
var nAmount:Number = 6;
var menus_array:Array = new Array();
var oInitObject:Object = new Object();
oInitObject.nRadiusX = 100;
oInitObject.nRadiusY = 20;
oInitObject.nCenterX = Stage.width/2;
oInitObject.nCenterY = Stage.height/2;
for (var i:Number = 0; i<nAmount; ++i) {
var target_mc:MovieClip = this.attachMovie("Pen", "my"+i+"_mc", i, oInitObject);
target_mc.nRadian = i*360/nAmount/180*Math.PI;
menus_array.push(target_mc);
}
this.onEnterFrame = function():Void {
xRotateAll(2/180*Math.PI);
};
function xRotateAll(nRadian:Number):Void {
var nLength:Number = menus_array.length;
for (var i:Number = 0; i<nLength; ++i) {
menus_array[i].xRotate(nRadian);
}
}
// MovieClip: リンケージ識別子"Pen"
// 第1フレームアクション
import flash.filters.BlurFilter;
var nMyDepth:Number = this.getDepth();
this.xRotate(0);
function xRotate(nTheta:Number):Void {
nRadian += nTheta;
var nUnitX:Number = Math.cos(nRadian);
var nUnitY:Number = Math.sin(nRadian); // -1 ≦ nUnitY ≦ 1
_x = nRadiusX*nUnitX+nCenterX;
_y = nRadiusY*nUnitY+nCenterY;
_xscale = 100*nUnitY;
// _alpha = 50*(nUnitY+1)/2+50;
var nBlur:Number = 4*(-nUnitY+1)/2; // 0 ≦ nUnitY ≦ 4
// BlurFilterインスタンス生成
var myBlur:BlurFilter = new BlurFilter(nBlur, nBlur/2);
// MovieClip.filtersプロパティ設定
this.filters = [myBlur];
var nDepth = (nUnitY>0 ? nMyDepth+100 : nMyDepth);
this.swapDepths(nDepth);
}
|
[*1] ベースにした.flaファイルは、[Flash 8アプリケーション]/Samples and Tutrials/Samples/ActionScript/Filters/Filters.fla。
|
2. ビットマップデータをディゾルブする
BitmapData.loadBitmap()およびMovieClip.attchBitmap()メソッドを使うと、[ライブラリ]からビットマップをダイナミックにMovieClipとして配置できる。つぎのサンプルは、[ライブラリ]にあるリンケージ識別子"Pen"を設定したビットマップ(図002)をロードして、ダイナミックに作成したMovieClipに配置する(スクリプト003)。
図002■[ライブラリ]のビットマップにリンケージ識別子を設定
スクリプト003■[ライブラリ]からビットマップをダイナミックに配置
import flash.display.BitmapData;
var myBitmapData:BitmapData = BitmapData.loadBitmap("Pen");
var _mc:MovieClip = this.createEmptyMovieClip("mc", this.getNextHighestDepth());
_mc.attachBitmap(myBitmapData, _mc.getNextHighestDepth());
|
BitmapData.loadBitmap(リンケージ識別子)
リンケージ識別子が設定されたビットマップをロードして、新しいBitmapDataインスタンスを作成する。
MovieClip.attachBitmap(BitmapDataインスタンス, 深度)
指定されたBitmapDataインスタンスのイメージを、MovieClipに設定する。
|
サンプル003■PixelDissolve
サンプル003は、画像をクリックすると、ディゾルブによりホワイトアウトする(スクリプト004)。Bitmap.pixelDissolve()メソッドには、毎回異なったランダム値を引数として渡す必要がある。そのようなランダム値は、メソッドの戻り値になっているので、それを受取って次回の呼出し時に用いる。
スクリプト004■画像をクリックでディゾルブ
import flash.display.BitmapData;
import flash.geom.Point;
var myBitmapData:BitmapData = BitmapData.loadBitmap("Pen");
var _mc:MovieClip = this.createEmptyMovieClip("mc", this.getNextHighestDepth());
_mc.attachBitmap(myBitmapData, _mc.getNextHighestDepth());
var nRandom:Number;
_mc.onPress = function() {
nRandom = Math.floor(Math.random()*10);
this.onEnterFrame = xDissolve;
};
var nTotalDissolved:Number = 0;
var nTotalPixels:Number = myBitmapData.width*myBitmapData.height;
var nDissolving:Number = 30;
var zeroPoint:Point = new Point(0, 0);
function xDissolve() {
nRandom = myBitmapData.pixelDissolve(myBitmapData, myBitmapData.rectangle, zeroPoint, nRandom, nDissolving, 0x00FFFFFF);
nTotalDissolved += nDissolving;
if (nTotalDissolved>=nTotalPixels) {
delete this.onEnterFrame;
}
nDissolving = Math.floor(nDissolving*1.1);
}
|
BitmapData.pixelDissolve(ソースBitmapData, ソース矩形領域, 左上隅Point, ランダム値, ピクセル数, カラー値)
ソースイメージを、指定したカラー値でディゾルブする。ターゲットのBitmapDataと異なるソースイメージを指定すれば、ターゲットからソースへのディゾルブも可能。
ユニークなランダム値が返されるので、連続したディゾルブには、その値をつぎの呼出し時に引数として渡す。
|
3. コンボリューション行列
ConvolutionFilterは、コンボリューション行列を用い、ピクセル単位で周囲のピクセル情報をもとにイメージ処理を行う。その結果、エンボスや輪郭検出、ぼかし、シャープなど、さまざまな効果が適用できる(サンプル004)。行列に指定する値とその効果については、「コンボリューション行列」の解説が詳しい。
サンプル004■Convolution − いくつかの効果
エンボスを5×5のコンボリューション行列で指定すると、つぎのようになる(表001)。
表001■エンボスのコンボリューション行列
0
|
0
|
0
|
0
|
0
|
0
|
1
|
1
|
0
|
0
|
0
|
1
|
0
|
-1
|
0
|
0
|
0
|
-1
|
-1
|
0
|
0
|
0
|
0
|
0
|
0
|
|
除数 1
バイアス 128
|
ConvolutionFilter(列数, 行数, コンボリューション行列, 除数, バイアス)
コンボリューション行列を適用してピクセル単位のイメージ処理を行う。
|
つぎのサンプル005は、画像をクリックすると、コンボリューション行列を使ってエンボスの効果を適用する(スクリプト005)。
サンプル005■ConvolutionEmboss
スクリプト005■ConvolutionFilterでエンボスを設定
// MovieClip this;
import flash.filters.ConvolutionFilter;
import flash.display.BitmapData;
var _mc:MovieClip = this.createEmptyMovieClip("image_mc", this.getNextHighestDepth());
_mc.attachBitmap(BitmapData.loadBitmap("Pen"), _mc.getNextHighestDepth());
// ConvolutionFilter引数設定
var nMatrixX:Number = 5; // 列数
var nMatrixY:Number = 5; // 行数
// コンボリューション行列を配列として作成
var matrix_array:Array = new Array();
// 最終的に作成される25エレメントの配列[*2]
// [0,0,0,0,0,0,1,1,0,0,0,1,0,-1,0,0,0,-1,-1,0,0,0,0,0,0]
matrix_array = matrix_array.concat([0, 0, 0, 0, 0]);
matrix_array = matrix_array.concat([0, 1, 1, 0, 0]);
matrix_array = matrix_array.concat([0, 1, 0, -1, 0]);
matrix_array = matrix_array.concat([0, 0, -1, -1, 0]);
matrix_array = matrix_array.concat([0, 0, 0, 0, 0]);
var nDivisor:Number = 1; // 除数
var nBias:Number = 128; // バイアス
_mc.onPress = function():Void {
var myConvolution:ConvolutionFilter = new ConvolutionFilter(nMatrixX, nMatrixY, matrix_array, nDivisor, nBias);
this.filters = [myConvolution];
};
|
[*2] ConvolutionFilter()に指定するコンボリューション行列は行数(5)×列数(5)の総エレメント数(25)を羅列した配列なので、Array.concat()メソッドを使って、RGBA各カラー値ごとの5エレメントからなる4つの配列をひとつに連結している。
|
4. 変換行列
Transform.matrixプロパティは、MovieClipの拡大・縮小や回転、傾斜を決める値を格納したMatrixオブジェクト(変換行列)。3×3の変換行列のうち、a、b、c、d、tx、tyの6つのプロパティが操作できる。サンプル006は、これら6つのプロパティの操作と、回転を行った場合のa、b、c、dの値の算出を、シミュレートする。
サンプル006■変換行列の操作(SWFのみ)
変換行列をもつMatrixクラスには、直接プロパティ値を変更する方法以外に、移動や拡大・縮小、回転を行うためのメソッドが用意されている。
Matrix.translate(tx, ty)
水平方向にtxピクセル、垂直方向にtyピクセル平行移動する。
Matrix.scale(a, d)
水平方向にa倍、垂直方向にd倍の拡大・縮小を行う。
Matrix.rotate(θ)
角度θ(ラジアン)の回転を行う。変換行列のプロパティ4つの値を、a:cosθ、b:sinθ、c:-sinθ、d:cosθに設定するのと同じ結果になる。
|
サンプル007■Transform
サンプル007は、画像の3つの頂点をドラッグで移動すると、それらの座標に対応した変換行列の値を計算して、画像を平行四辺形に変形する。計算した変換行列の値は、Matrixインスタンスのプロパティに設定したうえで、そのMatrixをMovieClip.transformプロパティに設定している(スクリプト006)。
スクリプト006■MovieClipの3頂点の座標を指定して変形
// タイムライン: _root
// 第1フレームアクション
// 変形するMovieClip: _root.my_mc
import flash.geom.Matrix;
import flash.geom.Point;
// Pointインスタンスで指定された3頂点に合わせてMovieClipを変形する
// MovieClip.transform.matrixのプロパティ値を計算して設定
function xTransformMovieClipPoints(_mc:MovieClip, point0:Point, point1:Point, point2:Point):Void {
var myMatrix:Matrix = _mc.transform.matrix;
var contents_mc:MovieClip = _mc.contents;
var nWidth:Number = contents_mc._width;
var nHeight:Number = contents_mc._height;
var point1_0:Point = point0.subtract(point1);
var point1_2:Point = point2.subtract(point1);
myMatrix.tx = point1.x;
myMatrix.ty = point1.y;
myMatrix.a = (point1_0.x)/nWidth;
myMatrix.b = (point1_0.y)/nWidth;
myMatrix.c = (point1_2.x)/nHeight;
myMatrix.d = (point1_2.y)/nHeight;
_mc.transform.matrix = myMatrix;
}
// 3頂点の座標を取得してxTransformMovieClipPoints()に渡す
// ドラッグした頂点のMovieClipから呼出される
function xTransform() {
var point0:Point = new Point(point0_mc._x, point0_mc._y);
var point1:Point = new Point(point1_mc._x, point1_mc._y);
var point2:Point = new Point(point2_mc._x, point2_mc._y);
xTransformMovieClipPoints(my_mc, point0, point1, point2);
}
// MovieClip: ドラッグする頂点
// 第1フレームアクション
function onPress():Void {
this.startDrag();
}
function onRelease():Void {
xOnRelease();
}
function onReleaseOutside():Void {
xOnRelease();
}
function xOnRelease():Void {
this.stopDrag();
_root.xTransform()
}
|
変換行列は、画像の3Dマッピングに応用できる。サンプル008は、立方体の3D空間における仮想の頂点座標を回転し[*3]、2Dに透視変換した座標に対して6つの画像を変形して、3次元の回転を表現している。応用事例として、サンプル中のスクリプトに簡単なコメントを加えた。
サンプル008■3D_Box − 変換行列の応用
5. setTimeout()とclearTimeout()関数
Flash 8から、setTimeout()とclearTimeout()関数が実装された。ヘルプに記載はないものの、公式にサポートされる。詳しくは「setTimeout()関数」と「clearTimeout()関数」を参照してほしい。
6. 参考URL
Flash 8の技術情報に関わる参考サイト。
Flash 8 LiveDocs英語版 / Flash 8 LiveDocs日本語版
ヘルプと同内容のドキュメント。ユーザーやMacromediaの人たちが、修正・補足の情報をコメントとして追加できる。Flash 8から日本語版がアップされた。
Flash 8ヘルプ勝手に正誤表
野中が独自の判断により、一方的に作成。LiveDocsにもコメントを入れて、リンクしている。Macromedia側の確認を経て、採用されたものもある。
mixi: [ActionScript Lounge]コミュニティ
野中の主催するmixiのコミュニティ。ActionScriptのマニアックな話題を掲載する。Flash 8のバグ情報も適宜追加中。
A. おまけ
Flash 8には、MXからあるゲーム以外に、イースターエッグがもうひとつ加わった。
図003■クリックするとEaster Eggsが
開発チームといえるか、疑問な顔ぶれも...
_____
作成者: 野中文雄
作成日: 2005年12月16日
(ドラフト作成: 2005年12月15日)
Copyright ©
2001-2006 Fumio Nonaka. All rights reserved.
|