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で動作するので電池がいらず便利です。。
さらにボタン電池を入れると真中に時計も表示されるので、なかなかいいです。
- 出版社/メーカー: サイバーガジェット
- 発売日: 2008/02/19
- メディア: Video Game
- 購入: 2人 クリック: 47回
- この商品を含むブログ (3件) を見る
パソコンの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&type=youtube&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>