在运行时创建刚体

 

首先要感谢Emanuele Feronato给我们分享那么多精品教程,我的文章灵感也都是来自他的博客

在”掉落的苹果——b2Body“和”创建圆形刚体“中,我们学会了如果创建矩形和圆形刚体。今天我们来看看如何在运行时创建这些刚体!

首先,我们来看一下效果,在舞台任意位置按下并拖动鼠标,松开鼠标后可以创建一个矩形刚体。在创建按下鼠标前按下空格键,可以创建一个圆形刚体。

package
{
	import Box2D.Collision.b2AABB;
	import Box2D.Collision.Shapes.b2CircleDef;
	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.KeyboardEvent;
	import flash.events.MouseEvent;

	/**
	 * http://www.ladeng6666.com
	 * @author ladeng6666
	 */
	public class Main extends Sprite
	{
		private var world:b2World;
		private var body:b2Body;

		private var startX:Number = 0, startY:Number = 0;

		//实时绘制图像的画布
		private var canvas:Sprite = new Sprite();
		private var isDrawCircle:Boolean = false;
		private var rwh:Object;

		public function Main()
		{
			createWorld();
			createDebug();
			createGround();

			addChild(canvas);

			addEventListener(Event.ENTER_FRAME, loop);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
			stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, onStageKeyDown);
		}

		private function onStageKeyDown(e:KeyboardEvent):void
		{
			if (e.keyCode == 32) {
				isDrawCircle = true;
			}
		}

		private function onStageMouseUp(e:MouseEvent):void
		{
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);

			canvas.graphics.clear();
			//当空格键按下时,创建圆形刚体,否则创建矩形刚体
			if (isDrawCircle) {
				createCircle(startX, startY, rwh.radius);
			}else {
				createBox(startX + rwh.width / 2, startY + rwh.height / 2, Math.abs(rwh.width), Math.abs(rwh.height));
			}
			isDrawCircle = false;

		}

		private function onStageMouseMove(e:MouseEvent):void
		{
			canvas.graphics.clear();
			canvas.graphics.beginFill(0xff0000, 0.5);
			canvas.graphics.lineStyle(1, 0, 0.5);
			//计算宽高、半径
			rwh = getRWH(startX, startY, mouseX, mouseY);

			//当空格键按下时,绘制圆形,否则绘制矩形
			if (isDrawCircle) {
				canvas.graphics.drawCircle(startX, startY, rwh.radius);
			}else {
				canvas.graphics.drawRect(startX, startY, rwh.width, rwh.height);
			}
			canvas.graphics.endFill();
		}

		private function onStageMouseDown(e:MouseEvent):void
		{
			//鼠标按下时,记录开始的位置
			startX = mouseX;
			startY = mouseY;
			//添加鼠标移动事件侦听
			stage.addEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);
		}
		//根据鼠标点击的位置,及鼠标当前位置计算矩形的宽高和半径
		private function getRWH(px1:Number, py1:Number, px2:Number, py2:Number):Object {
			var dx:Number = px2 - px1;
			var dy:Number = py2 - py1;
			var r:Number = Math.sqrt(dx * dx + dy * dy);

			return { radius:r, width:dx, height:dy };
		}
		private function loop(e:Event):void
		{
			world.Step(1/30, 10);
		}

		private function createWorld():void
		{
			//1.创建一个环境
			var environment:b2AABB = new b2AABB();
			environment.lowerBound = new b2Vec2( -100, -100);
			environment.upperBound = new b2Vec2(100, 100);
			//2.声明重力
			var gravity:b2Vec2 = new b2Vec2(0, 10);
			//3.睡着的对象是否模拟
			var doSleep:Boolean = true;
			//4.创建b2World世界
			world = new b2World(environment, gravity, doSleep);
		}

		private function createDebug():void
		{
			var debugSprite:Sprite = new Sprite();
			addChild(debugSprite);

			var debugDraw:b2DebugDraw = new b2DebugDraw();
			debugDraw.m_sprite = debugSprite;
			debugDraw.m_drawScale = 30.0;
			debugDraw.m_fillAlpha = 0.5;
			debugDraw.m_lineThickness = 1.0;
			debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit;

			world.SetDebugDraw(debugDraw);
		}
		//创建矩形刚体
		private function createBox(posX:Number,posY:Number,w:Number,h:Number):void
		{
			//1.创建刚体需求b2BodyDef
			var bodyRequest:b2BodyDef = new b2BodyDef();
			bodyRequest.position.Set(posX / 30, posY / 30);//记得米和像素的转换关系
			//2.Box2D世界工厂更具需求创建createBody()生产刚体
			body=world.CreateBody(bodyRequest);
			//3.创建敢提形状需求b2ShapeDef的子类
			//定义形状需求是b2CircleDef圆形
			var shapeRequest:b2PolygonDef = new b2PolygonDef();
			//详细说明我们的需求
			shapeRequest.density = 3;
			shapeRequest.friction = 0.3;
			shapeRequest.restitution = 0.2;
			shapeRequest.SetAsBox(w / 2 / 30, h / 2 / 30);
			//4.b2Body刚体工厂根据需求createShape生产形状
			body.CreateShape(shapeRequest);
			body.SetMassFromShapes();

		}
		//创建圆形刚体
		private function createCircle(posX:Number, posY:Number, radius:Number):void
		{
			//1.创建刚体需求b2BodyDef
			var bodyRequest:b2BodyDef = new b2BodyDef();
			bodyRequest.position.Set(posX / 30, posY / 30);//记得米和像素的转换关系
			//2.Box2D世界工厂更具需求创建createBody()生产刚体
			body=world.CreateBody(bodyRequest);
			//3.创建敢提形状需求b2ShapeDef的子类
			//定义形状需求是b2CircleDef圆形
			var shapeRequest:b2CircleDef = new b2CircleDef();
			//详细说明我们的需求
			shapeRequest.density = 3;
			shapeRequest.friction = 0.3;
			shapeRequest.restitution = 0.2;
			shapeRequest.radius = radius/30;
			//4.b2Body刚体工厂根据需求createShape生产形状
			body.CreateShape(shapeRequest);
			body.SetMassFromShapes();
		}
		private function createGround():void
		{
			//1.创建刚体需求b2BodyDef
			var bodyRequest:b2BodyDef = new b2BodyDef();
			bodyRequest.position.Set(stage.stageWidth/2 / 30, stage.stageHeight/30);//记得米和像素的转换关系
			//2.Box2D世界工厂更具需求创建createBody()生产刚体
			body=world.CreateBody(bodyRequest);
			//3.创建敢提形状需求b2ShapeDef的子类
			var shapeRequest:b2PolygonDef = new b2PolygonDef();
			//详细说明我们的需求
			shapeRequest.density = 0;
			shapeRequest.friction = 0.3;
			shapeRequest.restitution = 0.2;
			shapeRequest.SetAsBox(stage.stageWidth/30, 1);
			//4.b2Body刚体工厂根据需求createShape生产形状
			body.CreateShape(shapeRequest);
			body.SetMassFromShapes();
		}

	}

}

源代码下载

联系作者

公众号:拉小登 | 微博:拉登Dony | B站:拉小登Excel

3 Replies to “在运行时创建刚体”

  1. 我是自学android的,涉及到了box2d,网上没什么好的教材,反倒是楼主说的那个外国网站内容不错,不过是flash开发,我起初是看那的,后来才无意看到楼主的网站,写的也不错,适合我这样基础不好的人自学,谢谢楼主了,不知道楼主后面会不会用新的api,我反正需要2.1以后的。

回复 tank

您的电子邮箱地址不会被公开。 必填项已用 * 标注