Youtube検索をFlex+Wiiコンで

ちょいとYoutube検索をWiiコンを使って遊んでみました。
実際の動作ムービーはこちら
http://jp.youtube.com/watch?v=x11jj5uftY8
今回気をつけたところは、マウスクリックイベントの手動作成です。
本来ならマウスでクリックやカーソルの移動を行うところをWiiコントローラーでそれを実現してます。
やり方は簡単で、適当にスプライトを作成し、Wiiコントローラーの移動量に応じてスプライトを移動させます。回転量検出でもOKですが、今回はせっかくなので赤外線センサーで距離を測定させています。
ir.x1とir.y1がwiiコンとの距離になります。x2,y2も使うと三角形を使って詳細な距離が出せると思います。

ポイントの移動

point.x = 800 - int(wiimote.ir.x1*800);
point.y = int(wiimote.ir.y1*800);

マウスクリックイベントの手動作成方法(dispatchEventとMouseEventを組み合わせるとできるらしい)

planeArr[i].container.dispatchEvent( new MouseEvent(MouseEvent.CLICK , true , false  , 0  , 0 ) );

それでは、Wiiコントローラーを使ってFlashと連携する方法の簡単な説明です。
おすすめのセンサー
これがあると,x1y1,x2y2として、移動量がわかります。
センサーがなくても回転量はデフォルトで測定できます。
USBで動作するので電池がいらず便利です。。
さらにボタン電池を入れると真中に時計も表示されるので、なかなかいいです。

CYBER・2WAYセンサーバー (Wii用)

CYBER・2WAYセンサーバー (Wii用)

BlueToothと赤外線を認識させる
パソコンのBlueToothソフトを使用して、まずはwiiコントローラをパソコンに認識させます。
その際、赤外線もONしておいたほうがいい感じです。

パソコンのBluetoothを待ち受け状態にしてWiiコントローラの赤い認識用ボタンを押します。

こんな感じにしておくと認識しやすいです。

次にWiiFlashを使って、Flashとコネクトできるようにします。
http://www.wiiflash.org/
#新しいバージョン0.4が出てました。
うまく認識できれば 1 Wiimote(s) found っと表示されます。
もしうまく認識されない場合は、余計なUSB機器をはずしてBluetoothの認識から始めるといいと思います。
全体のソースコードはこち
整理してなくて申し訳ないです(汗

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()" backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#FFFFFF, #848AC2]">
<mx:Script>
<![CDATA[
import mx.containers.Canvas;
import org.wiiflash.events.ButtonEvent;
import org.wiiflash.Wiimote;
import org.papervision3d.cameras.FreeCamera3D;
import org.papervision3d.scenes.MovieScene3D;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.materials.BitmapFileMaterial;
import org.papervision3d.objects.Plane;
import mx.core.Container;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.scenes.Scene3D;
import caurina.transitions.*;
private var scene:MovieScene3D;
private var camera:FreeCamera3D;
private var container:Sprite;
private var wiimote:Wiimote = new Wiimote();
private function init():void{
    wiimote.addEventListener( Event.CONNECT, onWiimoteConnect );
    wiimote.connect();
    youtubeS.send({
        "word":"ハルヒ"
    });
}
private function testClick( e:MouseEvent ):void{
    myLog.text += "Click";
}
private function onWiimoteConnect( event:Event ):void{
    wiimote.addEventListener( ButtonEvent.A_PRESS, onAPress );
    wiimote.addEventListener( ButtonEvent.A_RELEASE, onARelease );
    wiimote.addEventListener( ButtonEvent.B_PRESS , onBPress );
    wiimote.addEventListener(ButtonEvent.HOME_PRESS , onHomePress);
}
private function onAPress( event:ButtonEvent ): void{
//    wiimote.rumbleTimeout = 500;
//    wiimote.rumble = true; //Wiiリモコンを振動させる
    onReset();
    myLog.text += "A press" ;
}
private function onBPress( event:ButtonEvent ): void{
//    wiimote.rumbleTimeout = 500;
//    wiimote.rumble = true; //Wiiリモコンを振動させる
    onSeiretu();
    myLog.text += "B press" ;
}
private function onARelease( event: ButtonEvent ): void{
    wiimote.rumble = false;
}
private function onHomePress( event: ButtonEvent ): void{
    var i:int = 0;
    var len:int = planeArr.length;
    for(  i = 0 ; i < len ; i++ ){
        if( planeArrHit[i] == true ){
            planeArr[i].container.dispatchEvent( new MouseEvent(MouseEvent.CLICK , true , false  , 0  , 0 ) );
            myLog2.text += "true =>" + i +"\n";
        }
    }
}
private function onMouseMove(e:MouseEvent):void{
}
private var point:Canvas;
private function makePoint():void{
    point = new Canvas();
    point.graphics.beginFill(0xff0000 , 1 );
    point.graphics.drawRoundRectComplex(10 , 10 , 20 , 20 , 3, 3, 3, 3 );
    point.graphics.endFill();
    myImage.addChild( point );
}
private var names:Array = [
      "linear",
      "easeinquad",    "easeoutquad",    "easeinoutquad",    "easeoutinquad",
      "easeincubic",   "easeoutcubic",   "easeinoutcubic",   "easeoutincubic",
      "easeinquart",   "easeoutquart",   "easeinoutquart",   "easeoutinquart",
      "easeinquint",   "easeoutquint",   "easeinoutquint",   "easeoutinquint",
      "easeinsine",    "easeoutsine",    "easeinoutsine",    "easeoutinsine",
      "easeincirc",    "easeoutcirc",    "easeinoutcirc",    "easeoutincirc",
      "easeinexpo",    "easeoutexpo",    "easeinoutexpo",    "easeoutinexpo",
      "easeinelastic", "easeoutelastic", "easeinoutelastic", "easeoutinelastic",
      "easeinback",    "easeoutback",    "easeinoutback",    "easeoutinback",
      "easeinbounce",  "easeoutbounce",  "easeinoutbounce",  "easeoutinbounce"
    ];
private var planeArr:Array;
private var p:Plane;
private function onFinish():void{
    //3Dシーンの作成
    makePoint();
    makeScene();
//    myLog.text += "" + youtubeS.lastResult;
    var i:int = 0;
    var len:int = youtubeS.lastResult.item.length();
    planeArr = new Array();
    for( i = 0 ; i < len ; i ++ ){
        var imageFile:String = youtubeS.lastResult.item[i].img;
        myLog.text += imageFile + "\n";
        var material:BitmapFileMaterial = new BitmapFileMaterial(imageFile);
        material.doubleSided = true;
        planeArr[i] = new Plane( material , 300 , 300 , 0 , 0 , null );
        planeArr[i].x = Math.random()*360;
        planeArr[i].y = Math.random()*360;
        planeArr[i].z = Math.random()*360;
        planeArr[i].rotationX = Math.random()*100;
        planeArr[i].rotationY = Math.random()*100;
        planeArr[i].rotationZ = Math.random()*100;
        scene.addChild(planeArr[i]);
        planeArr[i].container.alpha = 0.9;
        planeArr[i].container.name = i;
        planeArr[i].container.addEventListener(MouseEvent.CLICK , onClick );
    }
}
//アイテム選択時
private function onClick(e:MouseEvent=null):void{
    var i:int = e.currentTarget.name;
    var plane:Plane = planeArr[i];
    var target:DisplayObject3D = new DisplayObject3D();
    target.copyTransform(plane);
    target.moveBackward(100);
    myLog.text += "x=>" + target.x +" y=>"+ target.y +" z=>"+ target.z +"\n"
    Tweener.addTween( camera , {
        zoom:1,
        x:target.x,
        y:target.y,
        z:target.z,
        rotationX:plane.rotationX,
        rotationY:plane.rotationY,
        rotationZ:plane.rotationZ,
        time:2,
        transition    :"easeOutExpo"
    });
    Tweener.addTween( planeArr[i] , {
        rotationZ : 360,
        time:1,
        transition    :"easeInOutBack"
    });
    Tweener.addTween( planeArr[i].container , {
        alpha:1.0,
        width:600,
        height:500,
        time:1,
        transition    :"easeInOutBack"
    });
    plane.container.filters = [myGlow];
}
//リセット
private function onReset():void{
    Tweener.addTween( camera , {
        zoom:0,
        focus:300,
        x:0,
        y:0,
        z:-1000,
        rotationX:0,
        rotationY:0,
        rotationZ:0,
        time:1,
        transition    :"easeInOutBack"
    });
    var i:int = 0;
    var len:int = planeArr.length;
    for( i = 0 ; i < len ; i ++ ){
        planeArr[i].container.width = 300;
        planeArr[i].container.height = 300;
        planeArr[i].container.filters = [];
    }
    for( i = 0 ; i < len ; i ++ ){
        Tweener.addTween( planeArr[i] , {
            x:Math.random()*360*3,
            y:Math.random()*360*3,
            z:Math.random()*360*3,
            rotationX:Math.random()*60,
            rotationY:Math.random()*60,
            rotationZ:Math.random()*60,
            time:1,
            transition    :"easeInOutBack"
        });
    }
    myLog.text += "x=>" + camera.x + " y=>" + camera.y + " z=>" +camera.z + "\n";
    myLog.text += "zoom=>" + camera.zoom + " focus=>" + camera.focus + "\n";
    myLog.text += "rx=>" + camera.rotationX + " ry=>" + camera.rotationY + " rz=>" +camera.rotationZ + "\n";
}
//整列
private function onSeiretu():void{
    Tweener.addTween( camera , {
        zoom:1,
        focus:300,
        x:0,
        y:0,
        z:-1000,
        rotationX:0,
        rotationY:0,
        rotationZ:0,
        time:1,
        transition    :"easeInOutBack"
    });
    var i:int = 0;
    var len:int = planeArr.length;
    for( i = 0 ; i < len ; i ++ ){
        planeArr[i].container.width = 300;
        planeArr[i].container.height = 300;
        planeArr[i].container.filters = [];
    }
    for( i = 0 ; i < len ; i ++ ){
        var yoko:int = i%4;
        var tate:int=int(i/4);
        Tweener.addTween( planeArr[i] , {
            x:tate*310-400,
            y:yoko*310-400,
            z:150,
            rotationX:0,
            rotationY:0,
            rotationZ:0,
            time:1,
            transition    :"easeInOutBack"
        });
    }
//    myLog.text = "x=>" + camera.x + " y=>" + camera.y + " z=>" +camera.z + "\n";
//    myLog.text += "zoom=>" + camera.zoom + " focus=>" + camera.focus + "\n";
//    myLog.text += "rx=>" + camera.rotationX + " ry=>" + camera.rotationY + " rz=>" +camera.rotationZ + "\n";
}
private function makeScene():void{
    // 新しいスプライトを作って表示リストに入れておく。
    container        = new Sprite();
    container.x      = myImage.width / 2;
    container.y      = myImage.height / 2;
    myImage.addChild(container);
    // シーンを作る。
    scene = new MovieScene3D(container);
    // カメラを作る。
    camera       = new FreeCamera3D(1,300);
//    myLog.text = "x=>" + camera.x + " y=>" + camera.y + " z=>" +camera.z + "\n";
//    myLog.text += "zoom=>" + camera.zoom + " focus=>" + camera.focus + "\n";
//    myLog.text += "rx=>" + camera.rotationX + " ry=>" + camera.rotationY + " rz=>" +camera.rotationZ + "\n";
    // タイマーイベント作成
//    this.addEventListener(Event.ENTER_FRAME , myTimer );
    var timer:Timer = new Timer(20);
    timer.addEventListener(TimerEvent.TIMER , myTimer );
    timer.start()
}
//レンダラ
private var radian:Number = 0;
private function myTimer(e:TimerEvent):void{
    scene.renderCamera(camera);
    Tweener.addTween( camera , {
        rotationX : int( wiimote.sensorY*45),
        rotationZ : int( wiimote.sensorZ*45)-45,
        zoom      : 1-int( wiimote.sensorY*2),
        time:2
    });
    point.x = 800 - int(wiimote.ir.x1*800);
    point.y = int(wiimote.ir.y1*800);
    myLog.text  = "x=>" + wiimote.sensorX + "\ny=>" + wiimote.sensorY + "\nz=>" + wiimote.sensorZ + "\n";
    myLog.text += "x1=>" + wiimote.ir.x1 +  "\ny1=>" + wiimote.ir.y1 +  "\nx2=>" + wiimote.ir.x2 +  "\ny2=>" + wiimote.ir.y2 + "\n";
//    var e2:MouseEvent = new MouseEvent(MouseEvent.CLICK,true,false,point.x , point.y , null , false,false,false);
    var i:int = 0;
    var len:int = planeArr.length;
    myLog.text = "";
    for(  i = 0 ; i < len ; i++ ){
        planeArrHit[i] = planeArr[i].container.hitTestPoint( point.x , point.y );
        myLog.text +="i=>"+ i + " "+ planeArrHit[i] + "\n";
    }
}
private var planeArrHit:Array = new Array();
private function toRadian(angle:Number ):Number{
    return (angle /360 * Math.PI * 2 );
}
]]>
</mx:Script>
<mx:GlowFilter id="myGlow" blurX="20" blurY="20" color="0x0000ff" alpha="0.8" />
<mx:HTTPService id="youtubeS" url="http://moeten.info/maidcafe/?m=moesearch_new&amp;type=youtube&amp;ptype=xml" useProxy="false" method="GET"
    resultFormat="e4x" result="onFinish()" fault="//" />
<mx:Image id="myImage" x="10" y="10" width="730" height="567"/>
<mx:Button x="674" y="19" label="リセット" click="onReset();"/>
<mx:Button x="674" y="49" label="整列" click="onSeiretu();"/>
<mx:TextArea id="myLog" x="748" y="10" width="333" height="275" backgroundAlpha="0.1"/>
<mx:TextArea x="748" y="293" width="333" height="275" id="myLog2" backgroundAlpha="0.1"/>
</mx:Application>