Papervision3D + BOX2D練習

by tak0294
床の上に箱を落とすFlash
♥0 | Line 118 | Modified 2009-11-11 21:02:43 | MIT License
play

ActionScript3 source code

/**
 * Copyright tak0294 ( http://wonderfl.net/user/tak0294 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/glKg
 */

package  {
   import Box2D.Collision.b2AABB;
   import Box2D.Collision.Shapes.b2PolygonDef;
   import Box2D.Common.Math.b2Vec2;
   import Box2D.Dynamics.b2Body;
   import Box2D.Dynamics.b2BodyDef;
   import Box2D.Dynamics.b2DebugDraw;
   import Box2D.Dynamics.b2World;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.materials.*;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Cube;
	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.render.BasicRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;
	import org.papervision3d.lights.*;
	import org.papervision3d.materials.shadematerials.*;
	
	/**
	 * 床の上に箱を落とすFlash
	 */
	public class Main extends Sprite {
		private var world:b2World;
		private var old_body:b2Body;

		private var body_arr:Array = new Array();
		private var body_arr3d:Array = new Array();
		private var body_count:Number = 0;

		// PV3D用基本変数
		private var viewport:Viewport3D;
		private var scene:Scene3D;
		private var camera:Camera3D;
		private var renderer:BasicRenderEngine;
		private var rootNode:DisplayObject3D;
		private var light:PointLight3D;
		
		// 床用変数
		private var floorBody1:b2Body;
		private var floor3d:Cube;
		
		public function Main():void {
			
			////////////////////////////////////////
			// 物理エンジンのセットアップ
			// 外枠を定義する
			var worldAABB:b2AABB = new b2AABB();
			worldAABB.lowerBound.Set(-100, -100);
			worldAABB.upperBound.Set(100, 100);
			
			// 重力を下方向に10m/s^2とする
			var gravity:b2Vec2 = new b2Vec2(0, 10);
			
			// 外枠と重力を指定して、物理エンジン全体をセットアップする
			world = new b2World(worldAABB, gravity, true);
			
			////////////////////////////////////////
			// 床の設置
			// 床は画面の下のほうに設置します
			
			// 床の位置を左から2.5m、上から3mとする
			var floorBodyDef:b2BodyDef = new b2BodyDef();
			floorBodyDef.position.Set(2.5, 3);
			
			// 床の形を、幅4m、厚さ20cmとする
			// 指定するのはその半分の値
			var floorShapeDef:b2PolygonDef = new b2PolygonDef();
			floorShapeDef.SetAsBox(2, 0.1);
			
			// 床を動かない物体として作る
			var floor:b2Body = world.CreateBody(floorBodyDef);
			
			floor.CreateShape(floorShapeDef);
			////////////////////////////////////////
			// 描画設定
			
			var debugDraw:b2DebugDraw = new b2DebugDraw();
			debugDraw.m_sprite = this;
			debugDraw.m_drawScale = 100; // 1mを100ピクセルにする
			debugDraw.m_fillAlpha = 1; // 不透明度
			debugDraw.m_lineThickness = 1; // 線の太さ
			//debugDraw.m_drawFlags = 0xFFFFFFFF;
			debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit;
			world.SetDebugDraw(debugDraw);

			// PV3Dの初期設定
			viewport=new Viewport3D(0, 0, true, true);
			scene=new Scene3D();
			camera=new Camera3D();
			renderer=new BasicRenderEngine();
			rootNode=scene.addChild(new DisplayObject3D("rootNode"));
			camera.zoom=30;
			camera.focus=60;
			camera.x=-400;
			camera.y=400;
			camera.target=DisplayObject3D.ZERO;
			
//			light = new PointLight3D(false);
//			light.z = 0;
//			light.x = -400;
//			light.y = 800;

			addChild(viewport);

			// PV3Dの床の設定
			var boxcolor:Array=new Array();
			for(var i:int=0; i < 6; i++)
			{
			boxcolor[i]=new ColorMaterial(Math.floor(Math.random() * 0xFFFFFF), 0.6);
			}
			var materials:MaterialsList=new MaterialsList({front:boxcolor[0], back:boxcolor[1], right:boxcolor[2], left:boxcolor[3], top:boxcolor[4], bottom:boxcolor[5]});
			floor3d=new Cube(materials, 1000, 100, 10, 4, 4);
			rootNode.addChild(floor3d);
			// イベントハンドラを登録する
			stage.addEventListener(MouseEvent.CLICK, clickHandler);
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);

		}
		
		private function clickHandler(event:MouseEvent):void {
			
			////////////////////////////////////////
			// 箱の設置
			// 箱は床の上から落として、少しはねるようにします
			
			// 箱の位置を左から2.5m、上から1mとする
			var boxBodyDef:b2BodyDef = new b2BodyDef();
			boxBodyDef.position.Set(event.stageX / 100, event.stageY / 100);
			
			// 箱の形を、幅40cm、高さ40cmとして45度ぐらい右に回す
			var boxShapeDef:b2PolygonDef= new b2PolygonDef();
			boxShapeDef.SetAsOrientedBox(0.2, 0.2, new b2Vec2(0, 0), 0);
			boxShapeDef.density = 1;      // 密度 [kg/m^2]
			boxShapeDef.restitution = 0.5;  // 反発係数、通常は0~1
			
			// 箱を動く物体として作る
			var boxBody:b2Body = world.CreateBody(boxBodyDef);
			
			body_arr[body_count] = boxBody;
			/*
			//Jointの作成
			if(old_body != null)
			{
				var distanceJD:b2DistanceJointDef = new b2DistanceJointDef();//まず			jd.body1 = this.old_body;
				//オブジェクトを2つ指定して、固定する位置を指定する。GetPosition()でオブジェクトの中心位置を取得できる。  
				distanceJD.Initialize(boxBody,old_body,boxBody.GetPosition(),old_body.GetPosition());
				
				world.CreateJoint(distanceJD);
			}
			*/
			this.old_body = boxBody;
			
			
			boxBody.CreateShape(boxShapeDef);
			boxBody.SetMassFromShapes();
			
			var boxcolor:Array = new Array();
			for(var j:int=0; j < 6; j++)
			{
				boxcolor[j]=new ColorMaterial(0x222222, 1);
			}
			//var materials=new MaterialsList({front:boxcolor[0], back:boxcolor[1], right:boxcolor[2], left:boxcolor[3], top:boxcolor[4], bottom:boxcolor[5]});
			var materials:MaterialsList = new MaterialsList({all:new GouraudMaterial(light,0xFFFFFF,0x666666)}); 
			var cube:Cube=new Cube(materials, 80, 40, 40, 4, 4);
			//マテリアル設定
			
			//var materials = new WireframeMaterial( 0x999999 );
			//materials.doubleSided = true;
			//var spe:Sphere = new Sphere(materials, 40, 8, 6);
			rootNode.addChild(cube, "cube" + body_count.toString());
			
			body_count++;
		}
		
		private function enterFrameHandler(event:Event):void {
			if (world == null) {
				return;
			}
			// Flashはデフォルトで秒間24フレームなので、
			// 物理シミュレーションを1/24秒進める
			world.Step(1 / 24, 10);
			
			for(var i:int=0; i < body_count; i++)
			{
				var bb:b2Body=body_arr[i]as b2Body;
				//if (bb == boxboy)
				{
					var cube:Cube=rootNode.getChildByName("cube" + i.toString())as Cube;
					cube.x=(bb.GetPosition().x) * 100 - 200;
					cube.y=-(bb.GetPosition().y) * 100 + 300;
					cube.rotationZ=-bb.GetAngle() * (180 / Math.PI);
					//break;
				}
			}
			
			
			renderer.renderScene(scene, camera, viewport);
		}
	}
}

Forked