9RIA-ladeng6666 发表于 2018-2-5 15:57:29

【9RIA—ladeng6666】—【Box2D系列教程 5】在运行时创建刚体


转载:9RIA游戏开发者社区(天地会)
作者:ladeng6666(拉登大叔)
作者博客:http://www.ladeng6666.com/blog/


【Box2D系列教程-导航帖】—拉登大叔出品(总贴)



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

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

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

attach://773.swf

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();
      }

    }

}


下载:

页: [1]
查看完整版本: 【9RIA—ladeng6666】—【Box2D系列教程 5】在运行时创建刚体

感谢所有支持论坛的朋友:下面展示最新的5位赞助和充值的朋友……更多赞助和充值朋友的信息,请查看:永远的感谢名单

SGlW(66139)、 anghuo(841)、 whdsyes(255)、 longxia(60904)、 囫囵吞澡(58054)

下面展示总排行榜的前3名(T1-T3)和今年排行榜的前3名的朋友(C1-C3)……更多信息,请查看:总排行榜今年排行榜

T1. fhqu1462(969)、 T2. lwlpluto(14232)、 T3. 1367926921(962)  |  C1. anghuo(147)、 C2. fdisker(27945)、 C3. 囫囵吞澡(58054)