calendar

S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930
<< November 2019 >>

categories

archives

Flashで3D基本編:ゴ愎瑤鮑遒辰討澆

0
    さていよいよ第五回目となりました日の出 今回は、再利用可能な「関数」にチャレンジしてみましょう。前回では、Tweenerで3Dオブジェクトを移動させるデモをやりました。でも、実際にプログラムを変更して実行した人は、「あれ?サイトのサンプル動画は繰り返し動いているのに、自分の環境では一回動いただけで終わってしまうな」と思ったに違いありません。そうです。実はサイトにアップしているサンプル動画は、Tweener部分を「関数化」していて、繰り返し呼び出していたのですひらめき


    関数とはどんなもの?

    関数という事についてもう少し、分かりやすく説明します。
    例えば、「カレーを作る」という作業をプログラムで考えてみましょう。やる事としては、

    ・材料を買ってくる
    ・お湯を沸かす
    ・野菜を切っていれる
    ・肉をいためていれる
    ・ルーを入れる
    ・弱火で煮込みながらかきまぜる

    自分はあんまり料理は得意ではありませんので手順が間違っているかもしれませんが、それは置いときましょうw と、とにかくプログラムで考えたら上記の6ステップを書かなければいけません。これ自体はいいんですが、たとえば、プログラムの中で「カレーを作る」という事が何度も何度も起こるような場合、その都度この6ステップを書くのは面倒です。仮にプログラム中に1000回「カレーを作る」作業が出てきたら、プログラム行数的には6000行同じようなことを書かなくてはいけなくなります冷や汗 そこで、この「カレーを作る」というのを関数化してみます。以下のような感じになります。

    function カレーを作る()
    {
     材料を買ってくる;
     お湯を沸かす;
     野菜を切っていれる;
     肉をいためていれる;
     ルーを入れる;
     弱火で煮込みながらかきまぜる;
    }


    こうしておくと、プログラム中で、

    カレーを作る();

    と書くだけで、このカレーを作る作業(6行)が実行されるのです。つまり、何度も利用されるような手続きを関数化すれば、プログラム行数はグッと減るし、間違いなども減るという事ですチョキ


    引数ってなに?

    更にもう少し突っ込んでみます。
    例えば、カレーの中に、野菜を入れない場合もあれば、肉を入れない場合もある、という事があったとします。
    単純に考えれば、入れる・入れないの組み合わせは2×2の4通りです。 このような場合、同じような関数を4つ作ってもいいんですが、プログラムでは、この組み合わせが4通りどころかもっと多くなることも往々にしてあります汗
    そこで登場するのが「引数」と呼ばれるものです。上記のように、関数自体にも、関数を呼ぶ方にも、最後に()が付いています。ここに「引数」を入れることで、引数の内容によって関数の動きを変える、という事ができるのです。
    さっきのカレーを作る関数を、引数によって動きを変えるように変更してみます。

    function カレーを作る(野菜入れる:Boolean, 肉入れる:Boolean)
    {
     材料を買ってくる;
     お湯を沸かす;

     if (野菜入れる == true) 野菜を切っていれる;
     if (肉入れる == true) 肉をいためていれる;

     ルーを入れる;
     弱火で煮込みながらかきまぜる;
    }


    :Booleanとなっているのは、「ブール型」といって、trueかfalseの値を入れる、という意味です。
    この状態で、

    カレーを作る(true, false);

    という形で関数を呼び出せば、野菜が入っていて、肉が入っていないカレーができあがる、という訳ですグッド



    という訳で、関数(function)とは?を簡単にまとめると、「再利用できる塊で、引数で動きを変えられる」というものです。

    では実際に、sample3d.asのTweener部分を関数化してみます。sample3d.asを次のように変更してみてください。

    package {
     import flash.display.Sprite;
     import org.papervision3d.materials.*;
     import org.papervision3d.materials.shadematerials.*;
     import org.papervision3d.objects.primitives.*;
     import org.papervision3d.lights.PointLight3D;
     import org.papervision3d.view.BasicView;
     import caurina.transitions.Tweener;

     public class sample3d extends BasicView
     {
      public function sample3d():void
      {
       var light = new PointLight3D;
       startRendering();

       var mat = new FlatShadeMaterial(light);
       var object = new Sphere(mat);
       scene.addChild(object);

       movePosition(object);
      }

      private function movePosition(parameter_object)
      {
       Tweener.addTween(parameter_object, {rotationX:360, rotationZ:720, time:4, transition:"linear"});
       Tweener.addTween(parameter_object, {x:-400, time:2, transition:"easeInOutSine"});
       Tweener.addTween(parameter_object, {x: 400, time:2, delay:2, transition:"easeInOutSine"});
      }

     }
    }

    ※コードをコピー&ペーストする場合は、左側のスペースが全角になっているので注意してください。

    頭についているprivateの意味はまだ覚えなくていいですが、簡単に説明すると「publicやprivateは他のasファイル(クラス)からでも呼び出せるかどうか」という意味です。movePositionというのが関数名で、parameter_objectという引数を受け取って処理を行います。引数で受け取ったparameter_objectをTweenerで動かすという事が書かれています。(関数内ではparameter_objectという呼び方をしていますが、その中身はobjectです。刑務所の中(関数の中)では囚人が番号で呼ばれるようなイメージ?です温泉)


    でも、これだけでは繰り返し関数は動きません。1回関数を呼び出しているだけだからです。
    じゃあ、

    movePosition(object);
    movePosition(object);
    movePosition(object);

    と書けば三往復するのか、というとそうではありません。Tweener処理は、「今から何秒数えて動かす」という処理ですので、
    3回いっぺんにTweenerをさせても、重なる秒の処理は上書きされてしまい、最後の一回分しか有効にならないのです。

    やりたいのは、「movePositionの処理が終わったタイミングで、再度movePositionを動かす」ということです。
    そこで登場するのが、Tweenerの「onComplete:function() { ... }」という引数です。これを指定すると、文字通り「処理が終わった時に実行する内容」を書けるのです。
    movePosition関数の内容を以下のように書き換えます。

    private function movePosition(parameter_object)
    {
     Tweener.addTween(parameter_object, {rotationX:360, rotationZ:720, time:4, transition:"linear"});
     Tweener.addTween(parameter_object, {x:-400, time:2, transition:"easeInOutSine"});
     Tweener.addTween(parameter_object, {x: 400, time:2, delay:2, transition:"easeInOutSine", onComplete:function() {
      parameter_object.rotationX = 0;
      parameter_object.rotationZ = 0;
      movePosition(parameter_object); }
    });
    }

    { }の中に{ }が入っている形ですので混乱しないようにしますw
    「Tweenerの処理が終わったときに、rotationを0にして、再度movePositionを動かす」という意味になります。
    これによって、movePositionは永久に実行され続けますジョギング


    今回はここまでです。
    関数については、はじめはなかなかピンと来ないと思いますが、こればっかりは「習うより慣れろ」という言葉が適切かと思われます。
    自分でいろいろ試しながら、身につけていくのがいいかと思われます。

    では植物

    コメント
    コメントする








       
    この記事のトラックバックURL
    トラックバック