Box2d эластичное тросовое соединение - PullRequest
4 голосов
/ 07 февраля 2012

Я пишу игру, и мне нужно сделать веревку. Я сделал это с помощью b2RopeJoint, но там я не нашел возможности сделать его эластичным. Потом я искал b2DistanceJoint, все круто с эластичностью, но я не могу найти возможность установить ограничение только на максимальное расстояние (без минимального).

Как я могу это сделать?

Ответы [ 4 ]

5 голосов
/ 08 февраля 2012

Попробуйте это.

-(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 голос
/ 09 мая 2013

Здесь есть реализация соединения канатов в стиле 2.2: https://github.com/aaronfarr/box2Dweb

0 голосов
/ 13 ноября 2013

Из примера тестового стенда 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

Это далеко от совершенства, но может быть отправной точкой.

0 голосов
/ 11 июня 2012

Вы можете использовать как тросовое, так и дистанционное соединение.Сделайте расстояние между канатным соединением немного больше, чем расстояние.

...