package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.DisplayObject; import flash.display.Loader; import flash.display.Sprite; import flash.events.Event; import flash.events.KeyboardEvent; import flash.geom.ColorTransform; import flash.geom.Matrix; import flash.net.URLRequest; import flash.ui.Keyboard; import flash.system.LoaderContext; import org.papervision3d.cameras.Camera3D; import org.papervision3d.core.math.Matrix3D; import org.papervision3d.core.proto.CameraObject3D; import org.papervision3d.materials.BitmapAssetMaterial; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.materials.utils.PrecisionMode; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.Viewport3D; public class PVTest extends Sprite { private var _scene:Scene3D; private var _viewport:Viewport3D; private var _renderer:BasicRenderEngine; private var _camera:Camera3D; private var _openCamera:Camera3D; private var _goalLine:Plane; private var _bolaLayer:Sprite; private var _bola3DArr:Array; private var _bolaArr:Array; private var _loader:Loader; private var _bolaImg:DisplayObject; //フラグたち private var _keyAPress:Boolean = false; private var _keyDPress:Boolean = false; private var _keyRightPress:Boolean = false; private var _keyLeftPress:Boolean = false; private const _IMG_PATH:String = "http://www.chikathreesix.com/wonderfl/labola.png"; private const _AREA_WIDTH:Number = 2000; private const _AREA_HEIGHT:Number = 2000; private const _BOLA_NUM:int = 20; public function PVTest() { _bola3DArr = new Array(); _bolaArr = new Array(); _bolaLayer = new Sprite(); this.addChild(_bolaLayer); _loadImg(); } private function _loadImg():void { var context:LoaderContext = new LoaderContext(true); _loader = new Loader(); _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, _loadedImg); _loader.load(new URLRequest(_IMG_PATH), context); } private function _loadedImg(e:Event):void { e.currentTarget.removeEventListener(e.type, arguments.callee); _bolaImg = _loader.content; _loader.unload(); _init3D(); } private function _init3D():void{ _scene = new Scene3D(); _viewport = new Viewport3D(this.stage.stageWidth, this.stage.stageHeight); this.addChild(_viewport); _renderer = new BasicRenderEngine(); _camera = new Camera3D(); _camera.y = 50; _camera.z = 0; _bolaLayer = new Sprite(); this.addChild(_bolaLayer); _set3DObjects(); _setListener(); } /** * リスナーをセット */ private function _setListener():void { this.addEventListener(Event.ENTER_FRAME, _enterFrameAction); this.stage.addEventListener(KeyboardEvent.KEY_UP, _keyReleaseAction); this.stage.addEventListener(KeyboardEvent.KEY_DOWN, _keyPressAction); } /** * キーが押された * @param e */ private function _keyPressAction(e:KeyboardEvent):void { switch(e.keyCode) { case Keyboard.UP: _keyAPress = true; return; case Keyboard.DOWN: _keyDPress = true; return; case Keyboard.LEFT: _keyLeftPress = true; return; case Keyboard.RIGHT: _keyRightPress = true; return; } } /** * キーが離された * @param e */ private function _keyReleaseAction(e:KeyboardEvent):void { switch(e.keyCode) { case Keyboard.UP: _keyAPress = false; return; case Keyboard.DOWN: _keyDPress = false; return; case Keyboard.LEFT: _keyLeftPress = false; return; case Keyboard.RIGHT: _keyRightPress = false; return; } } /** * 3Dのオブジェクトをセット */ private function _set3DObjects():void{ for (var i:int = 0; i < _BOLA_NUM; i++) { var bmp:BitmapData = new BitmapData(_bolaImg.width, _bolaImg.height,true,0x000000); bmp.draw(_bolaImg,new Matrix(),new ColorTransform(),null,null,true); var obj:Bitmap = new Bitmap(bmp); _bolaLayer.addChild(obj); _bolaArr.push(obj); var obj3d:DisplayObject3D = new DisplayObject3D(); obj3d.autoCalcScreenCoords = true; obj3d.x = Math.floor(Math.random() * _AREA_WIDTH - _AREA_WIDTH / 2); obj3d.z = Math.floor(Math.random() * _AREA_HEIGHT); _scene.addChild(obj3d); _bola3DArr.push(obj3d); } } private function _enterFrameAction(e:Event = null):void { if (_keyRightPress) _camera.rotationY += 2; if (_keyLeftPress) _camera.rotationY -= 2; if(_keyAPress){ _camera.z += 10 * Math.cos(_camera.rotationY / 180 * Math.PI); _camera.x += 10 * Math.sin(_camera.rotationY / 180 * Math.PI); } if (_keyDPress) { _camera.z -= 10 * Math.cos(_camera.rotationY / 180 * Math.PI); _camera.x -= 10 * Math.sin(_camera.rotationY / 180 * Math.PI); } //3Dオブジェクトの再配置 _arrange3DObjects(); //再描画 _renderer.renderScene(_scene, _camera, _viewport); } private function _arrange3DObjects():void { var bolaLen:int = _bola3DArr.length; _sort(_bola3DArr); for (var i:int = 0; i < bolaLen; i++) { var bola3d:DisplayObject3D = _bola3DArr[i]; var bola:Bitmap = _bolaArr[i]; bola.x = bola3d.screen.x + this.stage.stageWidth / 2; bola.y = bola3d.screen.y + this.stage.stageHeight / 2 - bola.height / 2; bola.scaleX = bola.scaleY = _camera.focus / (_camera.focus + bola3d.screen.z) * _camera.zoom; //trace("bola x:" + bola.x + "bola y:" + bola.y + "scale :"+bola.scaleX); //通り過ぎたら if (bola3d.screen.z < _camera.focus) { bola.visible = false; } else bola.visible = true; //zソート _bolaLayer.setChildIndex(bola, bolaLen - i - 1); } } private function _sort(arr:Array):void { var i:int var j:int; var temp:DisplayObject3D; for (i = 0; i < arr.length - 1; i++) { for (j = arr.length - 1; j > i; j--) { if (arr[j - 1].screen.z >arr[j].screen.z) { /* 前の要素の方が大きかったら */ temp = arr[j]; /* 交換する */ arr[j] = arr[j - 1]; arr[j - 1]= temp; } } } } } }