3D空間でテクスチャ貼ってぐるぐるしてみた。

画像は 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)

ソースコード(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 distance : Number = 10;
    private var angle    : Number = 0;
 
    // 画像ファイルのパス
    private var imageFilePath:String = "planeworld.png";
 
    // 何か情報を表示
    private var dispInfo : TextField;
 
    public function PlaneWorld():void {
 
      // QUERY_STRINGパラメータ取得
      var param:Object = loaderInfo.parameters;
 
      // 画像ファイルのパスを指定
      if(param["imagefile"] != undefined){
        imageFilePath = param["imagefile"];
      }
 
      // 画面いっぱいに表示(縦横比無視)したいときはコレを使う
      // stage.scaleMode = StageScaleMode.EXACT_FIT;
 
      // リサイズに対応(swfをブラウザで直接ひらいているときとか)
      stage.addEventListener(Event.RESIZE, onStageResize);
 
      // 定期的にイベント発生
      addEventListener(Event.ENTER_FRAME, myLoopEvent);
 
      // 表示用の Sprite オブジェクトを生成
      container = new Sprite();
      container.x = 400 / 2; // at center : swf width  = 400
      //container.y = 400 / 2; // at center : swf height = 400
      container.y = 400;
 
      // 試しに円を描画してみる
      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);
 
      // 情報表示用
      dispInfo = createTextField();
      addChild(dispInfo);
 
      // シーンオブジェクトを作る
      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 updateDisplayInfo():void{
      dispInfo.text =
        "Info: " +
        "angle=" + angle + ", " +
        "distance=" + distance + ", " ;
    }
 
    private static function createTextField():TextField{
 
      // 表示メッセージのスタイル
      var format:TextFormat = new TextFormat();
      format.bold = false;
      format.italic = false;
      format.size = 10;
      format.underline = false;
      format.font = "_等幅";
 
      // 表示メッセージ
      var text:TextField = new TextField();
      text.autoSize = TextFieldAutoSize.LEFT;
      text.selectable = false;
      text.setTextFormat(format);
      text.background = true;
      text.backgroundColor = 0x000000;
      text.border = true;
      text.borderColor = 0xFFFFFF;
      text.textColor = 0xFFFFFF;
 
      return text;
    }
 
    private function createWorld():DisplayObject3D{
 
      var material:BitmapFileMaterial = new BitmapFileMaterial(imageFilePath);
      material.doubleSided = true;
      material.lineColor = 0x00FF00;
      material.lineAlpha = 1;
 
      var planeSize:int = 100;
      var segment:int = 20;
 
      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 myLoopEvent(event:Event):void {
 
      var b:Number = 200;
      var t:Number =  50;
 
      // 画面の左右にマウスをもっていくと、左右に回転
      if(container.mouseX < -t){
        angle += 1;
      }else if(container.mouseX > t){
        angle -= 1;
      }
 
      // 画面の上下にマウスをもっていくと、アングルを変更
      if(container.mouseY < -t - b){
        distance -= 0.2;
        if(distance < 1){
          distance = 1;
        }
      }else if(container.mouseY > t - b){
        distance += 0.2;
        if(distance > 20){
          distance = 20;
        }
      }
 
      camera.x = Math.cos(angle * Math.PI/180) * distance;
      camera.z = Math.sin(angle * Math.PI/180) * distance;
      scene.renderCamera(camera);
 
      updateDisplayInfo();
    }
 
    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)