ActionScript 3.0入門ノート CS4でタグ「Vector」が付けられているもの

(section09-03 Flash Player10の新しいGraphicsメソッドから抜粋)

 図形を分割する頂点をマウスでドラッグするように動かして再描画すれば、図形をマウスドラッグで変形させることができます。次の例では四角形を図のように4分割し、2番の頂点をマウス座標に合わせて移動させています。

fig09-03-18_shiji.jpg fig09-03-19.jpg
fig: マウス座標の位置に頂点2を作り、頂点をマウスドラッグで移動させます。
swfを試す

 ただし、クリックした座標に単純に2番の頂点を移動させるとドラッグしなくてもマウスダウンしただけでテクスチャが変形してしまいます。そこでマウスダウンした位置のUV座標も再計算して再描画します(52行目)。この状態からマウスドラッグに合わせて頂点を移動させれば(61行目)、マウスダウンした位置から頂点をドラッグすることになり、マウスでイメージをつかんで引っ張っているように見えます。

(section09-03 Flash Player10の新しいGraphicsメソッドから抜粋)

 次のサンプルは図形を8個の三角形に分割した場合です。頂点は9個になり、それぞれの座標は6〜9行目でverticesに登録しています。8個の三角形は頂点を0-1-3、1-3-4、1-2-4のよう結んで作ります。この頂点の並びを11〜19行目でindicesに登録します。0〜8の各頂点のUV座標は21〜24行目でuvtDataに登録します。たとえば、7番の頂点のUV座標は(0.5, 1)になります。

fig09-03-16_shiji.jpg

[:script:]]図形を8個の三角形に分割してテクスチャを貼る
var shape:Shape=new Shape();
//ビットマップデータで塗る
var bmpdata:BitmapData=new IMG_8268(0,0);
shape.graphics.beginBitmapFill(bmpdata);
//頂点の座標
var vertices:Vector.<Number>=new Vector.<Number>();
vertices.push(0,0, 160,0, 320,0);//頂点0-1-2
vertices.push(0,120, 160,120, 320,120);//頂点3-4-5
vertices.push(0,240, 160,240, 320,240);//頂点6-7-8
//三角形を描く頂点
var indices:Vector.<int>=new Vector.<int>();
indices.push(0,1,3);//三角形A
indices.push(1,3,4);//三角形B
indices.push(1,2,4);//三角形C
indices.push(2,4,5);//三角形D
indices.push(3,4,6);//三角形E
indices.push(4,6,7);//三角形F
indices.push(4,5,7);//三角形G
indices.push(5,7,8);//三角形H
//頂点のUV座標(0〜1)
var uvtData:Vector.<Number>=new Vector.<Number>();
uvtData.push(0,0, 0.5,0, 1,0);//頂点0-1-2
uvtData.push(0,0.5, 0.5,0.5, 1,0.5);//頂点3-4-5
uvtData.push(0,1, 0.5,1, 1,1);//頂点6-7-8
//三角形を描く
shape.graphics.drawTriangles(vertices,indices,uvtData);
shape.graphics.endFill();
shape.x=100;
shape.y=50;
addChild(shape);

 さきほどと同じように頂点の座標を変更すると、頂点の移動に合わせてテクスチャとして貼ったビットマップデータも変形します。
vertices.push(0,30, 160,0, 320,30);//頂点0-1-2
vertices.push(30,120, 190,120, 290,120);//頂点3-4-5
vertices.push(0,210, 160,240, 320,220);//頂点6-7-8

fig09-03-17.jpg
(section09-03 Flash Player10の新しいGraphicsメソッドから抜粋)

 図形にビットマップデータをテクスチャとして貼るには、各頂点がビットマップデータのどの位置になるかをUV座標で指定します。UV座標はビットマップデータの左上角を(0,0)、右下角を(1,1)とした比率で示す座標です。

fig09-03-10_shiji.jpg
 次のサンプルは三角形を描き、ビットマップデータの左上半分をテクスチャとして塗るスクリプトです。三角形の頂点の座標をvertices、描画する頂点番号をindices、そして頂点に対応するビットマップのUV座標をuvtDataで指定しています。ビットマップデータはビットマップシンボルをIMG_8268の名前でリンケージ書き出ししています。

[:script:]三角形にビットマップデータのテクスチャを貼る
var shape:Shape=new Shape();
//ビットマップデータで塗る
var bmpdata:BitmapData=new IMG_8268(0,0);
shape.graphics.beginBitmapFill(bmpdata);
//頂点の座標
var vertices:Vector.<Number>=Vector.<Number>([0,0, 320,0, 0,240]);
//三角形を描く頂点
var indices:Vector.<int>=Vector.<int>([0,1,2]);
//頂点のUV座標(0〜1)
var uvtData:Vector.<Number>=Vector.<Number>([0,0, 1,0, 0,1]);
//三角形を描く
shape.graphics.drawTriangles(vertices,indices,uvtData);
shape.graphics.endFill();
shape.x=50;
shape.y=50;
addChild(shape);

fig09-03-12.jpg

(section03-04 Vectorクラスで作る配列から抜粋)

 ベクターはエレメントのデータ型だけでなく、配列の長さすなわちエレメントの個数も固定できます。エレメントの個数を固定するにはベクターを作る際に第1引数で配列の長さ、第2引数でtrueを指定します。長さを決めてベクターを作ると各エレメントにはベース型に合わせた初期値が入ります。
 次の例はベース型がintで長さを5に固定したベクターvlistを作っています。作られたvlistを確認するとint型の初期値の0が5個入ったベクターが作られています。

[:script:]長さを決めたベクターを作る
var vlist:Vector.<int>=new Vector.<int>(5,true);
trace(vlist);//出力:0,0,0,0,0
 長さが決まっているベクターに値を入れるには[]演算子を使ってエレメントにアクセスします。push()やshift()で値を追加すると長さが変化するので使えません。pop()、unshift()、splice()での値の抜き出しも長さを変更するので利用できません。

[:script:]長さが決まっているベクターに値を設定する
var vlist:Vector.<int>=new Vector.<int>(5,true);
//エレメントの値を設定する
vlist[0]=45;
vlist[1]=21;
vlist[2]=74;
trace(vlist);//出力:45,21,74,0,0
 ベクターの長さを固定するかどうかはfixedプロパティで設定できます。そこで長さを固定せずに値を追加し、後からfixedをtrueにして長さを固定することができます。

[:script:]ベクターに値を追加した後で長さを固定する
//ベース型がStringのベクターcolorsを作る
var colors:Vector.<String>=new Vector.<String>();
//ベクターに値を追加する
colors.push("green");
colors.push("red","blue");
//ベクターの長さを固定する
colors.fixed=true;
(section03-04 Vectorクラスで作る配列から抜粋)

 Arrayクラスの配列にはいろんなデータ型の値を混ぜて入れることができる手軽さがありますが、配列に入れる値は数値だけに限りたいというようにデータ型を限定したい場合があります。
 Vectorクラスで作る配列は値のデータ型を限定できるという点が大きな違いです。Vectorクラスで作る配列をベクターと呼び、ベクターのエレメント(値)のデータ型を「ベース型」と呼びます。
 次のスクリプトではベース型がStringのベクターcolorsを作っています。つまり、colorsにはString型の値しか入れることができません。変数colorsを宣言する際にはVector型を指定すると同時にベース型をVector.<ベース型>の書式で指定します。ベクターに値を入れるにはpop()やshift()を使って値を追加していきます。

[:script:]ベース型がStringのベクターを作り値を入れる
//ベース型がStringのベクターcolorsを作る
var colors:Vector.<String>=new Vector.<String>();
//ベクターcolorsに値を追加する
colors.push("green","red","blue");
trace(colors);//出力:green,red,blue
 ベクターにベース型とは異なるデータ型の値を追加するとエラーになるか、強制的にベース型で指定したデータ型に変換されます。たとえば、ベクターcolorsに数値を追加すると値をストリングに強制的に変換されて入ります。数値を入れてもストリングになっているので、取り出した値に+演算子で数値を足すとストリングの連結になり、数値演算をしようとするとエラーになります。

[:script:]ベース型とは異なるデータ型の値を追加した場合
//ベース型がStringのベクターcolorsを作る
var colors:Vector.<String>=new Vector.<String>();
//エレメントに数値を追加する
colors.push(100,200,300);
trace(colors[0]+99);//10099 -- 文字列として連結される
trace(colors[1]*2);//数値演算はエラーになる

windingプロパティ

|
(section09-03 Flash Player 10の新しいGraphicsメソッドから抜粋)

 drawPath()の第3引数で設定するwindingプロパティは図形のパスが交差してできる領域を塗るかどうかの湾曲規則を指定します。初期値では"evenOdd"になっていて、重なりが奇数回の場合に塗ります。
 次の例ではdata1、data2、data3と3つの図形が重なったパスを使って図形を描いています。このとき、2度重なっている部分は色が塗られず、3回重なっている部分は色が塗られているのがわかります。
fig09-03-03.jpg
[:script:]重なりがある図形をwindingプロパティを"evenOdd"で塗る
var w:int=120;
var h:int=150;
var data1:Array=[0,0, w,0, w,h, 0,h, 0,0];
var data2:Array=[25,25, w+25,25, w+25,h+25, 25,h+25, 25,25];
var data3:Array=[50,50, w+50,50, w+50,h+50, 50,h+50, 50,50];
var datalist:Array=data1.concat(data2,data3);
var commands:Vector.<int>=Vector.<int>([1,2,3,2, 1,2,3,2, 1,2,2,2,2]);
var data:Vector.<Number>=Vector.<Number>(datalist);
//描画の交差領域の塗りの処理法
var winding:String=GraphicsPathWinding.EVEN_ODD;
//図形を描く
var shape:Shape=new Shape();
shape.graphics.beginFill(0xFF0000);
shape.graphics.drawPath(commands, data, winding)
shape.graphics.endFill();
shape.x=200;
shape.y=150;
addChild(shape);

 windingプロパティのもう一方の値は"nonZero"です。この値はGraphicsPathWinding.NON_ZEROとして定数が定義してあります。windingプロパティを"nonZero"に設定すると湾曲タイプ(点を順に線で結ぶ方向)が時計回りか反時計回りかで図形を区別します。時計回りの値を+1、反時計回りの値を-1とし、重なっている領域はこの値を合計します。そして、値の合計が0の領域は塗らず、0以外の領域は塗ります。
 次の例ではすべてがdata1、data2、data3の全部が時計回りで+1なので、重なっている領域で合計が0になるところはありません。したがって、すべての領域が塗られます。
fig09-03-04.jpg
(section09-03 Flash Player 10の新しいGraphicsメソッドから抜粋)

 次の例はdrowPath()を使って渦巻き状に線を引くサンプルです。このように座標を計算式で求めることで図形を効率よく描けます。

[:script:]drawPath()を使って渦巻きを描く
var r:Number=1;
var rad:Number=2*Math.PI/8;
//描画コマンド
var commands:Vector.<int>=new Vector.<int>();
//描画に使う座標
var data:Vector.<Number>=new Vector.<Number>();
//コマンドと座標を追加する
commands.push(GraphicsPathCommand.MOVE_TO);
data.push(0,0);
for (var i:int=1; i<50; i++) {
	commands.push(GraphicsPathCommand.LINE_TO);
	r=i*i/20;
	var pt:Point=Point.polar(r,rad*i);
	data.push(pt.x,pt.y);
}
//図形を描く
var shape:Shape=new Shape();
shape.graphics.lineStyle(1,0x005500);
shape.graphics.drawPath(commands, data);
shape.x=stage.stageWidth/2;
shape.y=stage.stageHeight/2;
addChild(shape);
fig09-03-02.jpg
(section09-03 Flash Player 10の新しいGraphicsメソッドから抜粋)

 次にdrawPath()を使って図形を描くサンプルを示します。これを実行すると19行目でシェイプが作られ、このシェイプに図形を描画されます。drawPath()での描画はdrawRect()などの描画の手順と同じように図形を塗るならば描画する前にbeginFill()で塗りを開始し、描画終了でendFill()を実行します(20〜22行目)。実際に描画を行っているのは21行目のdrawPath()です。drawPathの3個の引数のcommandsとdataとwindingには、描画で必要となる値を入れておきます。
 commandsとdataはベクターです。ベクターを作るには、new Vector.<ベース型>()のようにベース型(値のデータ型)を指定してインスタンスを作ります。commandsは要素の値がint型なのでを指定します(4行目)。
fig09-03-01.jpg
[:script:]drawPath()を使って図形を描く
var w:int=150;
var h:int=120;
//描画コマンド
var commands:Vector.<int>=new Vector.<int>();
commands.push(GraphicsPathCommand.MOVE_TO);
commands.push(GraphicsPathCommand.LINE_TO);
commands.push(GraphicsPathCommand.CURVE_TO);
commands.push(GraphicsPathCommand.LINE_TO);
//描画に使う座標
var data:Vector.<Number>=new Vector.<Number>();
data.push(0,0);
data.push(w,0);
data.push(w,h);
data.push(0,h);
data.push(0,0);
//描画の交差領域の塗りの処理法
var winding:String=GraphicsPathWinding.EVEN_ODD;
//図形を描く
var shape:Shape=new Shape();
shape.graphics.beginFill(0xFF0000);
shape.graphics.drawPath(commands, data, winding);
shape.graphics.endFill();
shape.x=200;
shape.y=150;
addChild(shape);
 dataベクターを見るとわかるようにこの図形の描画には5個の点を使用し、ベクターには合計10個の値が入ります。commandsでは、dataから値を順に取り出してメソッドを実行していきます。commandsに追加したメソッドとdataの座標とを付き合わせると次のようになっています。moveTo()とlineTo()の引数は2個ですが、curveTo()はコントロールポイントの座標があるので4個の値を必要とします。
data.push(0,0);//moveTo(0,0)
data.push(w,0);//lineTo(w,0)
data.push(w,h);//curveTo(w,h,0,h)
data.push(0,h);
data.push(0,0);//lineTo(0,0)
まったく新しいAS3の世界!
694a.jpg
Adobe Flash CS4
詳細!ActionScript3.0入門ノート[完全改訂版](CD-ROM付)

楽しいActionScript。
新たなる1歩へと踏み出しましょう。
■内容は?→ 目次を見る
■評判は?→ 書評を読む
この本を書いたわけ

タグ

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

あわせて読みたいブログパーツ