//←↑→↓ボタンで操作オブジェクトを移動させます //← →で方向決定、↑で前進、↓で後退 //Vボタンでカメラ位置を上に変更(カメラのY軸座標増加) //Cボタンでカメラ位置を下に変更(カメラのY軸座標減少) //カメラが操作オブジェクトに合わせて移動、視点も操作オブジェクトに合わせます //移動すると手足を動かします package { import flash.display.Sprite; import flash.events.Event; import flash.events.KeyboardEvent; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.objects.primitives.Cylinder; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.view.Viewport3D; import org.papervision3d.scenes.Scene3D; import org.papervision3d.cameras.Camera3D; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.objects.DisplayObject3D; [SWF(width="500", height="500", frameRate="60", backgroundColor="#111111")] public class MovieFigure extends Sprite { private var container : Sprite; private var viewport : Viewport3D; private var scene : Scene3D; private var camera : Camera3D; private var wireFramMate : WireframeMaterial; private var materials : MaterialsList; private var planeObj : Plane; private var head : Sphere; //頭部 private var body : Cube; //胴体部 private var leftHand : Cylinder; //画面向かって左側手 private var rightHand : Cylinder; //画面向かって右側手 private var leftFoot : Cylinder; //画面向かって左側足 private var rightFoot : Cylinder; //画面向かって右側足 private var renderer : BasicRenderEngine; private var planeSize : int = 2000; //Planeオブジェクト1辺の長さ private var status : int = 0; //操作オブジェクトの表示制御用ステータス private var rotat : Boolean = false; //Y軸回転判定 private var rotatNum : int = 0; //Y軸回転角度 private var wardMove : Boolean = false; //前進後退判定 private var wardMoveNum : int = 0; //前進後退速度 private var walkDispInterval : int = 0; //歩行表示間隔カウンター private const INTERVAL: int = 24; //歩行表示間隔 //MoviePaperPlaneクラスのコンストラクタ public function MovieFigure():void { //ビューポート生成 viewport = new Viewport3D(stage.stageWidth, stage.stageHeight); addChild(viewport); //シーン生成 scene = new Scene3D(); //レンダリングエンジン生成 renderer = new BasicRenderEngine(); //Planeオブジェクト用ワイヤーフレームマテリアル設定 wireFramMate = new WireframeMaterial(0x0000FF); //Planeオブジェクト生成 planeObj= new Plane(wireFramMate, planeSize, planeSize, 4, 4); planeObj.rotationX = 90; scene.addChild(planeObj); //操作用人型オブジェクトを作成 //胴体部オブジェクトを親として頭部・手足を子オブジェクトとして加えていく //胴体部をCubeオブジェクトで作成 materials = new MaterialsList( { all : new ColorMaterial(0xFF0000) } ); body = new Cube(materials, 150, 100, 160); body.y = 230; scene.addChild(body); //頭部をSphereでオブジェクト作成 head = new Sphere(new ColorMaterial(0xFF7700), 65, 8, 6); head.y = 150; body.addChild(head); //Cylinderオブジェクトで手足を作成 //画面向かって左側の手をCylinderオブジェクトで生成 leftHand = new Cylinder(new ColorMaterial(0xFF7700),20,130); leftHand.x = -110; leftHand.y = 10; body.addChild(leftHand); //画面向かって右側の手をCylinderオブジェクトで生成 rightHand = new Cylinder(new ColorMaterial(0xFF7700),20,130); rightHand.x = 110; rightHand.y = 10; body.addChild(rightHand); //画面向かって左側の足をCylinderオブジェクトで生成 leftFoot = new Cylinder(new ColorMaterial(0xFF7700),30,130); leftFoot.x = -50; leftFoot.y = -160; body.addChild(leftFoot); //画面向かって右側の足をCylinderオブジェクトで生成 rightFoot = new Cylinder(new ColorMaterial(0xFF7700),30,130); rightFoot.x = 50; rightFoot.y = -160; body.addChild(rightFoot); //カメラ設定 camera = new Camera3D(); camera.y = 200; camera.target = DisplayObject3D.ZERO; //イベント処理用リスナを設定 stage.addEventListener(Event.ENTER_FRAME, onEnterFrame); stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp); } //フレーム毎の処理 private function onEnterFrame(e:Event):void{ calcMove(); renderer.renderScene(scene, camera, viewport); } //設定された値をもとに操作オブジェクトの位置・表示を計算 //フレーム毎に呼び出される private function calcMove():void{ //← →ボタンが押され続けている間、操作オブジェクトを回転させる if(rotat) { body.rotationY += rotatNum; } //↑ ↓ボタンが押され続けている間、操作オブジェクトを前進・後退させる if(wardMove) { body.moveForward(wardMoveNum); } //walkDispInterval: //操作ボタン押下時は1の値、 //操作ボタン押下継続中は1以上の値、 //操作ボタンリリース時は0を設定 //操作ボタンの最初の押下時の歩行表示を行う if(walkDispInterval == 1) { //歩行表示 ctrlWaklDisp(); } //操作ボタン押下継続の間、指定した間隔で歩行表示 if((rotat || wardMove) && walkDispInterval >= 1) { //いずれかの操作ボタン押下継続時に歩行表示カウンタをカウントアップ walkDispInterval++; //指定したインターバルを経過時に歩行表時 if(walkDispInterval > INTERVAL) { //歩行表示 ctrlWaklDisp(); //歩行表示カウンタを2にもどす(1にもどした場合上記の最初の押下時処理を必ず通り表示がおかしくなるため) walkDispInterval = 2; } } //カメラ視点設定 setCamera(); } //カメラ視点設定 private function setCamera():void{ camera.x=-1000*Math.cos((90-body.rotationY)*Math.PI/180)+body.x; camera.z=-1000*Math.sin((90-body.rotationY)*Math.PI/180)+body.z; camera.target.x=body.x; camera.target.y=body.y; camera.target.z=body.z; } //キーボードを押したときの処理 //←↑→↓ボタン押下時処理(操作オブジェクト移動のための設定) //V、Cボタン押下時処理(カメラ視点変更処理) private function onKeyDown(event:KeyboardEvent):void{ //←ボタンDOWN 左回転の設定 if (event.keyCode == 37) { rotat = true; rotatNum = -5; //操作ボタン押下時の値:1を設定 if(walkDispInterval < 1) { walkDispInterval = 1; } //→ボタンDOWN 右回転の設定 } else if (event.keyCode == 39) { rotat = true; rotatNum = 5; if(walkDispInterval < 1) { walkDispInterval = 1; } //↑ボタンDOWN 前進の設定 } else if (event.keyCode == 38) { wardMove = true; wardMoveNum = 10; if(walkDispInterval < 1) { walkDispInterval = 1; } //↓ボタンDOWN 後退の設定 } else if (event.keyCode == 40) { wardMove = true; wardMoveNum = -5; if(walkDispInterval < 1) { walkDispInterval = 1; } //Vボタン カメラ位置が上になっていく(カメラY軸座標増加) } else if (event.keyCode == 86) { } else if (event.keyCode == 86) { if (camera.y < 600) {camera.y += 100;} //Cボタン カメラ位置が下になっていく(カメラY軸座標減少) } else if (event.keyCode == 67) { if (camera.y > 0) {camera.y -= 100;} } } //キーボードを離したときの処理 //←↑→↓ボタンリリース時処理(操作オブジェクト移動のための設定解除) private function onKeyUp(event:KeyboardEvent):void{ //←ボタンUP 左回転の設定設定解除 if (event.keyCode == 37) { rotat = false; //操作ボタンリリース時の値:0を設定 他の操作ボタン押下中には設定しない if(!rotat && !wardMove) { walkDispInterval = 0; } //→ボタンUP 右回転の設定設定解除 } else if (event.keyCode == 39) { rotat = false; if(!rotat && !wardMove) { walkDispInterval = 0; } //↑ボタンUP 前進の設定設定解除 } else if (event.keyCode == 38) { wardMove = false; if(!rotat && !wardMove) { walkDispInterval = 0; } //↓ボタンUP 後退の設定設定解除 } else if (event.keyCode == 40) { wardMove = false; if(!rotat && !wardMove) { walkDispInterval = 0; } } } //捜査対象オブジェクトの手足表示を制御 private function ctrlWaklDisp():void{ //status:操作オブジェクトの表示制御用ステータス //0:直立 //1:左手、右足前方&右手、左足後方 //2:左手、右足後方&右手、左足前方 //前進・後退時は1と2の状態を交互に繰り返す //直立状態(0)からは(1)の状態へ遷移 if (status == 0) {status = 1;} //(1)の状態をセット後、ステータスを(2)に変更 if (status == 1) { //左手、右足前方 leftHand.z = 70; leftHand.rotationX = -40; rightFoot.rotationX = -30; //右手、左足後方 rightHand.z = -70; rightHand.rotationX = 40; leftFoot.rotationX = 30; status = 2; //(2)の状態をセット後、ステータスを(1)に変更 } else if (status == 2) { //左手、右足後方 leftHand.z = -70; leftHand.rotationX = 40; rightFoot.rotationX = 30; //右手、左足前方 rightHand.z = 70; rightHand.rotationX = -40; leftFoot.rotationX = -30; status = 1; } } } } Papervision3DTest08 :人型操作オブジェクトを追尾するカメラ