zoukankan      html  css  js  c++  java
  • Hello Box2dAs3

    以前做化学课件,发现Flash里处理对象的碰撞是个很麻烦的问题,即使是对于规则的对象,比如某个仪器(滴管,试剂瓶等),也查过很多资料来解决碰撞问题,但都很复杂,看了后一头雾水。一次偶然发现box2dAs3,它竟然能把对象碰撞模拟得如此真实,并且Box2dAs3中处理碰撞并不需要开发者处理,开发者只需要创建一个一个的对象(box2d中称为刚体),它会自动处理每个刚体的碰撞,即物理特性。下面是我的第一篇关于box2dAs3的入门。

    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;
    	
    	/**
    	 * Box2dAs3 Version 2.0.1 
    	 * @author ywxgod--http://www.cnblogs.com/ywxgod/
    	 * 
    	 */
    	[SWF(backgroundColor="333333",frameRate="30",width="550",height="400")]
    	public class HelloBox2dAs3 extends Sprite 
    	{
    		private var physcale:Number = 30.0;
    		private var timeStep:Number = 1 / physcale;
    		private var iteration:int = 10;
    		
    		private var body:b2Body;
    		private var world:b2World;
    		
    		private const FLOOR_WIDTH:int = 550;
    		private const FLOOR_HEIGHT:int = 20;
    		private const WALL_WIDTH:int = 20;
    		private const WALL_HEIGHT:int = 400;
    		
    		private var maxBodysNum:int = 50;
    		private var count:int = 0;
    		
    		public function HelloBox2dAs3():void 
    		{
    			init();
    		}
    		
    		private function init():void 
    		{
    			createWorld();
    			createFloorAndWalls();
    			showDebuger();
    			run();
    			addEventListener(Event.ENTER_FRAME,onFrame);
    		}
    		
    		private function createWorld():void 
    		{
    			var aabb:b2AABB = new b2AABB();
    			aabb.lowerBound.Set( -100, -100);
    			aabb.upperBound.Set(100, 100);
    			var gravity:b2Vec2 = new b2Vec2(0, 9.8);
    			world = new b2World(aabb, gravity, true);
    		}
    		
    		private function createFloorAndWalls():void 
    		{
    			var floorShapeDef:b2PolygonDef = new b2PolygonDef();
    			floorShapeDef.density = 0;
    			floorShapeDef.friction = 0.3;
    			floorShapeDef.restitution = 0.4;
    			floorShapeDef.SetAsBox(FLOOR_WIDTH / 2 / physcale, FLOOR_HEIGHT / 2 / physcale);
    			var floorBodyDef:b2BodyDef = new b2BodyDef();
    			floorBodyDef.position.Set(FLOOR_WIDTH / 2 / physcale, (WALL_HEIGHT-FLOOR_HEIGHT/2) / physcale);
    			var floorBody:b2Body = world.CreateBody(floorBodyDef);
    			floorBody.CreateShape(floorShapeDef);
    			floorBody.SetMassFromShapes();
    			
    			var leftWallShapeDef:b2PolygonDef = new b2PolygonDef();
    			leftWallShapeDef.density = 0;
    			leftWallShapeDef.friction = 0.3;
    			leftWallShapeDef.restitution = 0.4;
    			leftWallShapeDef.SetAsBox(WALL_WIDTH / 2 / physcale, WALL_HEIGHT / 2 / physcale);
    			var leftWallBodyDef:b2BodyDef = new b2BodyDef();
    			leftWallBodyDef.position.Set(WALL_WIDTH / 2 / physcale, (WALL_HEIGHT / 2) / physcale);
    			var leftWallBody:b2Body = world.CreateBody(leftWallBodyDef);
    			leftWallBody.CreateShape(leftWallShapeDef);
    			leftWallBody.SetMassFromShapes();
    			
    			var rightWallShapeDef:b2PolygonDef = new b2PolygonDef();
    			rightWallShapeDef.density = 0;
    			rightWallShapeDef.friction = 0.3;
    			rightWallShapeDef.restitution = 0.4;
    			rightWallShapeDef.SetAsBox(WALL_WIDTH / 2 / physcale, WALL_HEIGHT / 2 / physcale);
    			var rightWallBodyDef:b2BodyDef = new b2BodyDef();
    			rightWallBodyDef.position.Set((FLOOR_WIDTH-WALL_WIDTH / 2) / physcale, (WALL_HEIGHT / 2) / physcale);
    			var rightWallBody:b2Body = world.CreateBody(rightWallBodyDef);
    			rightWallBody.CreateShape(rightWallShapeDef);
    			rightWallBody.SetMassFromShapes();
    		}
    		
    		private function createActors(count:int):void 
    		{
    			
    			var boxShapeDef:b2PolygonDef = new b2PolygonDef();
                     boxShapeDef.density = 2;
                     boxShapeDef.friction = 0.3;
                     boxShapeDef.restitution = 0.4;
                     boxShapeDef.SetAsBox(40 / 2 / physcale, 15 / 2 / physcale);
                     var boxShapeBodyDef:b2BodyDef = new b2BodyDef();
                     boxShapeBodyDef.position.Set((275) / physcale, (-count*15) / physcale);
                     var boxShapeBody:b2Body = world.CreateBody(boxShapeBodyDef);
                     boxShapeBody.CreateShape(boxShapeDef);
                     boxShapeBody.SetMassFromShapes();
    		}
    		
    		private function onFrame(e:Event):void
    		{
    			world.Step(timeStep, iteration);
    			
    			if (count--<5&&world.m_bodyCount< maxBodysNum)
    			{
    				createActors(count);
    				count = 5;
    			}
    		}
    		
    		private function showDebuger():void
    		{
    			var sprite:Sprite = new Sprite();
    			addChild(sprite);
    			var dbg:b2DebugDraw = new b2DebugDraw();
    			dbg.m_sprite = sprite;
    			dbg.m_alpha = 0.5;
    			dbg.m_drawScale = physcale;
    			dbg.m_drawFlags = b2DebugDraw.e_obbBit;
    			dbg.m_fillAlpha = 0.5;
    			world.SetDebugDraw(dbg);
    		}
    		
    		private function run():void 
    		{
    			
    		}
    	}
    	
    }

    18行 定义swf文件的舞台背景,帧频,宽度,高度

    21-23行 定义物理世界与flash世界中长度单位,box2d模拟频率及迭代次数

    50-57行 创建一个物理世界world,所有的刚体都是存在其中,world的作用就像flash中的stage,所有的显示对象都被添加到stage一样。创建world需要三个参数:边界盒,重力加速度,是否休眠。

    59-93行 创建地面,墙壁等。

    95-108行 创建方形刚体,跟59-93行中唯一不同的地方是密度的赋值。

    110-119行 在EnterFrameEvent中创建刚体。

    121-132行 利用box2dAs3本身的调试显示函数来显示创建的刚体。因为box2das3中没有显示对象的概念,所以无法像flash添加显示对象到舞台一样去做了。

    总结:

      1。flash中的长度是以像素为单位,box2d中的长度是以米为单位,且一米等于30个像素。

      2。flash中有显示对象,且显示对象都是位于stage上,box2d中有刚体,且刚体都是存在于world中。

      3。flash中创建对象是需要制定其宽度和高度,box2d中定义形状只需要其高度宽度的各一半。

      4。创建刚体的步骤:

        a。定义形状,在形状定义中定义摩擦系数friction,反弹系数restitution,密度density,形状的大小SetAsBox

        b。刚体定义,在刚体定义中设置刚体的位置position

        c。创建刚体,传入刚体定义,由world来创建刚体

        d。创建于刚体关联的形状,传入形状定义,有刚体来创建自己关联的形状。

        e。设置质量。

      5。设置b2DebugDraw时的参数

        a。m_sprite 用来显示刚体的显示对象

        b。m_alpha 显示对象的透明度

        c。m_drawScale 放大系数,这个只应该跟长度单位相同,否则显示的刚体将会只有原来的1/30。

        d。m_fillAlpha 绘制刚体时的填充色透明度。

        e。m_drawFlags 标志,告诉b2DebugDraw要绘制刚体哪些相关属性,具体值为b2DebugDraw.e_obbBit,b2DebugDraw.e_aabbBit,b2DebugDraw.e_centerOfMassBit等,也可以是几个值的和。

  • 相关阅读:
    【Prince2科普】衡量绩效的六大要素
    项目组合管理、项目集管理、项目管理和组织级项目管理之间的关系
    javascript中关系运算符的整理
    javascript中数组的基础----length和元素的求和
    回调函数和递归函数的应用
    谷歌浏览器打开时显示的是搜狗
    二级导航栏的立体显示
    利用css写的中英文切换的导航栏菜单
    javascript中的对象浅谈
    javascript中逻辑运算符总结
  • 原文地址:https://www.cnblogs.com/ywxgod/p/1690935.html
Copyright © 2011-2022 走看看