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)