yoppa.org


Web動画表現 2010

AS3によるインタラクション – マウスによるインタラクション 1 : マウスの位置を検知する

インタラクションとは

これまでのサンプルは、プログラムを実行すると、静止画であってもアニメーションであっても、ユーザがプログラムを終了するまではプログラムされた通りに自動的に再生されていました。言い換えると、このプログラムにユーザが介入する要素は、プログラムの起動と終了のみと言えるでしょう。

Flashでは、様々な手段でプログラムを実行している最中にも、ユーザがプログラムに対して介入することが可能です。ユーザがアクションを起こし、それに反応してプログラムは何らかのリアクションをする。ユーザはさらにその反応を見て、別のアクションを起こす。そうした、2つ以上の要素(この場合は、人間とコンピュータ上で動いているプログラム)の相互作用のことを、インタラクション(interaction)と呼びます。

プログラムにインタラクションを付加することで、より意外性に富んだ豊かな表現が可能となります。また、インタラクションをデザインしていくことは、これまでの伝統的なデザインの枠を越えた、新たな領域と言えるでしょう。どのようにしたら、効果的なインタラクションを実現できるのか、どのようにデザインすれば自然なインタラクションが生まれるのか、といったようにまだまだ未知の領域が残された刺激的な世界が拡がっています。

マウスによるインタラクション

一口にマウスによるインタラクションといっても、マウスの位置とマウスボタンが押されているorいない、という組合せによって、様々なユーザの動作が存在します。このそれぞれの動作とFlashの状態を組み合わせることで、様々なインタラクションが実現できます。Flashで用いられるマウスの動作には以下のものがあげられます。

  • 現在のマウスカーソルの位置を検知 -mouseX、mouseY
  • マウスボタンが押された瞬間を検知 – MouseEvent.MOUSE_DOWN
  • 押されていたマウスボタンを離した瞬間を検知 – MouseEvent.MOUSE_UP
  • マウスカーソルを動かした瞬間を検知 – mouseEvent.MOUSE_MOVE
  • マウスカーソルがステージに配置されたオブジェクトと重なって瞬間を検知 – mouseEvent.MOUSE_OVER
  • マウスカーソルがステージに配置されたオブジェクトから離れた瞬間を検知 – mouseEvent.MOUSE_OUT

今日はこれらのマウスに関する状態を検知する機能から、マウスの位置を知るためのmouseX、mouseYに注目して学んでいきます。

スクリプトのテンプレート

今日の授業で使用するスクリプトのテンプレートです。まず、AS3形式のFlashファイルを用意し、ドキュメントクラスを「Main」に指定します。その上で下記のコードを新規に作成したActionScriptファイルにペーストして、ファイル名を「Main.as」にしてFlaファイルと同じ場所に保存してください。

package {
  import flash.display.*;
  import flash.events.*;

  public class Main extends Sprite {
  //ここにグローバルな変数を記入

    public function Main() {
    //初期設定の項目を記入
           
      //フレーム更新のイベントリスナーの登録
      this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    }

    //イベントハンドラ
    function enterFrameHandler(event:Event):void {

    }
  }
}

マウスの位置を検知する 1

まず、一番簡単なマウスを利用したインタラクションとして、マウスの位置の検出を試してみましょう。まず、Flaファイル側でムービークリップシンボルを生成し、クラス名「Ball」という名前でリンケージを作成します。

では、まずはこのムービークリップBallの位置を、マウスカーソルの位置で移動してみましょう。マウスカーソルの位置を検知するには、mouseXとmouseYというプロパティを用います。画面全体(stage)から見たマウスカーソルの位置は、以下のように指定します。

  • stage.mouseX – 画面全体を基準としたマウスカーソルのX座標
  • stage.mouseY – 画面全体を基準としたマウスカーソルのX座標

このプロパティを画面に配置したムービークリップの(x, y)座標に代入すると、マウスカーソルの位置にムービクリップが移動します。

package 
{
    import flash.display.*;
    import flash.events.*;

    public class Main extends Sprite
    {
       //ここにグローバルな変数を記入
       var ball:Ball = new Ball();

       public function Main()
       {
           //初期設定の項目を記入
           this.addChild(ball);

           //フレーム更新のイベントリスナーの登録
           this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
       }

       //イベントハンドラ
       function enterFrameHandler(event:Event):void
       {
           ball.x = stage.mouseX;
           ball.y = stage.mouseY;
       }
    }
}
/wp-content/uploads/2010/11/webmov101201_01.swf, 400, 300

マウスの位置を検知 – マウスカーソルの位置で位置と大きさを変化させる

単純にマウスカーソルの位置とムービークリップの位置を一致させるだけでなく、ムービクリップの別のプロパティとマウスカーソルの位置を関連付けてみましょう。例えば、マウスカーソルのX座標の位置はムービクリップのX座標のままで、マウスカーソルのY座標はムービークリップのサイズに適用するように変化させてみましょう。

また、ムービクリップをもう1つ配置して、X座標を画面の中心で反転するように配置してみましょう。

package 
{
    import flash.display.*;
    import flash.events.*;

    public class Main extends Sprite
    {
        //ここにグローバルな変数を記入
        var ball1:Ball = new Ball();
        var ball2:Ball = new Ball();


        public function Main()
        {
            //初期設定の項目を記入
            this.addChild(ball1);
            this.addChild(ball2);

            //フレーム更新のイベントリスナーの登録
            this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }

        //イベントハンドラ
        function enterFrameHandler(event:Event):void
        {
            ball1.x = stage.mouseX;
            ball2.x = stage.stageWidth - stage.mouseX;
            ball1.y = stage.stageHeight / 2;
            ball2.y = stage.stageHeight / 2;
            ball1.scaleX = ball1.scaleY = stage.mouseY / stage.stageHeight;
            ball2.scaleX = ball2.scaleY =  1.0 - stage.mouseY / stage.stageHeight;
        }
    }
}
/wp-content/uploads/2010/11/webmov101201_02.swf, 400, 300

マウスの位置を検知 – カーソルを追いかける動き

マウスカーソルの位置を利用したインタラクションの応用例として、マウスカーソルの位置にすぐに移動するのではなく、すこし遅れたタイミングでなめらかな動きでカーソルを追い掛ける動きをつくってみましょう。

なめらかな動きを実現するために、マウスカーソルの座標と、現在のムービークリップの座標の差分をとって、常に一定の数値で割り算した値だけ移動するようにします。すると、物体は徐々に減速しながら限りなくカーソルの場所に近付いていくという動きになります。割り算する数値を調整すると、減速するスピードを変化させることが可能です。この動きは簡単な数式で効果的なので、多くのFlashサイトで見掛けます。

package 
{
    import flash.display.*;
    import flash.events.*;
    import flashx.textLayout.formats.Float;

    public class Main extends Sprite
    {
        //ここにグローバルな変数を記入
        var ball:Ball = new Ball();
        var interpolate:Number;


        public function Main()
        {
            //初期設定の項目を記入
            this.addChild(ball);
            interpolate = 0.1;

            //フレーム更新のイベントリスナーの登録
            this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }

        //イベントハンドラ
        function enterFrameHandler(event:Event):void
        {
            ball.x += (stage.mouseX - ball.x) * interpolate; 
            ball.y += (stage.mouseY - ball.y) * interpolate;
        }
    }
}
/wp-content/uploads/2010/11/webmov101201_03.swf, 400, 300

マウスの位置を検知 – カーソルを追いかける動きを沢山の物体で

応用例として、先週学んだ配列を利用して、カーソルをなめらかに追い掛ける動きを、たくさんの物体でやってみましょう。

package 
{
    import flash.display.*;
    import flash.events.*;
    import flashx.textLayout.formats.Float;

    public class Main extends Sprite
    {
        //ここにグローバルな変数を記入
        var balls:Array = new Array();
        var ballNum:Number;
        var interpolate:Number;


        public function Main()
        {
            //20コのボールを生成
            ballNum = 20;
            //ボールのパラメータを設定
            for (var i:int = 0; i < ballNum; i++)
            {
                var b:Ball = new Ball();
                b.alpha = 0.1;
                b.scaleX = b.scaleY = 3.0 - i / ballNum * 2.0;
                this.addChild(b);
                balls.push(b);
            }

            //フレーム更新のイベントリスナーの登録
            this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }

        //イベントハンドラ
        function enterFrameHandler(event:Event):void
        {
            //20コのボールが補完しながらカーソルを追う
            for (var i:int = 0; i < ballNum; i++)
            {
                balls[i].x += (stage.mouseX - balls[i].x) * 0.02 * (i + 1);
                balls[i].y += (stage.mouseY - balls[i].y) * 0.02 * (i + 1);
            }
        }
    }
}
/wp-content/uploads/2010/11/webmov101201_04.swf, 400, 300