Papervision3D でテクスチャぐるぐる PlaneWorld サンプル by Flex SDK をちょっと改造して、キーボードで移動操作できるようにしてみた。

方向キーとShiftキーを組み合わせて前後左右に移動可能。

画像は XB-LIM さん作の Pledge of BAHAMUT { FF3 ULTIMANIAc DATABASE } - ドラゴンクエストの世界地図 を利用しています。
The map image by XB-LIM (Pledge of BAHAMUT { FF3 ULTIMANIAc DATABASE } - The World maps of Dragon Quest)

Camera3D の視点移動がうまくいかない

カメラ(org.papervision3d.cameras.Camera3D)の位置をうまく変更することができないので、ルートノード (これが本当にルートノードになっているかちょっと確信がもてないが) を動かすことで解決している。

Camera3D#moveBackward
Camera3D#moveForward
Camera3D#moveLeft
Camera3D#moveRight

だと中心点(0,0,0)に向かって行ったり来たりするだけなのでパス。
もしかしたら 3Dオブジェクトをひとつ作って、そのオブジェクトを追いかけるように Camera3D#lookAt していけばうまくいくかもしれないが。

Papervision3D を弄ってみた(3)【閃光的網站・弛緩複合体 -Review Division-】 の「視点を動かす」という図がわかりやすい。

ソースコード(PlaneWorld.as)


package {
  import flash.display.*;
  import flash.events.*;
  import flash.text.*;
 
  import org.papervision3d.scenes.*;
  import org.papervision3d.objects.*;
  import org.papervision3d.cameras.*;
  import org.papervision3d.materials.*;
 
  public class PlaneWorld extends Sprite {
 
    private var container : Sprite;
    private var scene     : Scene3D;
    private var camera    : Camera3D;
    private var rootNode  : DisplayObject3D;
 
    // 画像ファイルのパス
    private var imageFilePath:String = "planeworld.png";
 
    // カメラ
    private var distance : Number = 10;
    private var angle    : Number = 0;
 
    public function PlaneWorld():void {
 
      // QUERY_STRINGパラメータ取得
      var param:Object = loaderInfo.parameters;
 
      // 画像ファイルのパスを指定
      if(param["imagefile"] != undefined){
        imageFilePath = param["imagefile"];
      }
 
      // リサイズに対応(swfをブラウザで直接ひらいているときとか)
      stage.addEventListener(Event.RESIZE, onStageResize);
 
      // キーボード操作
      stage.addEventListener(KeyboardEvent.KEY_DOWN, keydown);
 
      // 表示用の Sprite オブジェクトを生成
      container = new Sprite();
      container.x = 400 / 2; // at center : swf width  = 400
      //container.y = 400 / 2; // at center : swf height = 400
      container.y = 500;
      container.graphics.lineStyle(1.0, 0xFFFF00);
      container.graphics.drawCircle(0, 0, 100);
      container.graphics.lineStyle(1.0, 0xFF00FF);
      container.graphics.drawCircle(400, 400, 100);
 
      addChild(container);
 
      // シーンオブジェクトを作る
      scene = new MovieScene3D(container);
 
      // カメラオブジェクトを作る
      camera = new Camera3D();
      camera.x =    0;
      camera.y =  5;
      camera.z =  distance;
      camera.focus = 100;
      camera.zoom = 10;
      camera.sort = true;
 
      // ルートノードを作る
      rootNode = new DisplayObject3D();
      scene.addChild(rootNode);
 
      // 平面世界オブジェクトを作る
      rootNode.addChild(createWorld());
 
      scene.renderCamera(camera);
    }
 
    private function createWorld():DisplayObject3D{
 
      var material:BitmapFileMaterial = new BitmapFileMaterial(imageFilePath);
      material.doubleSided = true;
      material.lineColor = 0x00FF00;
      material.lineAlpha = 1;
 
      var planeSize:int = 400;
      var segment:int = 30;
 
      var p:Plane = new Plane(material, planeSize, planeSize, segment, segment);
      p.x =  0;
      p.y =  0;
      p.z =  0;
      p.rotationX = 90;
      return p;
    }
 
    private function keydown(event:KeyboardEvent):void {
 
      if(event.shiftKey){
        switch(event.keyCode) { // 37← 38↑ 39→ 40↓
          case 37:
            rootNode.x -= 1; // 左移動
            break;
          case 38:
            rootNode.z += 5; // 前進x5
            break;
          case 39:
            rootNode.x += 1; // →移動
            break;
          case 40:
            rootNode.z -= 5; // 後退x5
            break;
        }
      }else{
        switch(event.keyCode) { // 37← 38↑ 39→ 40↓
          case 37:
            rootNode.rotationY += 1; // 右回転
            break;
          case 38:
            rootNode.z += 1; // 前進
            break;
          case 39:
            rootNode.rotationY -= 1; // 左回転
            break;
          case 40:
            rootNode.z -= 1; // 後退
            break;
        }
      }
 
      scene.renderCamera(camera);
    }
 
    private function onStageResize(event:Event):void {
      container.x = stage.stageWidth  / 2;
      container.y = stage.stageHeight / 2;
    }
    
  }
}

# よく見たら回転部分がうまく動いていないような……

tags: zlashdot Flash 3D Flash Flex Papervision3D

Posted by NI-Lab. (@nilab)