Papervision3DTest10 :人型操作オブジェクト+複数視点追尾カメラ

by siouxcitizen forked from Papervision3DTest09 :人型操作オブジェクトを追尾するカメラ(Bダッシュつき) (diff: 117)
★★★ 操作オブジェクトについて :★★★★★★★★★★★★★★★★★★★★★
←↑→↓ボタンで操作オブジェクトを移動させます
← →で方向決定、↑で前進、↓で後退
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
★★★ 移動状態について :★★★★★★★★★★★★★★★★★★★★★★★★
移動すると手足を動かします
Bボタン押しながら前進・後退で移動速度3倍(手足を動かす速さは変わらず。。。)
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
★★★ カメラについて :★★★★★★★★★★★★★★★★★★★★★★★★★★
W、Sボタンでカメラ位置を上下に変更(カメラのX軸回転を行います)
A、Dボタンで操作オブジェクトを中心にカメラが回転します(カメラのY軸回転を行います)
Aで移動オブジェクトを中心にして左回転、Dでは右回転します
Fボタンで移動オブジェクトからのカメラの距離が変わります
Rボタンでデフォルトのカメラ設定にもどる(と思います。。。)
カメラが操作オブジェクトに合わせて移動、視点も操作オブジェクトに合わせます
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
♥0 | Line 247 | Modified 2009-04-10 07:19:00 | MIT License
play

ActionScript3 source code

/**
 * Copyright siouxcitizen ( http://wonderfl.net/user/siouxcitizen )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/cBVs
 */

// forked from hacker_7daxapax's Papervision3DTest09 :人型操作オブジェクトを追尾するカメラ(Bダッシュつき)

//★★★ 操作オブジェクトについて :★★★★★★★★★★★★★★★★★★★★★
//←↑→↓ボタンで操作オブジェクトを移動させます
//← →で方向決定、↑で前進、↓で後退
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

//★★★ 移動状態について :★★★★★★★★★★★★★★★★★★★★★★★★
//移動すると手足を動かします
//Bボタン押しながら前進・後退で移動速度3倍(手足を動かす速さは変わらず。。。)
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

//★★★ カメラについて :★★★★★★★★★★★★★★★★★★★★★★★★★★
//W、Sボタンでカメラ位置を上下に変更(カメラのX軸回転を行います)
//A、Dボタンで操作オブジェクトを中心にカメラが回転します(カメラのY軸回転を行います)
//Aで移動オブジェクトを中心にして左回転、Dでは右回転します
//Fボタンで移動オブジェクトからのカメラの距離が変わります
//Rボタンでデフォルトのカメラ設定にもどる(と思います。。。)
//カメラが操作オブジェクトに合わせて移動、視点も操作オブジェクトに合わせます
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

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; //歩行表示間隔
        private var bDash : Boolean = false; //Bダッシュ判定
        
        private var cameraYRotStat : int = 0; //カメラのY軸回転状態 0~3 
        private var cameraXRotStat : int = 0; //カメラのX軸回転状態 0~3 
        private var cameraPitch: int = 0; //カメラのX軸回転の値 
        private var cameraYaw : int = 0; //カメラのY軸回転の値 
        private var distStat: int = 1; //カメラ設置場所の距離種類 0~2 
                 
        //MovieFigureクラスのコンストラクタ
        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) {
               //Bボタンが押されていないときの前進・後退は通常の移動速度
               if (!bDash) {
                   body.moveForward(wardMoveNum);
               //Bボタンが押されているときの前進・後退は通常の3倍速    
               } else {
                   body.moveForward(wardMoveNum*3);    
               }
               
            }
            
            //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{
            var cameraDist : int = -1000; //デフォルトの距離、ステータスは1
            if (distStat == 0) {
                cameraDist = -500;
            } else if (distStat == 1) {
                cameraDist = -1000;
            } else if (distStat == 2) {
                cameraDist = -1500;
            }
            
            //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.x=cameraDist*Math.cos((90-body.rotationY)*Math.PI/180)+body.x;  
            camera.z=cameraDist*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;
                        
            //カメラX軸回転設定
            if (cameraXRotStat == 0) {
                cameraPitch = 90; //デフォルトのカメラの高さ
            } else if (cameraXRotStat == 1) {
                cameraPitch = 70; //デフォルトより1段階高いのカメラの高さ
            } else if (cameraXRotStat == 2) {
                cameraPitch = 50; //デフォルトより2段階高いのカメラの高さ
            } else if (cameraXRotStat == 3) {
                cameraPitch = 100; //地面近いカメラの高さ
            }
            
            //カメラY軸回転設定
            if (cameraYRotStat == 0) {
                cameraYaw = 270; //デフォルト設定のための値がわからないので、便宜的に1回転してから元の位置に戻す。。。
            } else if (cameraYRotStat == 1) {
                cameraYaw = 0;
            } else if (cameraYRotStat == 2) {
                cameraYaw = 90;
            } else if (cameraYRotStat == 3) {
                cameraYaw = 180;
            }

            camera.orbit(cameraPitch, cameraYaw, true, body);
            
            //カメラのX軸回転(カメラの上下位置)
            //camera.orbit(50, yaw, true, body);//1番高いカメラ位置
            //camera.orbit(70, yaw, true, body);//2番目に高いカメラ位置
            //camera.orbit(90, yaw, true, body);//デフォルトのカメラの高さ
            //camera.orbit(100, yaw, true, body);//地面近いカメラの高さ
        
            //カメラのY軸回転設定 
            //操作オブジェクトのデフォルトの↑ボタン進行方向を上または北側として、
            //camera.orbit(90, 0, body);//右(または東側)から操作オブジェクトへの視点
            //camera.orbit(90, 90, body);//上(または北側)から操作オブジェクトへの視点
            //camera.orbit(90, 180, body);//左(または西側)から操作オブジェクトへの視点
            //camera.orbit(90, 270, body);//下(または南側)から操作オブジェクトへの視点(360度、一回転してデフォルト位置へもどる設定)
        }    
            
        
        //キーボードを押したときの処理
        //←↑→↓ボタン押下時処理(操作オブジェクト移動のための設定)
        //A、D、W、Sボタン押下時処理(カメラ視点変更処理)
        //F、Rボタン処理 F:カメラ距離変更 R:カメラ設定デフォルト
        //Bボタン処理 Bダッシュを行う
        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;
                }
            //Bボタン Bボタン押下中は前進・後退中の移動速度3倍
            } else if (event.keyCode == 66) {
                bDash= true;
            //Aボタン 操作オブジェクトを中心にカメラを左回り回転(Y軸回転)
            //90度づつ左回り回転 南→西→北→東→南 の順番でカメラ位置変更   
            } else if (event.keyCode == 65) {
                cameraYRotStat--;
                if(cameraYRotStat < 0) {cameraYRotStat = 3;}
            //Dボタン 操作オブジェクトを中心にカメラを右回り回転(Y軸回転)    
            //90度づつ右回り回転 南→東→北→西→南 の順番でカメラ位置変更   
            } else if (event.keyCode == 68) {
                cameraYRotStat++;
                if(cameraYRotStat > 3) {cameraYRotStat = 0;}
            //Wボタン 操作オブジェクトを中心にカメラを上下移動(X軸回転)
            } else if (event.keyCode == 87) {
                cameraXRotStat++;
                if(cameraXRotStat > 3) {cameraXRotStat = 0;}
            //Sボタン 操作オブジェクトを中心にカメラを上下移動(X軸回転)
            } else if (event.keyCode == 83) {
                cameraXRotStat--;
                if(cameraXRotStat < 0) {cameraXRotStat = 3;}
            //Fボタン カメラと操作オブジェクトの距離を変更
            } else if (event.keyCode == 70) {
                distStat -= 1;
                if(distStat < 0) {distStat = 2;}
            //Rボタン カメラの設定をデフォルトにもどす
            } else if (event.keyCode == 82) {
                distStat = 1;
                cameraXRotStat = 0;
                cameraYRotStat = 0;
            }
        }
        
        //キーボードを離したときの処理
        //←↑→↓ボタンリリース時処理(操作オブジェクト移動のための設定解除)
        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;
                }
            //BボタンUP Bダッシュ解除
            } else if (event.keyCode == 66) {
                bDash = false;
            }
        }
        
        //捜査対象オブジェクトの手足表示を制御
        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.z = 50;
                rightFoot.rotationX = -30;
                //右手、左足後方
                rightHand.z = -70;
                rightHand.rotationX = 40;
                leftFoot.z = -50;
                leftFoot.rotationX = 30;
                status = 2;
            //(2)の状態をセット後、ステータスを(1)に変更
            } else if (status == 2) {
                //左手、右足後方
                leftHand.z = -70;
                leftHand.rotationX = 40;
                rightFoot.z = -50;
                rightFoot.rotationX = 30;
                //右手、左足前方
                rightHand.z = 70;
                rightHand.rotationX = -40;
                leftFoot.z = 50;
                leftFoot.rotationX = -30;
                status = 1;
            }
        }
    }
}

Forked