In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Alternativa3D 7.5 でアクションゲームサンプル

Alternativa3D 7.5を使った3Dアクションゲームのサンプルです。
立体的なマップを歩きとジャンプ移動して、
ショット、体当たりで敵(ラミエルさん)を破壊します。
スコアやゲームオーバーなどはありません。

操作方法
移動:WASD
カメラ:マウス移動
ジャンプ:スペース(3段ジャンプまで可能)
ショット:左クリック

2010/11/8 0:43 テクスチャを正しいものに修正しました。
/**
 * Copyright GARENA123 ( http://wonderfl.net/user/GARENA123 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/9BaG
 */

//3Dアクションゲーム
//操作:WASD
//視点:マウス移動
//射撃:左クリック
//跳躍:スペース
package {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.StageQuality
	import flash.display.Sprite;
	import flash.display.StageDisplayState;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.filters.BlurFilter;
	import flash.filters.ColorMatrixFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.geom.Vector3D;
	import flash.system.LoaderContext;
	import flash.ui.Keyboard;
	//
	//ステータス表示
	import net.hires.debug.Stats;
	//
	//Alternativa3D
	import alternativ7.engine3d.loaders.MaterialLoader;
	import alternativ7.engine3d.containers.ConflictContainer;
	import alternativ7.engine3d.controllers.SimpleObjectController;
	import alternativ7.engine3d.core.Camera3D;
	import alternativ7.engine3d.core.View;
	import alternativ7.engine3d.materials.FillMaterial;
	import alternativ7.engine3d.materials.TextureMaterial;
	import alternativ7.engine3d.primitives.Box;
	import alternativ7.engine3d.primitives.Plane;
	import alternativ7.engine3d.primitives.Sphere;
	import alternativ7.engine3d.primitives.GeoSphere;
	import alternativ7.engine3d.objects.Sprite3D;

	[SWF(width = 465, height = 465, frameRate = 60 , backgroundColor = "#000000")]

	public class Main extends Sprite {
		private static var STAGE_W:uint = 465;
		private static var STAGE_H:uint = 465;
		private static var FPS:uint = 60;

		private static var PI2:Number = Math.PI / 180;
		private static var fullScreenSupport:Boolean = true;
		private var stats:Stats;

		private var keyState:KeyState;
		private var isMouseDown:Boolean = false;

		private var cursorX:Number = 0;
		private var cursorY:Number = 0;

		private var cameraPitch:Number = 0;

		//3D関連
		private var container:ConflictContainer;
		private var containerBg:ConflictContainer;
		private var camera:Camera3D;
		private var cameraBg:Camera3D;
		private var controller:SimpleObjectController;
		private var cameraRdmAdd:int = 0;

		//3Dオブジェクト格納
		private var boxs:Vector.<Box>;
		private var particleObjs:Vector.<ParticleObj>;
		private var bulletObjs:Vector.<BulletObj>;
		private var enemyObjs:Vector.<EnemyObj>;

		//テクスチャ
		private var txMatCubeTop:TextureMaterial;;
		private var txMatCubeBottom:TextureMaterial;
		private var txMatCubeFront:TextureMaterial;
		private var txMatCubeLeft:TextureMaterial;
		private var txMatCubeBack:TextureMaterial;
		private var txMatCubeRight:TextureMaterial;
		private var txMatRamiel:TextureMaterial;
		private var txMatKusa0:TextureMaterial;
		private var txMatKusa1:TextureMaterial;
		private var txMatKusa2:TextureMaterial;
		private var txMatKusa3:TextureMaterial;
		private var txMatStar:TextureMaterial;
		private var txMatBg:TextureMaterial;
		private var txMatKage:TextureMaterial;
		private var txMatExp:TextureMaterial;
		//テクスチャ読み込み関連
		private var textures:Vector.<TextureMaterial> ;
		private var materialLoader:MaterialLoader;
		private var loaderContext:LoaderContext;

		private var player:PlayerObj = new PlayerObj();
		private var playerH:int = 30;
		private var player3D:GeoSphere;
		private var player3D2:Box;

		private var kage:Plane;
		private var bg:Sphere;

		private var bgBmd:BitmapData;
		private var bgBmp:Bitmap;

		private var layerMain:Sprite;
		private var layerBg:Sprite;
		private var layerBmp:Sprite;
		

		public function Main():void {
			stage.quality = StageQuality.LOW;
			stats = new Stats();
			//
			//レイヤーを準備
			//レイヤーは、メイン3Dと背景(天球)の2つです。
			//ただし、背景はそのまま表示すると手前レイヤーでロゴが隠れた際に表示が消えてしまう(Alternativa3Dの仕様)ので、
			//レンダリング結果をBitmapDataにdrawして、そちらを表示します。
			bgBmd = new BitmapData(STAGE_W, STAGE_H,false,0x000000);
			bgBmp = new Bitmap(bgBmd);
			layerBg = new Sprite();
			layerMain = new Sprite();
			layerBmp = new Sprite();
			layerBmp.addChild(bgBmp);
			//addChild(layerBg);
			addChild(layerBmp);
			addChild(layerMain);

			//3Dの初期化、*Bgは天球用
			//container
			container = new ConflictContainer();
			containerBg = new ConflictContainer();
			//
			//camera
			camera = new Camera3D();
			cameraBg = new Camera3D();
			container.addChild(camera);
			containerBg.addChild(cameraBg);
			camera.view = new View(STAGE_W, STAGE_H, false);
			cameraBg.view = new View(STAGE_W, STAGE_H, false);
			layerBg.addChild(cameraBg.view);
			layerMain.addChild(camera.view);

			//カメラ設定
			camera.farClipping = 1000;
			camera.x = 0;
			camera.y = -1000;
			camera.z = 100;
			cameraBg.farClipping = 5000;

			controller = new SimpleObjectController(stage, camera, 500);
			controller.lookAtXYZ(0, 0, 0);
			//
			boxs = new Vector.<Box>();
			enemyObjs = new Vector.<EnemyObj>();
			particleObjs = new Vector.<ParticleObj>();
			bulletObjs = new Vector.<BulletObj>();

			//テクスチャの読み込み
			//とりあえず読み込みは一時的にスルー
			txMatCubeTop = new TextureMaterial();
			txMatCubeBottom = new TextureMaterial();
			txMatCubeFront = new TextureMaterial();
			txMatCubeLeft = new TextureMaterial();
			txMatCubeBack = new TextureMaterial();
			txMatCubeRight = new TextureMaterial();
			txMatRamiel = new TextureMaterial();
			txMatKusa0 = new TextureMaterial();
			txMatKusa1 = new TextureMaterial();
			txMatKusa2 = new TextureMaterial();
			txMatKusa3 = new TextureMaterial();
			txMatStar = new TextureMaterial();
			txMatBg = new TextureMaterial();
			txMatKage = new TextureMaterial();
			txMatExp = new TextureMaterial();
			txMatCubeTop.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_cube_kusa_top.png";
			txMatCubeBottom.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_cube_kusa_bottom.png";
			txMatCubeFront.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_cube_kusa_front.png";
			txMatCubeLeft.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_cube_kusa_left.png";
			txMatCubeBack.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_cube_kusa_back.png";
			txMatCubeRight.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_cube_kusa_right.png";
			txMatRamiel.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_ramiel.png";
			txMatKusa0.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_kusa0.png";
			txMatKusa1.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_kusa1.png";
			txMatKusa2.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_kusa2.png";
			txMatKusa3.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_kusa3.png";
			txMatStar.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_star.png";
			txMatBg.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_air.png";
			txMatKage.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_kage.png";
			txMatExp.diffuseMapURL = "http://garena.sakura.ne.jp/wonderfl/action3d/tx_exp.png";
			textures = new Vector.<TextureMaterial>();
			textures.push(txMatCubeTop);
			textures.push(txMatCubeBottom);
			textures.push(txMatCubeFront);
			textures.push(txMatCubeLeft);
			textures.push(txMatCubeBack);
			textures.push(txMatCubeRight);
			textures.push(txMatRamiel);
			textures.push(txMatKusa0);
			textures.push(txMatKusa1);
			textures.push(txMatKusa2);
			textures.push(txMatKusa3);
			textures.push(txMatStar);
			textures.push(txMatBg);
			textures.push(txMatKage);
			textures.push(txMatExp);
			//
			//MaterialLoaderに読み込むテクスチャのリストを投げて、読み込み開始
			loaderContext = new LoaderContext(true);
			materialLoader = new MaterialLoader()
			materialLoader.load(textures, loaderContext);
			
			//
			//宙に浮かぶキューブ群をBoxを使って生成
			var myBoxTotal:uint = 10;
			for (var x:int = 0; x < myBoxTotal; x++) {
				for (var y:int = 0; y < myBoxTotal; y++) {
					//ボックス生成時に、new Box(1,1,1)で、サイズを1にしたあと、scaleでサイズを変えると、
					//scaleX,scaleY,scaleZの値がボックスの大きさと同等になるので便利
					var myZ:Number = Math.random() * 500;
					var myBox:Box = new Box(1,1,1);
					myBox.faces[0].material = txMatCubeRight;
					myBox.faces[1].material = txMatCubeLeft;
					myBox.faces[2].material = txMatCubeFront;
					myBox.faces[3].material = txMatCubeBack;
					myBox.faces[4].material = txMatCubeTop;
					myBox.faces[5].material = txMatCubeBottom;

					myBox.x = (x - myBoxTotal*0.5) * 100; 
					myBox.y = (y - myBoxTotal*0.5) * 100;
					myBox.z = myZ + 50;
					myBox.scaleX = 100;
					myBox.scaleZ = 100;
					myBox.scaleY = 100;
					myBox.clipping = 1000;

					container.addChild(myBox);
					boxs.push(myBox);
				}
			}
			//
			//敵(ラミエルさん)群をSphereを使って生成
			var myEnemyTotal:uint = boxs.length;
			for (var i:int = 0; i < myEnemyTotal; i++) {
				var mySphere:Sphere = new Sphere(70,4,2,false, txMatRamiel);
				var myX:Number = boxs[i].x;
				var myY:Number = boxs[i].y;
				var myZ:Number = boxs[i].z + 100 + Math.random() * 300;
				
				var myEnemyObj:EnemyObj = new EnemyObj(mySphere, myX, myY, myZ, 10);
				container.addChild(mySphere);
				enemyObjs.push(myEnemyObj);
			}
			//
			//草
			var myKusaTotal:int = 200;
			var myTxs:Array = [txMatKusa0,txMatKusa1,txMatKusa2,txMatKusa3]
			for (var i:int = 0; i < myKusaTotal; i++) {
				var myRdm:int = Math.floor(Math.random() * 4)
				var mySc:Number = Math.random() * 20 + 5
				var myKusa:Sprite3D = new Sprite3D(mySc,mySc,myTxs[myRdm]);
				myKusa.x = Math.random() * 2000 - 1000;
				myKusa.y = Math.random() * 2000 - 1000;
				myKusa.z = mySc;
				container.addChild(myKusa);
			}
			//
			//星
			var myStarTotal:int = 500;
			for (var i:int = 0; i < myStarTotal; i++) {
				var mySc:Number = Math.random() * 10 + 5
				var myStar:Sprite3D = new Sprite3D(mySc,mySc,txMatStar);
				myStar.x = Math.random() * 4000 - 2000;
				myStar.y = Math.random() * 4000 - 2000;
				myStar.z = Math.random() * 2000;
				container.addChild(myStar);
			}
			//
			//プレイヤー
			var playerMaterial:FillMaterial = new FillMaterial(0xFFCC00, 0.5, 1, 0xFF9900);
			player3D = new GeoSphere(30, 1, false, playerMaterial);
			container.addChild(player3D);
			player3D.x = 0;
			player3D.y = 0;
			player3D.z = 0;
			var playerMaterial2:FillMaterial = new FillMaterial(0xFF9900, 1, 1, 0xFF6600);
			player3D2 = new Box(15, 15, 15);
			player3D2.setMaterialToAllFaces(playerMaterial2);
			container.addChild(player3D2);
			kage = new Plane(40, 40, 1, 1, true, false, false, null, txMatKage);
			container.addChild(kage);
			//
			//天球(天球のみ、背景用のcontainerに配置します。)
			bg = new Sphere(4000, 10, 10, true, txMatBg);
			containerBg.addChild(bg);
			//
			//ステータス表示
			addChild(stats);
			//
			//イベント
			addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
			//マウスイベント
			stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
			//キーボードイベント
			keyState = new KeyState();
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyState.onKeyDown);
			stage.addEventListener(KeyboardEvent.KEY_UP, keyState.onKeyUp);
		}
		//マウスを押されたとき
		private function mouseDownHandler(_e:MouseEvent):void{
			isMouseDown = true;
		}
		//マウスを放したとき
		private function mouseUpHandler(_e:MouseEvent):void{
			isMouseDown = false;
		}
		//マウスが動いたとき
		private function mouseMoveHandler(_e:MouseEvent):void{
			cursorX = (stage.mouseX - (stage.stageWidth * 0.5)) / (stage.stageWidth * 0.5);
			cursorY = stage.mouseY / stage.stageHeight;
		}
		//毎フレーム実行
		private function onEnterFrameHandler(_e:Event):void {
			//カメラ
			player.sp.w = cursorX * 0.04;
			cameraPitch = -cursorY * Math.PI;
			cameraPitch = Math.max(Math.min(cameraPitch, -Math.PI * 0.1), -Math.PI * 0.8);
			player.point.w += player.sp.w;
			//
			//前後移動
			if (keyState.up) {
				player.sp.y = player.spWalk;
			} else if (keyState.down) {
				player.sp.y = -player.spWalk;
			} else {
				player.sp.y = 0;
			}
			//左右移動
			if (keyState.left) {
				player.sp.x = -player.spWalk;
			} else if (keyState.right) {
				player.sp.x = player.spWalk;
			} else {
				player.sp.x = 0;
			}
			//斜め移動時は補正
			if (player.sp.x != 0 && player.sp.y != 0) {
				player.sp.x *= 0.7071;
				player.sp.y *= 0.7071;
			}
			//ジャンプ
			if (keyState.aP && player.jumpCount < player.jumpMax) {
				//ジャンプボタンが押されていて、ジャンプ可能な状態であれば、ジャンプ開始
				player.sp.z = player.spJump;
				player.ground = false;
				player.jumpCount++;
			} else if (player.point.z > 0 && player.ground == false) {
				//空中にいる時は、重力で落下
				player.sp.z -= 9.8 / FPS;
			}
			//
			//座標移動
			var mySpX:Number = (Math.sin(player.point.w) * player.sp.y) - (Math.sin(player.point.w - Math.PI*0.5) * player.sp.x);
			var mySpY:Number = (Math.cos(player.point.w) * player.sp.y) - (Math.cos(player.point.w - Math.PI*0.5) * player.sp.x)
			var mySpZ:Number = player.sp.z
			var myX:Number = player.point.x + mySpX;
			var myY:Number = player.point.y + mySpY;
			var myZ:Number = Math.max(player.point.z + mySpZ, 0);
			
			var myHit:Boolean = false;
			var myGround:Boolean = false
			
			//キューブとの当たり判定
			//プレイヤーの近くにあるキューブを抽出
			var myHitBoxArray:Array = [];
			for (var i:int = 0; i < boxs.length; i++) {
				var myBox:Box = boxs[i];
				//判定はプレイヤーY軸の上端と下端
				if (lengthTest(myBox, myX, myY, myZ + playerH * 0.5, 200)) {
					myHitBoxArray.push(myBox);
				}
			}
			var myLoop:int = 0;
			if(myHitBoxArray.length > 0){
				for (var i:int = 0; i < myHitBoxArray.length; i++) {
					myX = player.point.x + mySpX;
					myY = player.point.y + mySpY;
					myZ = Math.max(player.point.z + mySpZ, 0);
					
					
					var myBox:Box = myHitBoxArray[i];
					//判定はプレイヤーZ軸の上端と下端
					var myHitB:Boolean = hitTestBox(myBox, myX, myY, myZ);
					var myHitT:Boolean = hitTestBox(myBox, myX, myY, myZ + playerH);
					var myHitG:Boolean = false;
					
					if (myHitB || myHitT) {
						if(player.ground && myHitB && hitTestBox(myBox, myX, myY, myZ + 20) == false){
							mySpZ = 0;
							player.point.z = myBox.z + myBox.scaleZ * 0.5;
							myGround = true;
							player.ground = true;
							player.jumpCount = 0;
						}else if(mySpZ < 0 && myHitB && hitTestBox(myBox, myX, myY, myZ - mySpZ) == false) {
							//着地
							mySpZ = 0;
							player.point.z = myBox.z + myBox.scaleZ * 0.5;
							myGround = true
							player.ground = true;
							player.jumpCount = 0;
						}else if (mySpZ > 0 && myHitT && hitTestBox(myBox, myX - mySpX, myY - mySpY, myZ + playerH)) {
							//ジャンプで頭ぶつけ
							mySpZ = -mySpZ;
							player.point.z = myBox.z - myBox.scaleZ * 0.5 - playerH;
						}else{
							var mySpXL:Number = (Math.sin((player.point.w + Math.PI*0.75)) * player.sp.y) - (Math.sin((player.point.w - Math.PI*0.5 + Math.PI*0.75)) * player.sp.x);
							var mySpYL:Number = (Math.cos((player.point.w + Math.PI*0.75)) * player.sp.y) - (Math.cos((player.point.w - Math.PI*0.5 + Math.PI*0.75)) * player.sp.x)
							
							var mySpXR:Number = (Math.sin((player.point.w - Math.PI*0.75)) * player.sp.y) - (Math.sin((player.point.w - Math.PI*0.5 -Math.PI*0.75)) * player.sp.x);
							var mySpYR:Number = (Math.cos((player.point.w - Math.PI*0.75)) * player.sp.y) - (Math.cos((player.point.w - Math.PI*0.5 - Math.PI*0.75)) * player.sp.x);
							//
							var myAddX:Number = 0;
							var myAddY:Number = 0;
							for (var j:int = 1; j < 6; j++) {
								myAddX = mySpXL * j * 0.2;
								myAddY = mySpYL * j * 0.2;
								if (hitTestBox(myBox,myX + myAddX, myY + myAddY, myZ) == false && hitTestBox(myBox,myX + myAddX, myY + myAddY, myZ + playerH) == false) {
									mySpX += myAddX;
									mySpY += myAddY;
									break;
								}
								myAddX = mySpXR * j * 0.2;
								myAddY = mySpYR * j * 0.2;
								if (hitTestBox(myBox,myX + myAddX, myY + myAddY, myZ) == false && hitTestBox(myBox,myX + myAddX, myY + myAddY, myZ+playerH) == false) {
									mySpX += myAddX;
									mySpY += myAddY;
									break;
								}
								myAddX = -mySpX * j * 0.2;
								myAddY = -mySpY * j * 0.2;
								if (hitTestBox(myBox,myX + myAddX, myY + myAddY, myZ) == false && hitTestBox(myBox,myX + myAddX, myY + myAddY, myZ+playerH) == false) {
									mySpX += myAddX;
									mySpY += myAddY;
									break;
								}
							}
							//XY軸移動時にヒット判定がある場合は、XY軸を補正した後、最初から当たり判定チェックをやり直す
							i = -1;
							myLoop++;
							if (myLoop > 30) {
								//ループ回数が30を超えた場合は強制的に終了
								break;
							}
						}
					}
				}	
			}
			//落下判定
			if (player.point.z <= 0 || myGround == true) {
				//0以下(地面) or キューブ当たり判定の段階で着地してるかどうか
				myGround = true;
			}else {
				//キューブとヒットしているかどうか
				for (var i:int = 0; i < boxs.length; i++) {
					if (myGround == false) {
						var myBox:Box = boxs[i]
						myHitG = hitTestBox(myBox, myX, myY, myZ - 1);
						if (myHitG == true) {
							myGround = true;
						}
					}
				}
			}
			if (myGround == false) {
				player.ground = false;
			}
			
			//影
			var myKageZ:Number = 0;
			for (var i:int = 0; i < boxs.length; i++) {
				var myBox:Box = boxs[i];
				if (hitTestXY(myBox, player.point.x, player.point.y)) {
					var myT:Number = myBox.z + myBox.scaleZ * 0.5;
					if(myT <= player.point.z){
						myKageZ = Math.max(myKageZ, myT);
					}
				}
			}
			kage.z = myKageZ + 3;
			player.sp.x = mySpX;
			player.sp.z = mySpZ
			player.sp.y = mySpY
			player.point.x += mySpX;
			player.point.z += mySpZ;
			player.point.y += mySpY;
			if (player.point.z <= 0) {
				player.point.z = 0;
				player.sp.z = 0
				player.ground = true;
				player.jumpCount = 0;
			}
			
			//プレイヤー座標
			player3D.x = player.point.x
			player3D.y = player.point.y
			player3D.z = player.point.z + 30
			player3D.rotationZ = -player.point.w
			player3D2.x = player3D.x;
			player3D2.y = player3D.y;
			player3D2.z = player3D.z;
			player3D2.rotationX += 0.04
			player3D2.rotationY += 0.043
			player3D2.rotationZ += 0.072
			
			kage.x = player.point.x;
			kage.y = player.point.y;
			
			kage.rotationZ = -player.point.w;
			
			//カメラ座標
			camera.x += ((player3D.x + Math.sin(player.point.w) * -120) - camera.x) * 1;
			camera.y += ((player3D.y + Math.cos(player.point.w) * -120) - camera.y) * 1;
			camera.z += ((player3D.z + 40 + (cameraPitch + Math.PI * 0.5) * -50) - camera.z) * 1;
			
			camera.rotationZ = -player.point.w;
			camera.rotationX += (cameraPitch - camera.rotationX) * 0.2;
			
			//
			//敵
			for (var i:int = 0; i < enemyObjs.length; i++) {
				var myEnemyObj:EnemyObj = enemyObjs[i];
				var mySphere:Sphere = myEnemyObj.sphere;
				var myPoint:Vector3D = myEnemyObj.point
				myEnemyObj.enterFrameAction();
				//当たり判定
				var myHitP:Boolean =  lengthTest(myPoint, player.point.x, player.point.y + playerH * 0.5, player.point.z, 60);
				if (myHitP) {
					addParticle(myPoint.x, myPoint.y, myPoint.z);
					container.removeChild(mySphere);
					myEnemyObj.sphere = null;
					enemyObjs.splice(i, 1);
					i--;
					cameraRdmAdd = 25;
				}
			}
			
			//ショットの判定
			for (var i:int = 0; i < bulletObjs.length; i++) {
				var myBulletObj:BulletObj = bulletObjs[i];
				var mySphere:Sphere = myBulletObj.sphere;
				var myPoint:Vector3D = myBulletObj.point;
				myPoint.x += myBulletObj.sp.x;
				myPoint.y += myBulletObj.sp.y;
				myPoint.z += myBulletObj.sp.z;
				mySphere.x = myPoint.x
				mySphere.y = myPoint.y
				mySphere.z = myPoint.z
				if (myPoint.x < -5000 || 5000 < myPoint.x || myPoint.y < -5000 || 5000 < myPoint.y || myPoint.z < 0 || 5000 < myPoint.z) {
					container.removeChild(mySphere);
					myBulletObj.sphere = null;
					bulletObjs.splice(i, 1);
					i--;
				}else {
					//敵との判定
					var myHitState:Boolean = false;
					for (var j:int = 0; j < enemyObjs.length; j++) {
						var myEnemyObj:EnemyObj = enemyObjs[j];
						var myEnemyPoint:Vector3D = myEnemyObj.point;
						var myHitB:Boolean =  lengthTest(myPoint, myEnemyPoint.x, myEnemyPoint.y, myEnemyPoint.z, 40);
						if (myHitB) {
							//敵にヒット
							myHitState = true;
							addParticleS(myPoint.x,myPoint.y,myPoint.z)
							myEnemyObj.life--;
							myEnemyObj.bulletHit();
							container.removeChild(mySphere);
							myBulletObj.sphere = null;
							bulletObjs.splice(i, 1);
							i--;
							if (myEnemyObj.life <= 0) {
								//敵を破壊
								//カメラの振動を、破壊した敵からの距離に比例して設定
								cameraRdmAdd = Math.max(cameraRdmAdd, Math.min(25, 25 - Math.sqrt(Math.pow(myEnemyPoint.x - camera.x, 2) + Math.pow(myEnemyPoint.y - camera.y, 2) + Math.pow(myEnemyPoint.z - camera.z, 2)) * 0.02));
								addParticle(myEnemyPoint.x, myEnemyPoint.y, myEnemyPoint.z);
								container.removeChild(myEnemyObj.sphere);
								myEnemyObj.sphere = null;
								enemyObjs.splice(j, 1);
							}
							break;
						}
					}
					if(myHitState == false){
						//キューブとの判定(敵にヒットしていない場合のみ)
						for (var j:int = 0; j < boxs.length; j++) {
							var myBox:Box = boxs[j];
							var myHitB:Boolean = hitTestBox(myBox, myPoint.x, myPoint.y, myPoint.z);
							if (myHitB) {
								//キューブとヒット
								container.removeChild(mySphere);
								myBulletObj.sphere = null;
								bulletObjs.splice(i, 1);
								i--;
								break;
							}
						}
					}
				}
				
			}
			
			//パーティクル
			for (var i:int = 0; i < particleObjs.length; i++) {
				var myParticleObj:ParticleObj = particleObjs[i];
				var mySprite3D:Sprite3D = myParticleObj.sprite3D;
				myParticleObj.point.x += myParticleObj.sp.x;
				myParticleObj.point.y += myParticleObj.sp.y;
				myParticleObj.point.z += myParticleObj.sp.z;
				myParticleObj.sp.z -= 9.8 / FPS;
				myParticleObj.life--;
				mySprite3D.x = myParticleObj.point.x;
				mySprite3D.y = myParticleObj.point.y;
				mySprite3D.z = myParticleObj.point.z;
				if (myParticleObj.life < 0 || myParticleObj.point.x < -5000 || 5000 < myParticleObj.point.x || myParticleObj.point.y < -5000 || 5000 < myParticleObj.point.y || myParticleObj.point.z < 0 || 5000 < myParticleObj.point.z) {
					container.removeChild(mySprite3D);
					particleObjs[i].sprite3D = null;
					particleObjs.splice(i, 1);
					i--;
				}
			}
			//マウスが押し下げられているときは、ショット発射
			if (isMouseDown) {
				var myFillMat:FillMaterial = new FillMaterial(0xFF3300, 1, 1, 0xFF6600);
				var mySphere:Sphere = new Sphere(20, 3, 2, false, myFillMat);
				var mySp:Number = 40;
				//プレイヤーの向いている方向にショット発射
				var mySpX:Number = Math.sin(cameraPitch) * (Math.sin(player.point.w + Math.PI) * mySp + Math.random() * 6 - 3);
				var mySpY:Number = Math.sin(cameraPitch) * (Math.cos(player.point.w + Math.PI) * mySp + Math.random() * 6 - 3);
				var mySpZ:Number = Math.cos(cameraPitch) * mySp + Math.random() * 6 - 3;
				var myX:Number = player.point.x + mySpX * 0.4;
				var myY:Number = player.point.y + mySpY * 0.4;
				var myZ:Number = player.point.z + mySpZ * 0.4 + playerH;
				var myBulletObj:BulletObj = new BulletObj(mySphere,myX,myY,myZ,mySpX,mySpY,mySpZ);
				mySphere.rotationX = Math.random() * Math.PI * 2
				mySphere.rotationY = Math.random() * Math.PI * 2
				mySphere.rotationZ = Math.random() * Math.PI * 2
				bulletObjs.push(myBulletObj);
				container.addChild(mySphere);
			}
			//カメラ振動
			if (cameraRdmAdd > 0) {
				cameraRdmAdd -= 1;
				camera.x += Math.random() * cameraRdmAdd - cameraRdmAdd * 0.5
				camera.y += Math.random() * cameraRdmAdd - cameraRdmAdd * 0.5
				camera.z += Math.random() * cameraRdmAdd - cameraRdmAdd * 0.5
			}
			camera.render();
			cameraBg.rotationX = camera.rotationX;
			cameraBg.rotationY = camera.rotationY;
			cameraBg.rotationZ = camera.rotationZ;
			cameraBg.render();
			//
			keyState.keyCheck();
			
			//viewが重なっていると消えてしまう(ロゴ部分を隠すと非表示になる仕様)を回避するため、
			//背景用のviewは別のbitmapDataにdrawしてそちらを表示
			bgBmd.draw(layerBg);
			//bgBmd.draw(layerMain);
		}
		
		//着弾パーティクル追加
		private function addParticleS(agX:Number, agY:Number, agZ:Number):void {
			for (var i:int = 0; i < 8; i++) {
				var mySc:Number = Math.random() * 16 + 16;
				var mySprite3D:Sprite3D = new Sprite3D(mySc,mySc,txMatExp);
				var mySp:Number = 8 + Math.random() * 32;
				var myRX:Number = Math.random() * Math.PI * 2;
				var myRY:Number = Math.random() * Math.PI * 2;
				var myRZ:Number = Math.random() * Math.PI * 2;
				
				var mySpX:Number = Math.sin(myRX) * Math.cos(myRY) * mySp
				var mySpY:Number = Math.sin(myRY) * Math.cos(myRZ) * mySp;
				var mySpZ:Number = Math.sin(myRZ) * Math.cos(myRX) * mySp;
				
				var myLife:int = Math.floor(Math.random() * 10 + 5);
				
				var myParticleObj:ParticleObj = new ParticleObj(mySprite3D, agX + mySpX, agY + mySpY, agZ + mySpZ, mySpX, mySpY, mySpZ, myLife);
				container.addChild(mySprite3D);
				particleObjs.push(myParticleObj);
			}
		}
		//爆発パーティクル追加
		private function addParticle(agX:Number, agY:Number, agZ:Number):void {
			for (var i:int = 0; i < 50; i++) {
				var mySc:Number = Math.random() * 128 + 32;
				var mySprite3D:Sprite3D = new Sprite3D(mySc,mySc,txMatExp);
				var mySp:Number = 5 + Math.random() * 40;
				var myRX:Number = Math.random() * Math.PI * 2;
				var myRY:Number = Math.random() * Math.PI * 2;
				var myRZ:Number = Math.random() * Math.PI * 2;
				
				var mySpX:Number = Math.sin(myRX) * Math.cos(myRY) * mySp
				var mySpY:Number = Math.sin(myRY) * Math.cos(myRZ) * mySp;
				var mySpZ:Number = Math.sin(myRZ) * Math.cos(myRX) * mySp;
				
				var myLife:int = Math.floor(Math.random() * 40 + 20);
				
				var myParticleObj:ParticleObj = new ParticleObj(mySprite3D, agX + mySpX, agY + mySpY, agZ + mySpZ, mySpX, mySpY, mySpZ, myLife);
				container.addChild(mySprite3D);
				particleObjs.push(myParticleObj);
			}
		}
		
		//当たり判定
		private function hitTestBox(agBox:Box, agX:Number, agY:Number, agZ:Number):Boolean {
			if (agBox.x - agBox.scaleX * 0.5 <= agX && agX <= agBox.x + agBox.scaleX * 0.5) {
				if (agBox.y - agBox.scaleY * 0.5 <= agY && agY <= agBox.y + agBox.scaleY * 0.5) {
					if (agBox.z - agBox.scaleZ * 0.5 <= agZ && agZ <= agBox.z + agBox.scaleZ * 0.5) {
						return true;
					}
				}
			}
			return false;
		}
		//
		//当たり判定(XY座標(平面)のみ、Z軸(高さ)を問わず
		private function hitTestXY(agBox:Box, agX:Number, agY:Number):Boolean {
			if (agBox.x - agBox.scaleX * 0.5 <= agX && agX <= agBox.x + agBox.scaleX * 0.5) {
				if (agBox.y - agBox.scaleY * 0.5 <= agY && agY <= agBox.y + agBox.scaleY * 0.5) {
					return true;
				}
			}
			return false;
		}
		//
		//距離判定
		private function lengthTest(agBox:*, agX:Number, agY:Number, agZ:Number, agLength:Number):Boolean {
			if (Math.abs(agBox.x - agX) < agLength) {
				if (Math.abs(agBox.y - agY) < agLength) {
					if (Math.abs(agBox.z - agZ) < agLength) {
						return true;
					}
				}
			}
			return false;
		}
	}
}
//----------------------------------
//PlayerObj.as
//プレイヤーの各種情報を保持
//package {
	import flash.geom.Vector3D;
	//public 
	class PlayerObj {
		public var point:Vector3D;
		public var sp:Vector3D;
		public var ground:Boolean = true;
		
		public var spWalk:Number = 4;
		public var spJump:Number = 7;
		public var jumpMax:uint = 3;
		public var jumpCount:uint = 0
		//
		public function PlayerObj(agX:Number = 0, agY:Number = 0, agZ:Number = 800, agW:Number = 0):void {
			point = new Vector3D(agX, agY, agZ, agW);
			sp = new Vector3D();
		}
	}
//}
//----------------------------------
//EnemyObj.as
//敵の各種情報を保持
//package {
	import flash.filters.ColorMatrixFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Vector3D;
	import alternativ7.engine3d.primitives.Sphere;
	//public 
	class EnemyObj {
		public var sphere:Sphere;
		public var point:Vector3D;
		public var sp:Vector3D;
		public var life:int;
		public var hitFrame:int = 0;
		public var hitState:Boolean = false;
		private var rotSp:Number
		private var rotSpAdd:Number = 0
		//
		public function EnemyObj(_sphere:Sphere, _x:Number = 0, _y:Number = 0, _z:Number = 0, _life:uint = 10):void {
			sphere = _sphere;
			point = new Vector3D(_x, _y, _z);
			sp = new Vector3D();
			life = _life;
			
			sphere.x = _x;
			sphere.y = _y;
			sphere.z = _z;
			
			rotSp = Math.random() * 0.02 + 0.01
		}
		
		public function bulletHit():void {
			if (hitState == false) {
				hitState = true;
				rotSpAdd = 1;
				if(hitFrame == 0){
					sphere.colorTransform = new ColorTransform(1, 1, 1, 1, 180, 180, 180, 0);
					hitFrame = 1;
				}else {
					sphere.colorTransform = new ColorTransform(1, 1, 1, 1, 100, 100, 100, 0);
					hitFrame = 0;
				}
			}
		}
		public function enterFrameAction():void {
			if (hitState) {
				hitState = false;
				sphere.colorTransform = new ColorTransform(1, 1, 1, 1, 0, 0, 0, 0);
			}
			sphere.rotationZ += rotSp + rotSpAdd;
			rotSpAdd *= 0.9;
		}
	}
//}
//----------------------------------
//BulletObj.as
//ショットの各種情報を保持
//package {
	import alternativ7.engine3d.primitives.Sphere;
	import flash.geom.Vector3D;
	//public 
	class BulletObj {
		public var point:Vector3D;
		public var sp:Vector3D;
		public var sphere:Sphere
		
		public function BulletObj(_sphere:Sphere, _x:Number = 0, _y:Number = 0, _z:Number = 0, _spX:Number = 0, _spY:Number = 0, _spZ:Number = 0):void {
			sphere = _sphere;
			point = new Vector3D(_x, _y, _z);
			sp = new Vector3D(_spX, _spY, _spZ);
			
			sphere.x = _x;
			sphere.y = _y;
			sphere.z = _z;
		}
	}
//}
//----------------------------------
//ParticleObj.as
//パーティクルの各種情報を保持
//package {
	import alternativ7.engine3d.objects.Sprite3D;
	import flash.geom.Vector3D;
	//public 
	class ParticleObj {
		public var point:Vector3D;
		public var sp:Vector3D;
		public var life:int;
		public var sprite3D:Sprite3D;
		
		public function ParticleObj(_sprite3D:Sprite3D, _x:Number = 0, _y:Number = 0, _z:Number = 0, _spX:Number = 0, _spY:Number = 0, _spZ:Number = 0, _life:int = 30):void {
			sprite3D = _sprite3D;
			point = new Vector3D(_x, _y, _z);
			sp = new Vector3D(_spX, _spY, _spZ);
			life = _life;
			
			sprite3D.x = _x;
			sprite3D.y = _y;
			sprite3D.z = _z;
		}
	}
//}
//----------------------------------
//KeyState.as
//キーボードの操作状態を保存します。
//package {
	//import flash.ui.Keyboard;
	import flash.events.KeyboardEvent;
	//public 
	class KeyState {
		public var left:Boolean = false;
		public var up:Boolean = false;
		public var right:Boolean = false;
		public var down:Boolean = false;
		public var a:Boolean = false;
		public var b:Boolean = false;
		public var c:Boolean = false;
		public var d:Boolean = false;
		public var p:Boolean = false;
		public var f:Boolean = false;
		public var esc:Boolean = false;
		//
		//押したフレームのみtrue
		public var leftP:Boolean = false;
		public var upP:Boolean = false;
		public var rightP:Boolean = false;
		public var downP:Boolean = false;
		public var aP:Boolean = false;
		public var bP:Boolean = false;
		public var cP:Boolean = false;
		public var dP:Boolean = false;
		public var pP:Boolean = false;
		public var fP:Boolean = false;
		public var escP:Boolean = false;
		//
		public var controlType:uint = 0;
		public var keyChecked:Boolean = false;
		//
		private var aCode:uint = 90;
		private var bCode:uint = 88;
		private var cCode:uint = 67;
		private var dCode:uint = 86;
		private var pCode:uint = 80;
		private var fCode:uint = 70;
		//
		public function onKeyDown(myEvt:KeyboardEvent):void {
			keyChecked = false;
			//trace("[ "+myEvt+" ]キーが押されました")
			switch (myEvt.keyCode) {
				case 37://←
				case 100://テンキー4
				case 65://A
					if (left == false) {
						leftP = true;
					}
					left = true;
					break;
				case 38://↑
				case 104://テンキー8
				case 87://W
					if (up == false) {
						upP = true;
					}
					up = true;
					break;
				case 39://→
				case 102://テンキー6
				case 68://D
					if (right == false) {
						rightP = true;
					}
					right = true;
					break;
				case 40://↓
				case 98://テンキー2
				case 83://S
					if (down == false) {
						downP = true;
					}
					down = true;
					break;
				case aCode://Z
				case 32://SPACE
					if (a == false) {
						aP = true;
					}
					a = true;
					break;
				case bCode://X
					if (b == false) {
						bP = true;
					}
					b = true;
					break;
				case cCode://C
					if (c == false) {
						cP = true;
					}
					c = true;
					break;
				case dCode://V
					if (d == false) {
						dP = true;
					}
					d = true;
					break;
				case pCode://P
					if (p == false) {
						pP = true;
					}
					p = true;
					break;
				case fCode://F
					if (f == false) {
						fP = true;
					}
					f = true;
					break;
				case 27://ESC
					if (esc == false) {
						escP = true;
					}
					esc = true;
					break;
				default :
					break;
			}
		}
		public function onKeyUp(myEvt:KeyboardEvent):void {
			keyChecked = false;
			switch (myEvt.keyCode) {
				case 37://←
				case 100://テンキー4
				case 65://A
					left = false;
					break;
				case 38://↑
				case 104://テンキー8
				case 87://W
					up = false;
					break;
				case 39://→
				case 102://テンキー6
				case 68://D
					right = false;
					break;
				case 40://↓
				case 98://テンキー2
				case 83://S
					down = false;
					break;
				case aCode://Z
				case 32://SPACE
					a = false;
					break;
				case bCode://X
					b = false;
					break;
				case cCode://C
					c = false;
					break;
				case dCode://V
					d = false;
					break;
				case pCode://P
					p = false;
					break;
				case fCode://F
					f = false;
					break;
				case 27://ESC
					esc = false;
					break;
				default :
					break;
			}
		}
		public function keyCheck():void {
			if(keyChecked == false){
				keyChecked = true;
				leftP = false;
				upP = false;
				rightP = false;
				downP= false;
				aP = false;
				bP = false;
				cP = false;
				dP = false;
				pP = false;
				fP = false;
				escP = false;
			}
		}
	}
//}