11RIA 闪客社区 - 最赞 Animate Flash 论坛

搜索
查看: 2068|回复: 0
上一主题 下一主题

[2D 物理引擎] 【9RIA—ladeng6666】—【Box2D系列教程 5】在运行时创建刚体

[复制链接] TA的其它主题
发表于 2018-2-5 15:57:29 | 显示全部楼层 |阅读模式

【游客模式】——注册会员,加入11RIA 闪客社区吧!一起见证Flash的再次辉煌……

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

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


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



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

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

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



[Actionscript3] 纯文本查看 复制代码
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;

    /**
     * [url]http://www.ladeng6666.com[/url]
     * @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();
        }

    }

}



下载:
OK 2012-06-09 在运行时创建刚体.rar (439.54 KB, 下载次数: 1)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

感谢所有支持论坛的朋友:下面展示最新的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)



快速回复 返回顶部 返回列表