サンプルダウンロード
PDRファイル・CSFファイル在中
「3d_rotation.zip」 11.6 KB (11,966 バイト)
簡易3D回転メニュー作成方法解説
ParaDraw Ver.0.3a4 で作成した絵を,Suzuka Ver.0.7.3.3 で動作させています。
簡易3D回転メニュー などというタイトル名を使っていますが,実際はメニューではありません。また,単に簡易的に3D風に回転するように見せかけたスプライト群です。
各スプライトに onハンドラ などを書いて,何か動作をさせると,メニューになります。Flash 解説サイトなどでよく見かける動きのものです。
解説サイトでよくありますが,作り方や考え方や説明は ささきち流? のような気がします。
自分が実際に考えて作った順に説明します。
まず,スプライトは複数個回しますが,とりあえず1個を回してみようと思い作ったのが次のものです。
説明サンプル1 クリック (説明サンプル1は別窓で開きます。)
この 説明サンプル1 のフレームのスクリプトは次のようになっています。
egg0 が _root に置いたスプライトのインスタンス名です。
// 円運動の基準 x座標 の設定
dtm_x = Stage.width/2;
// 円運動の基準 y座標 の設定
dtm_y = Stage.height/2;
// 円運動の半径の設定
rds = Stage.width/2-60;
// 円座標(角度)の初期値を設定
rad = 0;
// 1フレーム進む時間ごとに毎回実行
this.onEnterFrame = function(){
// 角度を 80分の1周 加算(適当に代入してるだけ)
rad+=2*Math.PI/80;
egg0._x = dtm_x+Math.cos(rad)*rds;
egg0._y = dtm_y+Math.sin(rad)*rds;
my_txt.text = "sin(rad)="+Math.sin(rad);
};
|
角度の計算に degree(デグリー:度) を使って解説されているサイトが多いですが,ささきちの場合は使いません。
Math.sin() や Math.cos() の () 内に入れる角度は radian(ラジアン:弧度) ですから,最初から最後まで radian で考えた方が簡単で良いのではないかと思います。
習っていても習っていなくても,半周する角度が π(Math.PI)radian です。したがって1周する角度が 2π(2*Math.PI)radian です。
ただそれだけのことです。
ささきちは算数や数学が苦手なのですが,苦手だからこそ,ごちゃごちゃと変換演算が必要な degree(デグリー:度) で考える方がややこしいです。
もし,radian単位が覚えにくい(?)場合は,次のような絵でも連想すると覚えられるかもしれません。

「まず半切りのパイナップル片を空想してパイン(π)と思い込む。そのパインが2つ合わさると(2π)1周する。」
こんなささきち流の変な覚え方なんてどうでも良いですが,とにかく 「πが半周する角度で 2πが1周する角度」 です。
上のスクリプトに
// 角度を 80分の1周 加算(適当に代入してるだけ)
rad+=2*Math.PI/80;
と書いていますが,この 80 には何の根拠もありません。適当に入れた数値で,1フレーム進む時間ごとに毎回 1/80周 させてみようと思って書いてみたただけです。
そんな風に考えると,degree(デグリー:度) を使う必要は全くありませんね。degreeでは1周を360に分割して1度としますが,それ自体が大まかな地球の公転から決めた単なる勝手な定義であって,そういう関係ない定義を使っても何のメリットもないと思います。
また上のスクリプトにはこんな行があります。
my_txt.text = "sin(rad)="+Math.sin(rad);
これは,sinの値を使ってその後の値を決めようと思ったので,参考までに表示させているだけです。
sinの値は -1〜1 の間を行ったり来たりします。-1に近いときが上の方を移動中で,1に近いときが下の方を移動中です。
sin(サイン),cos(コサイン) に関しては習っていらっしゃらなければ当然わからないと思います。また,ここでは教えるのはちょっと難しいです。高校数学あたりで確か習いました(懐かしい〜)。
もし習っていらっしゃって,思いだせない方は次の図のようなものを思い出していただければ良いと思います。

sinの値を使った上で,さらに円運動をつぶし,擬似遠近感を入れたのが次のサンプルです。
説明サンプル2 クリック (説明サンプル2も別窓で開きます。)
この 説明サンプル2 のスクリプトは次のようになっています。
// 円運動の基準 x座標 の設定
dtm_x = Stage.width/2;
// 円運動の基準 y座標 の設定
dtm_y = Stage.height/2;
// 円運動の半径の設定
rds = Stage.width/2-60;
// 円座標(角度)の初期値を設定
rad = 0;
// 1フレーム進む時間ごとに毎回実行
this.onEnterFrame = function(){
// 角度を 80分の1周 加算(適当に代入してるだけ)
rad+=2*Math.PI/80;
egg0._x = dtm_x+Math.cos(rad)*rds;
// 円運動の y軸運動 を1/4 につぶす
egg0._y = dtm_y+Math.sin(rad)*rds/4;
// 不透明度を 60〜100 の間で変動させる
egg0._alpha = (4+Math.sin(rad))*20;
// 大きさも 60〜100 の間で変動させる
egg0._xscale = egg0._yscale = (4+Math.sin(rad))*20;
// 深度は 600〜1000 の間で変動させる
egg0.swapDepths(Math.floor((4+Math.sin(rad))*20)*10);
my_txt.text = "sin(rad)="+Math.sin(rad);
};
|
こんな感じで大きさとアルファを変化させて疑似的な遠近感を出しています。
また,本当は複数のスプライトを動かすので,この時点で深度のことも考えておきます。
以上のような感じで1つできればあとは for文 と 配列アクセス演算子 を使って一気に複数のスプライトを動かせば,だいたいは出来上がりです。
説明サンプル3 クリック (説明サンプル3も別窓で開きます。)
この 説明サンプル3 のスクリプトは次のようになっています。
// 円運動させるものの個数を設定
n = 10;
// 円運動の基準 x座標 の設定
dtm_x = Stage.width/2;
// 円運動の基準 y座標 の設定
dtm_y = Stage.height/2;
// 円運動の半径の設定
rds = Stage.width/2-60;
// 円座標(角度)の初期値を設定
rad = 0;
// 1フレーム進む時間ごとに毎回実行
this.onEnterFrame = function(){
// 角度を 80分の1周 加算(適当に代入してるだけ)
rad+=2*Math.PI/80;
// egg0〜egg n-1 までを操作
for(i=0; i<n; i++){
// 角度を新たに変数化
rad2 = i*2*Math.PI/n+rad;
this["egg"+i]._x = dtm_x+Math.cos(rad2)*rds;
// 円運動の y軸運動 を1/4 につぶす
this["egg"+i]._y = dtm_y+Math.sin(rad2)*rds/4;
// 不透明度を 60〜100 の間で変動させる
this["egg"+i]._alpha = (4+Math.sin(rad2))*20;
// 大きさも 60〜100 の間で変動させる
this["egg"+i]._xscale = this["egg"+i]._yscale = (4+Math.sin(rad2))*20;
// 深度は 600〜1000 の間で変動させる
this["egg"+i].swapDepths(Math.floor((4+Math.sin(rad2)*20)*10));
}
};
|
あとは,マウスの座標によって回転の速さを変えれば最初にある Flash のように動く物ができます。
上の 説明サンプル3 の,
// 角度を 80分の1周 加算(適当に代入してるだけ)
rad+=2*Math.PI/80;
という1行を,次のように変えます。
// 角度の加算をマウスの x座標 によって決める
rad+=(_root._xmouse-dtm_x)/dtm_x*2*Math.PI/80;
ただここを変更するだけで,マウスによって動きが変わるものになります。
この擬似 簡易3D回転メニュー の Flash は,実際に以上のように考えて,以上のような作成段階を経て作成しました。
他のものであっても,全体の構想は作る前に全て考えますが,実際に作成に取りかかるときには,だいたい上のように1段階ずつ検証しながら作成していきます。
さらなる発展は本格3D回転メニュー へ
|