- 2007-09-02 23:10
- papervision3d
Papervision3D Rev1.5で複数のオブジェクトにマウスイベントを設置する方法にはちょっとしたテクニックが必要です。ライブラリとしての設計不足な気もしますが、まだまだ若いライブラリなので、これから改善されていく事でしょう。
まず、1つ目に大切なのはシーンの作成です。今まで私のエントリではScene3Dというクラスを使って3D環境となるシーンを作ってきました。しかし、これでは複数のオブジェクトにマウスイベントを付ける事ができません。
これはScene3Dのソースコードからも明らかです。これは是非改善してほしい点ですが、Rev1.5ではMovieScene3Dで複数オブジェクトにマウスイベントを設置できるので、今回はこれを使います。
container = new Sprite(); addChild(container); scene = new MovieScene3D(container);
今回は前回のエントリで作った文字オブジェクトを利用します。
文字オブジェクトを作るために必要なマテリアルを生成するメソッドはこうです。
private function get_clip(text:String, color:Number):MovieClip { var format:TextFormat = new TextFormat("Impact", obj_h, color); var txt_field:TextField = new TextField(); var mc:MovieClip = new MovieClip(); txt_field.text = String(text); txt_field.height = obj_h; txt_field.setTextFormat(format); format.align = TextFormatAlign.CENTER; mc.addChild(txt_field); return mc; }
引数に文字列と色を指定すると、そのマテリアルを生成するためのMovieClipを返します。
これを使って文字マテリアルを作ります。
var mc:MovieClip = get_clip(i.toString(), GRAY); material = new MovieMaterial(mc, true);
このマテリアルを利用してオブジェクトを作成します。
obj = new Plane(material, obj_w, obj_h, obj_segw, obj_segh);
これらの詳細は前回のエントリ「Papervision3DのMovieMaterialを使ってテクスチャを生成する方法」を参照下さい。
2つ目に大切なことは、マウスイベントを取得したいオブジェクトは全て3Dシーン内に設置する必要があるということです。これだと、多重構造のオブジェクトはマウスイベントが取得できない事になります。これについても是非改善してほしい所です。
obj = new Plane(material, obj_w, obj_h, obj_segw, obj_segh); scene.addChild(obj);
3Dシーンに設置したオブジェクトにマウスイベントを設定します。
オブジェクトが持つコンテナにマウスイベントを付ける必要があります。
obj.container.addEventListener(MouseEvent.CLICK, mouse_click);
あとはmouse_clickという関数を作るだけです。今回はクリックされたオブジェクトの色を変化させることにします。
if(name == "gray") { mc = get_clip(num.toString(), BLACK); plane.material = new MovieMaterial(mc, true); plane.name = "black"; } else { mc = get_clip(num.toString(), GRAY); plane.material = new MovieMaterial(mc, true); plane.name = "gray"; }
オブジェクトの色は簡単にオブジェクトの名前から判別するようにしています。
名前が”black”なら色をGRAY(0xcccccc)に設定し、”gray”ならBLACK(0×999999)に設定します。
上のフラッシュ動画の各オブジェクトをクリックしてみて下さい。色が変化するはずです。
ソースコードを公開しておきます。
package { import flash.display.*; import flash.events.*; import flash.display.Sprite; import org.papervision3d.core.proto.*; import org.papervision3d.scenes.MovieScene3D; import org.papervision3d.objects.Plane; import org.papervision3d.materials.MovieMaterial; import org.papervision3d.cameras.Camera3D; import flash.text.TextField; import flash.text.TextFormat; import flash.text.TextFormatAlign; [SWF( backgroundColor="0xffffff", frameRate="45" )] public class MyPlanes extends Sprite { //each object parameters private var obj_w :int = 240; private var obj_h :int = 320; private var obj_segw :int = 1; private var obj_segh :int = 1; //global parameters private var obj_num :int = 10; private var radius :int = 1000; private var degree :Number = 0.0; private var GRAY :Number = 0xcccccc; private var BLACK :Number = 0x999999; //global object private var container :Sprite; private var scene :SceneObject3D; private var camera :CameraObject3D; private var objs :Array; //--------------------------------------------Constructor public function MyPlanes() { //ステージ this.stage.quality = "MEDIUM"; this.stage.scaleMode = "noScale"; this.stage.align = StageAlign.TOP_LEFT; this.stage.addEventListener(Event.ENTER_FRAME, loop); this.stage.addEventListener(Event.RESIZE, resize); //コンテナ生成 container = new Sprite(); container.x = this.stage.stageWidth / 2; container.y = this.stage.stageHeight / 2; addChild(container); //シーン生成 scene = new MovieScene3D(container); //オブジェクトの生成 objs = new Array(obj_num); for(var i:int=0; i < obj_num; i++) { var pos_deg:Number = i * 360 / obj_num; var pos_rad:Number = Math.PI * pos_deg / 180; var mc:MovieClip = get_clip(i.toString(), GRAY); var obj:Plane; var material:MaterialObject3D; material = new MovieMaterial(mc, true); obj = new Plane(material, obj_w, obj_h, obj_segw, obj_segh); scene.addChild(obj); obj.x = radius * Math.cos(pos_rad); obj.z = radius * Math.sin(pos_rad); obj.name = "gray"; obj.extra = pos_rad; //original position obj.container.name = String(i); obj.container.addEventListener(MouseEvent.CLICK, mouse_click); objs[i] = obj; } //カメラ設定 camera = new Camera3D(); camera.z = -radius * 1.1; camera.y = obj_w / 2; camera.zoom = 1.1; this.stage.addEventListener(Event.ENTER_FRAME, loop); this.stage.addEventListener(Event.RESIZE, resize); resize(null); } //-------------------------------------------get_clip private function get_clip(text:String, color:Number):MovieClip { var format:TextFormat = new TextFormat("Impact", obj_h, color); var txt_field:TextField = new TextField(); var mc:MovieClip = new MovieClip(); txt_field.text = String(text); txt_field.height = obj_h; txt_field.setTextFormat(format); format.align = TextFormatAlign.CENTER; mc.addChild(txt_field); return mc; } //-------------------------------------------mouse_click private function mouse_click(e:Event):void { var num:int = Number(e.currentTarget.name); var plane:Plane = objs[num]; var name:String = plane.name; var mc:MovieClip; if(name == "gray") { mc = get_clip(num.toString(), BLACK); plane.material = new MovieMaterial(mc, true); plane.name = "black"; } else { mc = get_clip(num.toString(), GRAY); plane.material = new MovieMaterial(mc, true); plane.name = "gray"; } } //--------------------------------------------------loop private function loop(e:Event):void { var root_rad :Number = Math.PI * degree / 180; var rad :Number; var rot :Number; for each(var plane:Plane in objs) { rad = root_rad + plane.extra; rot = 45 * Math.sin(2 * rad); plane.x = radius * Math.cos(-rad); plane.z = radius * Math.sin(-rad); } degree += 0.3; //再レンダリング scene.renderCamera(camera); } //-------------------------------------------------stage private function resize(e:Event):void { container.x = this.stage.stageWidth / 2; container.y = this.stage.stageHeight / 2; camera.focus = this.stage.stageWidth / 6; } } }
Papervision3Dの複数オブジェクトにマウスイベントを設置するには少しテクニックが必要であることが分かりました。しかし、回避策が存在しますので、現時点ではそれを選択することで柔軟性は低いものの不可能ではありません。これからのPapervision3Dの改善に期待したいものです。
Comments:0
Trackbacks:0
- Trackback URL for this entry
- http://www.adamrocker.com/blog/154/papervision3d_many_o.html/trackback/
- Listed below are links to weblogs that reference
- Papervision3Dで複数のオブジェクトにマウスイベントを付ける方法 from throw Life
