Box2d弹力绳接头

时间:2012-02-07 06:29:37

标签: box2d-iphone

我正在写一个游戏,我需要编制一根绳子。我用b2RopeJoint做了它,但在那里我没有找到机会让它变得有弹性。 然后我找了b2DistanceJoint,一切都很酷,有弹性,但我找不到设置限制只能达到最大距离的能力(没有最小距离)。

我该怎么做?

4 个答案:

答案 0 :(得分:5)

试试这个。

-(void) CreateElasticRope {
    //=======Params
    // Position and size
    b2Vec2 lastPos = b2Vec2(4,4); //set position first body
    float widthBody = 0.35;
    float heightBody = 0.1;
    // Body params
    float density = 0.05;
    float restitution = 0.5;
    float friction = 0.5;
    // Distance joint
    float dampingRatio = 0.0;
    float frequencyHz = 0;
    // Rope joint
    float kMaxWidth = 1.1;
    // Bodies
    int countBodyInChain = 15;
    b2Body* prevBody;

    //========Create bodies and joints
    for (int k = 0; k < countBodyInChain; k++) {
        b2BodyDef bodyDef;
        if(k==0 ) bodyDef.type = b2_staticBody; //first body is static
        else bodyDef.type = b2_dynamicBody;
        bodyDef.position = lastPos;
        lastPos += b2Vec2(2*widthBody, 0); //modify b2Vect for next body
        bodyDef.fixedRotation = YES;
        b2Body* body = world->CreateBody(&bodyDef);

        b2PolygonShape distBodyBox; 
        distBodyBox.SetAsBox(widthBody, heightBody);
        b2FixtureDef fixDef;
        fixDef.density = density;
        fixDef.restitution = restitution;
        fixDef.friction = friction;
        fixDef.shape = &distBodyBox;
        body->CreateFixture(&fixDef);
        body->SetHealth(9999999);
        body->SetLinearDamping(0.0005f);

        if(k>0) {
            //Create distance joint
            b2DistanceJointDef distJDef;
            b2Vec2 anchor1 = prevBody->GetWorldCenter();
            b2Vec2 anchor2 = body->GetWorldCenter();
            distJDef.Initialize(prevBody, body, anchor1, anchor2);
            distJDef.collideConnected = false;
            distJDef.dampingRatio = dampingRatio;
            distJDef.frequencyHz = frequencyHz;
            world->CreateJoint(&distJDef);

            //Create rope joint
            b2RopeJointDef rDef;
            rDef.maxLength = (body->GetPosition() - prevBody->GetPosition()).Length() * kMaxWidth;
            rDef.localAnchorA = rDef.localAnchorB = b2Vec2_zero;
            rDef.bodyA = prevBody;
            rDef.bodyB = body;
            world->CreateJoint(&rDef);

        } //if k>0
        prevBody = body;
    } //for 
}

答案 1 :(得分:1)

这里有一个2.2风格的ropejoint实现:https://github.com/aaronfarr/box2Dweb

答案 2 :(得分:0)

您可以同时使用绳索关节和距离关节。使绳索接头的距离比距离接头稍长。

答案 3 :(得分:0)

从Box2D测试平台示例中,我修改了“Web”示例,如下所示:

#ifndef ELASTICROPE_H
#define ELASTICROPE_H

#define NUM_JOINTS  7
#define NUM_LINKS   8


class ElasticRope : public Test
{

public:
    ElasticRope()
    {
        b2Body* ground = NULL;
        {
            b2BodyDef bd;
            ground = m_world->CreateBody(&bd);

            b2EdgeShape shape;
            shape.Set(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
            ground->CreateFixture(&shape, 0.0f);
        }

        {
            b2CircleShape shape;
            shape.m_radius = 0.8f;

            // create bodies
            for (int b = 0; b < NUM_LINKS; b++) {
                b2BodyDef bd;
                bd.type = b2_dynamicBody;

                bd.position.Set(5.0f, NUM_LINKS-b);
                m_bodies[b] = m_world->CreateBody(&bd);
                m_bodies[b]->CreateFixture(&shape, 5.0f);
            }

            for (int j = 0; j < NUM_JOINTS; j++) {
                b2DistanceJointDef jd;
                b2Vec2 p1, p2, d;
                jd.frequencyHz = 5.0f;
                jd.dampingRatio = 1.0f;

                jd.bodyA = m_bodies[j];
                jd.bodyB = m_bodies[j+1];

                m_joints[j] = m_world->CreateJoint(&jd);
            }
        }
    }

    void Step(Settings* settings)
    {
        Test::Step(settings);
        m_debugDraw.DrawString(5, m_textLine, "This demonstrates an elastic rope.");
        m_textLine += DRAW_STRING_NEW_LINE;
    }

    void JointDestroyed(b2Joint* joint)
    {
        for (int32 i = 0; i < 8; ++i)
        {
            if (m_joints[i] == joint)
            {
                m_joints[i] = NULL;
                break;
            }
        }
    }

    static Test* Create()
    {
        return new ElasticRope;
    }

    b2Body* m_bodies[NUM_LINKS];
    b2Joint* m_joints[NUM_JOINTS];
};

#endif // ELASTICROPE_H

它远非完美,但可能是一个起点。