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

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

[2D 物理引擎] 【9RIA—ladeng6666】—【Box2D系列教程 20】Box2D 关节——”马达关节” b2RevoluteJoint

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

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

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

x
本帖最后由 TKCB 于 2018-2-6 13:05 编辑

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


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



昨天我们学习了Box2D 的"距离关节"b2DistanceJoint,并用它模拟了一个简单的自行车。今天我们来学习"马达关节" b2RevoluteJoint 。

"马达关节"b2RevoluteJoint同样连接了两个刚体bodyA和bodyB。不过和"马达关节"不同的是,它只有一个节点anchor,所以两个刚体都只能围绕这一个节点选择。另外,我们可以在这个节点anchor位置施加一个作用力maxMotorTorque,这样节点就会想马达一样转起来,所以我把它叫做"马达关节"。

还是不好理解,对吧!那就再打个比方,我把b2RevoluteJoint关节比作....电风扇。风扇叶是bodyA,马达是anchor,底座是bodyB,下面的图可以更好的解释这一点:

QQ截图20180205174159.jpg
如上图所示,因为节点anchor在bodyA的圆心处,所以bodyA会围绕着节点anchor旋转。

b2RevoluteJoint的initialize方法结构如下:

[Actionscript3] 纯文本查看 复制代码
public function Initialize(
        bA:b2Body,
        bB:b2Body,
        anchor:b2Vec2
    ) : void


bA即bodyA,bB即bodyB,anchor即节点,具体的功能,我在前面都讲过了,就不再赘述了。
另外,如前面提到的,通过设置b2RevoluteJointDef的maxMotorTorque、motorSpeed和enableMotor,可以模拟马达旋转。这三个参数的作用分别如下:
    enableMotor:决定是否使用
    motormotorSpeed:设置最大的角速度
    maxMotorTorque:要达到角速度应用的扭矩力这三个属性是让节点转起来的必要条件,缺一不可!记住哦。

用b2RevoluteJoint实现风扇的效果如下:


完整的代码和注释如下:
[Actionscript3] 纯文本查看 复制代码
package
{
    import Box2D.Collision.Shapes.b2PolygonShape;
    import Box2D.Collision.Shapes.b2Shape;
    import Box2D.Common.Math.b2Vec2;
    import Box2D.Dynamics.b2Body;
    import Box2D.Dynamics.b2BodyDef;
    import Box2D.Dynamics.b2FixtureDef;
    import Box2D.Dynamics.b2World;
    import Box2D.Dynamics.Joints.b2RevoluteJoint;
    import Box2D.Dynamics.Joints.b2RevoluteJointDef;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;

    /**
     * [url=http://www.ladeng6666.com]http://www.ladeng6666.com[/url]
     * @author ladeng6666
     */
    public class RevoluteJointTest extends Sprite
    {
        private var world:b2World;
        private var debugSprite:Sprite;
        private var bodyA:b2Body, bodyB:b2Body;
        private var posA:Point, posB:Point;

        public function RevoluteJointTest()
        {
            LDEasyBox2D.stage = stage;
            world=LDEasyBox2D.createWorld();
            debugSprite=LDEasyBox2D.createDebug(world);
            addChild(debugSprite);

            //创建地面,
            LDEasyBox2D.createWrapWall(world, stage);
            createBodies();

            createRevoluteJoint();

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

        private function createRevoluteJoint():void
        {
            //创建马达关节需求
            var revoluteJoint:b2RevoluteJointDef = new b2RevoluteJointDef();
            //用bodyA、bodyB和anchor节点初始化马达关节
            revoluteJoint.Initialize( bodyA, bodyB, new b2Vec2(posA.x / 30, posA.y / 30));
            //设置连接的两个刚体之间不进行碰撞检测
            revoluteJoint.collideConnected = false;
            //开启马达
            revoluteJoint.enableMotor = true;
            //设置马达的最大角速度,单位为 弧度/秒,如设置为Math.PI,即每秒钟转180度
            revoluteJoint.motorSpeed = Math.PI;
            //设置最大的扭力值
            revoluteJoint.maxMotorTorque = 500;
            //创建马达关节
            world.CreateJoint(revoluteJoint);
        }
        //创建bodyA和bodyB刚体
        private function createBodies():void
        {
            //设置两个刚体的坐标位置
            posA = new Point(275, 100);
            posB = new Point(275, 300);
            //创建一个十字刚体,赋值给bodyA
            var bodyDef:b2BodyDef = new b2BodyDef();
            bodyDef.type = b2Body.b2_dynamicBody;
            bodyDef.position.Set(posA.x / 30, posA.y / 30);
            bodyA = world.CreateBody(bodyDef);
            //设置刚体属性
            var fixtureDef:b2FixtureDef = new b2FixtureDef();
            fixtureDef.density = 3;
            fixtureDef.restitution = .2;
            fixtureDef.friction = .2;

            //设置刚体形状,并赋值给fixtureDef
            //一个横着的矩形
            var shape:b2PolygonShape = new b2PolygonShape();
            shape.SetAsBox(50/30, 5/30);
            fixtureDef.shape = shape;
            bodyA.CreateFixture(fixtureDef);
            //加一个竖着的矩形
            shape.SetAsBox(5 / 30, 50 / 30);
            fixtureDef.shape = shape;
            //生成刚体bodyA的形状
            bodyA.CreateFixture(fixtureDef);

            //创建bodyB刚体
            bodyB = LDEasyBox2D.createBox(world, posB.x, posB.y, 200, 50);
        }

        private function onStageMouseDown(e:MouseEvent):void
        {
            var dragBody:b2Body = LDEasyBox2D.getBodyAtMouse(world);
            if (dragBody != null) {
                LDEasyBox2D.startDragBody(world,dragBody,10000*dragBody.GetMass());
            }

        }

        private function onStageMouseUp(e:MouseEvent):void
        {
            LDEasyBox2D.stopDragBody(world);
        }

        private function loop(e:Event):void
        {
            LDEasyBox2D.updateWorld(world);

        }

    }

}

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐 上一条 /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)



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