サンプルダウンロード
PDRファイル・CSFファイル在中
「3d_rotation_r.zip」 8.39 KB (8,599 バイト)
本格3D回転メニュー作成方法解説
ParaDraw Ver.0.3a4 で作成した絵を,Suzuka Ver.0.7.3.3 で動作させています。
本格3D回転メニュー などというタイトル名を使っていますが,これも実際はメニューではありません。簡単な透視変換(透視投影)を使って,ちょっとだけ本格的に3D風に回転するように見せかけたスプライト群です。
「簡易3D回転メニュー と何が違うねん!?」
と思われるかもしれませんが,そんなに違いはないと思います。作者は同じですし,比較するためになるべく違いがないように作成しましたので......。
大きな違いは次の図を見てもらえばわかると思います。

正投影図など平行投影図には,消失点(vanishing point)が存在しませんが,中心投影図などの遠近法を用いた透視図には消失点が存在します。
このサンプルは一点透視図法に基づいたスクリプトを用いたもので,一点透視図法は1つの消失点を持っています。
そして,すべての平行な直線は距離に比例してこの消失点へと近づいていき,やがて消えます。
いきなり難しいことを書きましたが,だいたい,「簡易」の方では egg の大きさは良いとしても,向こう側の egg と egg の隙間が大きすぎますよね。
これは消失点が無茶苦茶で遠近法が無茶苦茶だからです。したがって隙間などが不自然に見えます。
少なくとも「本格」の方はその点が解消されていると思います。
しかし,egg 自体の見え方,つまり 0〜9 の egg の絵を見る角度は変えていませんから,絵自体が 3D 変化するわけではありません。egg の運動と大きさを 3D に近い見かけにしているという擬似3Dです。
Flashは(Suzukaも) 2D(2次元)ソフトですが,遠近法(この場合一点透視図法)をスクリプトに採り入れると,ある程度 3D(3次元) 表現が実現できます。(※↓)
x-y軸座標しか持たない Flash などに z軸座標(奥行き) を持たせて,z座標を x-y軸座標に再計算させる変換を透視変換(透視投影)と言います。
もともと,モニタ自体も 2D なのですから,3D ソフトであっても内部のどこかで2Dに変換をかけているということになります。
上のサンプルでも,他のものと同様,ActionScriptコードを考えて書いたのはささきち自身ですが,透視変換やその関数を考えたわけではありません。
透視変換について調べていたら,簡単な公式(すぐに使えて動作が軽そうな関数)が見つかったので,それをこの ActionScript に採り入れてみました。
透視変換(透視投影)の原理は次の図のようになっています。

上の図の「見かけの大きさ=vs/(vs+sz)」という式を使って透視変換を行っています。
// 円運動させるものの個数を設定
n = 10;
// 円運動の基準 x座標 の設定
dtm_x = Stage.width/2;
// 円運動の基準 y座標 の設定
dtm_y = Stage.height/2;
// 円運動の半径の設定
rds = Stage.width/2-10;
// 円座標(角度)の初期値を設定
rad = 0;
//視点の距離を設定
vs = 180;
//
//透視変換用の関数 change3D を定義
function change3D(sx, sy, sz) {
dim_x = sx*vs/(vs+sz);
dim_y = sy*vs/(vs+sz);
scl = 1*vs/(vs+sz)*100;
}
//
// 1フレーム進む時間ごとに毎回実行
this.onEnterFrame = function() {
// 角度の加算をマウスの x座標 によって決める
rad += (_root._xmouse-dtm_x)/dtm_x*2*Math.PI/80;
// egg0〜egg n-1 までを操作
for (i=0; i<n; i++) {
// 角度を新たに変数化
rad2 = i*2*Math.PI/n+rad;
// 仮のx,y,z座標を算出
tmp_x = Math.cos(rad2)*rds;
tmp_y = Math.sin(rad2)*rds/4;
tmp_z = 100-(Math.sin(rad2)+1)*50;
//透視変換用の関数 change3D の実行
change3D(tmp_x, tmp_y, tmp_z);
// 変換後の数値によって座標や大きさなどを決定
this["egg"+i]._x = dim_x+dtm_x;
this["egg"+i]._y = dim_y+dtm_y;
this["egg"+i]._xscale = this["egg"+i]._yscale=scl;
this["egg"+i]._alpha = scl;
this["egg"+i].swapDepths(Math.floor(scl*10));
}
};
|
コードの内容自体も,簡易3D回転メニュー とほとんど変わりません。
//透視変換用の関数 change3D を定義
function change3D(sx, sy, sz) {
dim_x = sx*vs/(vs+sz);
dim_y = sy*vs/(vs+sz);
scl = 1*vs/(vs+sz)*100;
}
という,透視変換用の関数を用意しておいて,
this.onEnterFrame = function() { } 内から実行させています。
いったんは,egg の仮のx,y,z座標を算出しておいてそのまま代入するのではなく,透視変換用の関数で変換して,実際に座標や大きさを決めているという流れです。
わざわざ透視変換用の関数 change3D を定義する必要はありません。
this.onEnterFrame = function() { } 内に入れてしまっても良いのですが,入れてしまうと中身がごちゃごちゃになってわかりにくくなるかと思ったので,わざと別に定義してあるだけです。
あと,欲を言えば,アルファを使って空気遠近法を演出するのではなく,フィルターのブラー(ぼかし)を使いたいところですが,Suzuka では BlurFilter クラスのメソッドが使えないので,ActionScript のみでブラーをかけることはちょっと無理です。
Adobe Flash であっても,BlurFilter クラスのメソッドを使う場合は,
import flash.filters.BlurFilter;
のように BlurFilterクラス のクラスファイル定義をあらかじめ import しておく必要があります。
Suzuka の場合はここで エラー が出ますし,仮にエラーが出ないとしても BlurFilterクラス のクラスファイルなんてものが存在しないので,使用のしようがありません。
訂正!(勉強不足でした...(ノ_・、) スミマセン)
「フィルタパッケージの操作」
http://livedocs.adobe.com/flash/8_jp/main/00001507.html
> import ステートメントを使用して BlurFilter クラスを
> 読み込まない場合、フィルタを使用するには、
> 完全修飾名 (パッケージ名にクラス名を続けたもの) を
> 使用する必要があります。
>
> // import ステートメントを使わない場合
> var myBlur:flash.filters.BlurFilter
> = new flash.filters.BlurFilter(10, 10, 3);
というわけで,
こちらの文法を使うと import 文を使わなくても,フィルターはかけられるのでした〜!
これが使えるのなら,Flash 8 でできることの大半が,Suzuka でもできてしまうと言うことです...。
Suzukaって凄いな(今さらながら)。
この方法は 続々・3D回転メニュー で説明します。
しかし,BlurFilterクラス のメソッドを使わなくても,スプライト内で egg をブラー付きでトゥイーンさせて,そのスプライトにgotoAndStop(); を書けば,動的にブラーを変化させることは可能です。
これについては,続・3D回転メニュー でさらに説明します。
ちなみに,
ActionScript でも ParaDraw でもなく,Flash での透視図法を用いた絵の描き方についてですが,こちらについては,このサイトにもリンクをいただいている狼少年さんが説明されています。
一点透視図法など,図法自体の説明は狼少年さんのサイトの方がずっとわかりやすいと思います。
よろしければ参考にしてみてください。
FLAH学習・理論 透視図法
http://www17.ocn.ne.jp/~wolves/SCHOOL/lecture/lecR3-1.html
※ Flash は 2D ソフトであると書きましたが,
Flash8 及び Flash CS3 以上では,3Dエンジン「Papervision3D」
と組み合わせるとかなり本格的な3Dが作成可能のようです(未検証)。
ささきちのような数学に弱い人間がコツコツと変換を考えるよりは,
ずっと本格的で良いものが作成できると思います。
もし,興味とお金がある方は,
Papervision 3D について調べてみても良いかもしれません。
この辺りになると,現在の Suzuka では不可能に近い世界です。
時代は進んでいますし,Flash も進化し続けています。
Google検索:Papervision3D
Google検索:Papervision 3D
---2007年8月31日---
初回アップ
---2007年11月5日---
import flash.filters.BlurFilter;
に関しての内容を訂正
さらなる発展は
続・3D回転メニュー
続々・3D回転メニューへ
|