Home > action script > Flashで3Dの表現:3Dメニューみたいな

Flashで3Dの表現:3Dメニューみたいな

3d.jpg

といっても、Flashは3Dソフトではないので、擬似的に3Dに見える表現をする事になります。

そのあたりの説明はKeith Petersさんの「Making Things Move」に大変分かりやすく書かれていますし、今回の核となるスクリプトも、書籍に書かれています。

・手前のものほど大きく、奥のものは小さく見える。 ・奥のものほど消失点に近づく。 というのを基本ルールとし、今回は、奥のものほど暗くなる(照明が当たらなくなる)感じを表現してみました。(要 Flash Player8 以上)

3d.swf

というのが今回制作したサンプルです。ソースは以下のようになります。


import flash.geom.ColorTransform;

//Vanishing Point(消失点)
var vpX = Stage.width/2;
var vpY = Stage.height/2;
//矩形の数
var rectNum:Number = 20;
//中心軸と配置するムービークリップとの距離
var radius:Number = 150;
//Focal Length(焦点距離)
var fl:Number = 250;

init();
function init():Void {
    for (var i:Number = 0; i<rectNum; i++) {
        var rect:MovieClip = attachMovie("rect""rect"+i, i);
        var angleInitY:Number = (360/rectNum)*i;
        //ラジアンに変換
        angleInitY = angleInitY*Math.PI/180;
        var cosInitY:Number = Math.cos(angleInitY);
        var sinInitY:Number = Math.sin(angleInitY);
        var initX1:Number = radius*cosInitY-0*sinInitY;
        var initZ1:Number = 0*cosInitY+radius*sinInitY;
        rect.x = initX1;
        rect.y = 0;
        rect.z = initZ1;
        rect.number.text=i
        //pall.swapDepths(0)//中心棒を通す
    }
}
function onEnterFrame():Void {
    if(_root._xmouse>=0&&_root._xmouse<=Stage.width){//ブラウザの別ウィンドウが開かれた時の対策
        for (var i:Number = 0; i<rectNum; i++) {
            var rect:MovieClip = this["rect"+i];
            var angleY:Number = (_xmouse-vpX)*0.001;
            var cosY:Number = Math.cos(angleY);
            var sinY:Number = Math.sin(angleY);
            var angleX:Number = (_ymouse-vpY)*0.001;
            var cosX:Number = Math.cos(angleX);
            var sinX:Number = Math.sin(angleX);
            
            var x1:Number = rect.x*cosY-rect.z*sinY;
            var z1:Number = rect.z*cosY+rect.x*sinY;
            var y1:Number = rect.y*cosX-z1*sinX;
            var z2:Number = z1*cosX+rect.y*sinX;
            
            rect.x = x1;
            rect.y = y1;
            rect.z = z2;
            var scale = fl/(fl+rect.z);
            rect._xscale = rect._yscale=scale*100;
            rect._x = vpX+(rect.x*scale);
            rect._y = vpY+(rect.y*scale);
            //zの値をもとに、重なり順を調整
            rect.swapDepths(-rect.z);
            //奥のムービークリップの明度を下げる
            var val = Math.min(-5*Math.sqrt(z2),0);
            rect.transform.colorTransform = new ColorTransform(1, 1, 1, 1, val, val, val, 0);
        }
    }
}

このソースを第一フレームにコピペし、ライブラリに、中心を基準にしたムービークリップ「rect(リンケージ名もrect)」を用意すれば動くとおもいます。サンプルのように数字を表示させたいときはrectの中にダイナミックテキスト「number」を置いてください。

スクリプトの先頭から見ていきます。

まず、今回は奥のMCほど暗くなるという表現に使うために、ColorTransformクラスをインポートしておきます。

次に初期値の設定をします。値の内容はコメントを参考にしてください。

続いて、イニシャライズ、及びそれ用の関数の定義をしています。今回はy軸を中心軸として、軸からの距離radiusにシンボルrectをrectNumの数だけ等間隔に配置するように設定しています。(実際に配置しているのは後ろのonEnterFrameで処理していて、ここでは初期座標となるx,y,zの値を設定しているだけです。)

どうやって座標を得ているかというと、以前のエントリ「〜度回転させた後の_xと_yを求める方法」を使って、座標{x:radius, y:0, z:0}にあるものを中心軸を回転の軸として(30*i)度回転させたときの座標を得るようにしています。

その後、onEnterFrameの中で、ステージの中心とマウス座標の距離からy軸を中心にangleY、x軸を中心にangleX回転させる処理をしています。回転後の座標は先程と同様の手法で、今回は2軸回転させるので、一度y軸回転させ、さらにx軸回転させたときの座標を得るという感じの2段処理をしています。

var scale = fl/(fl+rect.z);
rect._xscale = rect._yscale=scale*100;
rect._x = vpX+(rect.x*scale);
rect._y = vpY+(rect.y*scale);

この時点で奥行きz(奥に行くほどzが大きくなる座標体系を使っています)が手に入りましたので、ステージ、焦点距離、zとの関係(Making Things Move p328)を使ってscaleを割り出し、ムービークリップの大きさ、座標を決定しています。

rect.swapDepths(-rect.z);

swapDepthsで手前のMCほど上に配置するようにしています。

var val = Math.min(-5*Math.sqrt(z2),0);
rect.transform.colorTransform = new ColorTransform(1, 1, 1, 1, val, val, val, 0);

最後に、焦点距離flより向こうにあるMCの明度を落とすようにしています。z2のままだと、再奥部で急激に暗くなる感じだったので、Math.sqrt()でバイアスをかけ、(しつこいようですが、zは奥がプラスになるので、明度を下げる→マイナスの値が欲しいので)-5を掛けています。このままだと手前のMCはプラスの値になり、明るくなってしまうので、値がプラスのときはMath.min()で0になるようにしています。

そして、Flash8の新機能であるColorTransformでrgbそれぞれを下げて、暗くしています。
(追記:上のスクリプトは多分彩度が下がる。明度は前の3つのパラメーター下げた方がいいかもです。)

これをベースに、1軸を固定して、1方向だけに回転するムービー(angleX=0にする等)とか、自動で回転し続ける(angleY=0.02にする等)、その際、やや見下ろす感じにする(initの中のrect.y=20にする等)とか、いろいろ調節するだけで、いろんな動きができるので、しばらく退屈しないとおもいます。

僕は3D表現なんてさっぱり分かりませんでしたが、「Making Things Move」を読んで「エウレカッ!」だったので激しくお勧めしておきます。

Foundation Actionscript Animation: Making Things Move (Foundation)

Comment:13

starter 2006-09-21 (木) 23:48

ダイナミックテキストの文字も拡大縮小されると思いますが、なぜ綺麗に拡大縮小されるのですか?
私がやろうとしても、文字がぶれたりしてしまいます・・・

tera 2006-09-22 (金) 00:45

>>starterさん
はじめましてこんばんは。
ご質問頂いた件ですが、ダイナミックテキストに対して、フォントの埋め込みはされているでしょうか?
ダイナミックテキストボックスを選択した状態で、プロパティパネルの右端の「埋め込み…」ボタンをクリックして、(サンプルの場合は)数字のアウトラインデータを選択し、埋め込んでます。その分swfファイルの総データ量は大きくなりますが、数字やアルファベットぐらいなら大丈夫かなと思います。日本語を埋め込むと激重になります。
フォントが「_ゴシック」とかだと埋め込み自体ができませんので何か他のフォントにして下さい。

心当たりといえばこれくらいなのですが、いかがでしょうか?それとも別の原因でしょうか?

starter 2006-09-22 (金) 08:14

ありがとうございます。
おっしゃる通りでした♪お恥ずかしいです。
1軸回転で使わせて頂いております。

あと、BlurFilterも使わせて頂いておりますが、
flash.filters.BlurFilterとしないと私の環境では動きませんでした。これはバージョンの違いなどですかね?

今後も勉強させて頂きますのでよろしくお願いします。記事の更新楽しみにしております。

tera 2006-09-22 (金) 08:23

おはようございます。
解決してよかったです。
BlurFilterは僕が書き忘れていました。starterさんがおっしゃられるように、どの環境でもflash.filters.BlurFilterしないといけないです。
記事の方を修正しておきます。
ありがとうございました。

araview 2006-12-08 (金) 12:44

実際に3Dをブラウザ上で再生し、そのウィンドウを開いたまま他のウィンドウやデスクトップで作業を始めると
動きが暴走し始めるのはブラウザやコンピュータによるのでしょうか。多分SWFがマウスの位置を読めなくなるのが
原因ではないかと思ったのですが。。。

tera 2006-12-08 (金) 13:34

>>araview様
コメントありがとうございます。
当方のMac/FireFox1.5でも確認いたしました。
この記事では、とにかくグイングインまわる仕組みだけを掲載していましたので、細かい条件設定等はしてませんでした。
エントリ中のコードとswfを修正し、対応しました。
onEnterFrame関数の2行目に、_xmouseの条件分岐を入れ、エリア外なら回転が止まるようにしました。
上記対応方法以外にも、変数をかませて、「エリア外の時はこの回転数で」という指定も可能ですし、ご自由に条件づけてくださいです。
よろしくお願いします。

shin 2007-07-15 (日) 04:06

はじめまして。
私はaction scriptを勉強し始めて1ヶ月の初心者です。
このソースで、メニューを作りたいのですが、数字ではなく
テキストを表示させるにはどうしたらよろしいのでしょうか?
自分なりに調べてみたのですが、どうしてもわからずじまいで・・・
もし、お時間が許せばレスをお願い致します。

tera 2007-07-15 (日) 10:39

init 関数の行末の rect.number.text=i; の i の所を "いろは" にしてみて下さい。その際、ネットで公開した時用に、ムービークリップ rect の中のダイナミックテキストに日本語を埋め込むか、フォントの指定を _ゴシック にするなどしておいてください。
これで、数字の部分が全て"いろは"になります。
文字をひとつひとつ帰る場合は予め外側(コード2行目にでも)ムービークリップの個数分の配列に各テキストを格納しておき、
menuArray = ["トップ", "about", "works", "recruit"]; とか
で、上記initの中を
rect.number.text=menuArray[i];
でいけるのではないでしょうか。(未検証ですが)

shin 2007-07-17 (火) 00:24

お忙しい中、レスをありがとうございした。

さっそく検証してみます。

shima 2007-07-31 (火) 16:19

 初めまして。今回初めて書き込みさせていただきます。アクションスクリプトを始めて間もないのですが、自分なりに頑張っております。このソース(回転する数字)で、画像などを個々に変更したい場合はどの様な仕組みになるのでしょうか?試行錯誤しているのですが、なかなか進まず・・・お時間の許す限りで結構ですので、教えて頂ければ嬉しいです。

tera 2007-07-31 (火) 16:35

>shima様
はじめまして。コメントありがとうございます。
ご回答としましては、
http://www.trick7.com/blog/2006/07/10-124628.php
の記事のコメント部分に書いております内容以上のことは現状ご用意できませんです。
まずはそちらの方をご覧くださいませ〜。

有り難う御座います 2007-08-01 (水) 12:00

素早いご返事感謝致します。無理を言って申し訳ありません。そちらを参考にして検証してみたいと思います。

nayu 2008-06-06 (金) 13:36

エウレカッってどういう意味でしょうか?
Yahooで検索するとエウレカセンブンとでてきたのですが
関係あるのでしょうか

Comment Form

コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。

Remember personal info

Trackback:0

TrackBack URL for this entry
http://www.trick7.com/blog/mt-tb.cgi/174
Listed below are links to weblogs that reference
Flashで3Dの表現:3Dメニューみたいな from trick7.com blog

Home > action script > Flashで3Dの表現:3Dメニューみたいな

持っている Flash & ActionScript 関連本の中から、自分的おすすめの読む順番をご紹介。各書籍のレビューは books カテゴリからご覧頂けます。
この順番でどう?(AS3.0)
  • Adobe Flash CS3 詳細! ActionScript 3.0 入門ノート (DVD付)
    Adobe Flash CS3 詳細! ActionScript 3.0 入門ノート (DVD付)

    デザイン方面からFlashデビューして、そのままAS2.0を使うようになった人が、難しいと評判のAS3デビューする時の最初の1冊として、とにかく目を通しておくと良いかと思います。プログラミング経験の少ない方でも、サンプルをじっくり読めば、ゼロからのAS3デビュー可。
  • ActionScript 3.0 アニメーション
    ActionScript 3.0 アニメーション
    洋書「Making Things Move!」の日本語訳本。ActionScript3.0で数学的アニメーションを作ることがメインテーマなのですが、前半部分でAS3.0の基礎を分かり易く解説されています。後半の重力, IK, 3D表現等のアニメーション解説も楽しい。僕はこれのAS2.0洋書版を読んでFlashの面白さに気付きました。
  • Essential ActionScript 3.0 (Essential)
    Essential ActionScript 3.0 (Essential)

    900ページ以上ある相当分厚い本。基礎からOOPまでを解説。ほぼ網羅しているので、これを抑えておけばAS3博士になれそう。
  • Actionscript 3.0 Cookbook
    Actionscript 3.0 Cookbook

    ActionScript3.0のリファレンス本。問題とその解決法が1ページぐらいで細分化されているので空いた時間にちょっとずつ読み進められる。WebでAS3のソースを見て勉強する時の字引としても使う。ただ、時期的に初期の本なので、AS3自体が仕様変更してたりするので正誤表は必読。
  • Object-Oriented Actionscript 3.0
    Object-Oriented Actionscript 3.0

    7/23に発売されたFlash&OOP本。AS2.0版は持っているのだけど、オブジェクト指向の初歩的な解説から入って、後半は僕の理解を超える難度になっていきました。今度こそ理解できるか?
この順番でどう?(AS2.0)
  • Foundation Actionscript Animation: Making Things Move (Foundation)
    Foundation Actionscript Animation: Making Things Move (Foundation)

    スクリプトでアニメーションさせる方法を学べる。プログラムの知識というよりも数学や物理の知識が必要。バネの表現や3D表現など、汎用性の高いテクニックを身に付けられ、個人の表現力をレベルアップするのに最適。参考までに、僕が調べた英単語リスト。2007年4月に、AS3対応版も発売されました。
  • ゲーム開発のための数学・物理学入門 Beginning Math and Physics for Game Programmers
    ゲーム開発のための数学・物理学入門  Beginning Math and Physics for Game Programmers

    「Making Things Move!」の世界を突き詰めたい人用のステップアップのための本。行列や物理運動、2D/3D表現。Flashの本ではなく、じっくり読むタイプの本なので、あとまわしにしてもいいかも。
  • Flash 8 Essentials
    Flash 8 Essentials

    Flash8の新機能を紹介。全10章が独立した構成で、興味のある部分から読めます。フィルタやビットマップ、ビデオの使い方とかを、基礎から順を追って理解していけるので、ゼロからスクリプティングできるようになる。僕はビットマップ関連の作業の際のリファレンスとして常用しています。
  • .fla―Idea of Flash Creation
    .fla―Idea of Flash Creation

    上の本でFlash8の基本を身に付けて、それをどう面白い表現に落とし込むかを学べます。深津さんの、試行錯誤・実験しやすいスクリプティング、クラス設計に凄さを感じました。YouTubeやFlickrのAPI、PHPとの連携記事も。
  • FLASH ActionScript 2.0入門完全ガイド+実践サンプル集 [CD-ROM付]
    FLASH ActionScript 2.0入門完全ガイド+実践サンプル集 [CD-ROM付]

    ここまでで表現力が付き、テンションが上がるので、その勢いで難解なオブジェクト指向に挑戦。プログラム経験のない人がいきなり英語のOOP本を読むのは厳しい。この本で継承とかインターフェースとかポリモーフィズムとかの用語を理解しておくといいかも。
  • オブジェクト指向でなぜつくるのか―知っておきたいプログラミング、UML、設計の基礎知識―
    オブジェクト指向でなぜつくるのか―知っておきたいプログラミング、UML、設計の基礎知識―

    Flashの本ではありませんが、OOPの概念を気軽に読めるボリュームで解説してくれます。英語と日本語のOOP用語の対応を図るためにも「Object-oriented Actionscript for Flash 8」と併読するのがおすすめ。なんとなく読んでおくだけでも結構違うのでは。
  • Object-oriented Actionscript for Flash 8
    Object-oriented Actionscript for Flash 8

    前半はOOPの利便性や基本の紹介。デザインパターンやMVCの理解。13章からグッと難しくなって大変。Flash8対応。
  • Essential Actionscript 2.0
    Essential Actionscript 2.0

    上の本よりもさらにOOPプログラマ向け。同じOOP本ということでやや重複しており、こちらはMX2004時代の本なので見送ってもいいかも。分かりやすい英語で良著。この本のAS3版が出たら間違いなく買い。

Page Top