在运行时创建刚体
首先要感谢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(); } } }
联系作者
很不错的例子!学习了
我是自学android的,涉及到了box2d,网上没什么好的教材,反倒是楼主说的那个外国网站内容不错,不过是flash开发,我起初是看那的,后来才无意看到楼主的网站,写的也不错,适合我这样基础不好的人自学,谢谢楼主了,不知道楼主后面会不会用新的api,我反正需要2.1以后的。
后面的教程都更新成2.1了,欢迎你继续关注!