0

cocos2dx+box2d: Hello. I actually have a problem. I did a bit of rope and she behaves normally. But if the object tie two ropes, it somehow as it stops abruptly. Can anyone understand why this is happening and can help? I recorded a video with two ropes, which shows that the object sharply ostanavliaetsya. And the video with one rope, where all is well:

One rope:http://youtu.be/Yh4x8qrgmgo

Two rope: http://youtu.be/iRPVPLrC9ZQ Because of what the object may stop so abruptly?

Add Rope:

GameScene::createRope(blk1,groundBody,blk1->GetLocalCenter(), cc_to_b2Vec(580, screen.height/1) ,1.0);
    GameScene::createRope(groundBody,blk1,cc_to_b2Vec(380, screen.height/2),  blk1->GetLocalCenter() ,1.1);

Create Rope:

void GameScene::createRope(b2Body *bodyA, b2Body *bodyB, b2Vec2 anchorA, b2Vec2 anchorB, float sag)
{
    b2RopeJointDef jd;
    jd.bodyA = bodyA;
    jd.bodyB = bodyB;

    jd.localAnchorA = anchorA;
    jd.localAnchorB = anchorB;
    jd.collideConnected = true;

    // Max length of joint = current distance between bodies * sag
    float32 ropeLength = (bodyA->GetWorldPoint(anchorA)- bodyB->GetWorldPoint(anchorB)).Length()*sag;
    jd.maxLength = ropeLength;

    // Create joint
    b2RopeJoint *ropeJoint = (b2RopeJoint *)world->CreateJoint(&jd);

    VRope *newRope = new VRope(ropeJoint, _ropeSpriteSheet);
    _ropes.push_back(newRope);
}

http://youtu.be/Lchc1II3cjY - The ropes are arranged at the same height. Essentially the same object should swing up and down a bit

In fact, the rope taut, but the sprite does not look stretched, and therefore it seems that the object should swing. I do not know how to fix it ... create Rope:

void VRope::createRope(const CCPoint& pointA, const CCPoint& pointB,float distance)
{
    // 16; //12; //increase value to have less segments per rope, decrease to have more segments
    int segmentFactor = 20;
    numPoints = (int) distance/segmentFactor;

    CCPoint diffVector = ccpSub(pointB,pointA);
    float multiplier = distance / (numPoints-1);
    antiSagHack = 0.1f; //HACK: scale down rope points to cheat sag. set to 0 to disable, max suggested value 0.1
    for(int i=0;i<numPoints;i++) {
        CCPoint tmpVector = ccpAdd(pointA, ccpMult(ccpNormalize(diffVector), multiplier*i*(1-antiSagHack)));        
        VPoint *tmpPoint = new VPoint();
        tmpPoint->setPos(tmpVector.x, tmpVector.y);
        vPoints.push_back(tmpPoint);
    }
    for(int i=0;i<numPoints-1;i++) {
        VStick* tmpStick = new VStick(vPoints[i], vPoints[i+1]);
        vSticks.push_back(tmpStick);
    }

    if(spriteSheet) {
        for(int i=0;i<numPoints-1;i++) {
            VPoint* point1 = vSticks[i]->getPointA();
            VPoint* point2 = vSticks[i]->getPointB();
            CCPoint stickVector = ccpSub(ccp(point1->x,point1->y),ccp(point2->x,point2->y));
            float stickAngle = ccpToAngle(stickVector);

            float f = spriteSheet->getTextureAtlas()->getTexture()->getPixelsHigh() / CC_CONTENT_SCALE_FACTOR();
            CCRect r = CCRectMake(0, 0, multiplier, f);
            CCSprite* tmpSprite = CCSprite::createWithTexture(spriteSheet->getTexture(), r);

            ccTexParams params = {GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT};
            tmpSprite->getTexture()->setTexParameters(&params);
            tmpSprite->setPosition(ccpMidpoint(ccp(point1->x, point1->y), ccp(point2->x, point2->y)));
            tmpSprite->setRotation(-1 * CC_RADIANS_TO_DEGREES(stickAngle));
            spriteSheet->addChild(tmpSprite);
            ropeSprites.push_back(tmpSprite);
        }
    }
}

if I increase the number of segments that the rope will be stretched, but not look beautiful. and yes I cut by joint, so cutting is not accurate ....

If you increase the number of segments (reduced number of points and the rope looks like a stick)

http://youtu.be/hn8ALt2P8pE

If you increase the number of segments (reduced number of points and the rope looks like a stick) And if you reduce the surprising number of segments, it is not really too sagging look. What am I doing wrong? All code on the ropes

http://github.com/Banck/Rope

Help me please

  • Can you add your code to the post? – FuzzyBunnySlippers Jan 18 '14 at 12:11
  • From the video, it looks like your second rope is too short. You are using (probably a verlet rope) something to simulate the links for the rope, but could you add the box2d debug drawing to show the actual rope joint you are using? – FuzzyBunnySlippers Jan 18 '14 at 12:12
  • Yes, I use Verlet Rope. Second rope really short, but in fact the object should swing slightly from side to side though. – user3079929 Jan 18 '14 at 12:21
  • From your second video, it looks like the actual length of your second rope is too short. Try doubling the length of your second rope in the b2RopeJoint and I think it will swing past the "low point" as you expect. With the length you have now, it looks like it is stopping it part way through the first part of the swing. – FuzzyBunnySlippers Jan 18 '14 at 12:24
  • Second rope is short, but he still should not stop so abruptly. That debug version: http://youtu.be/ezuwMGl_ZI0 But the second video, the ropes are on odinakooy height. The object has to swing up and down a bit: http://youtu.be/Lchc1II3cjY – user3079929 Jan 18 '14 at 12:37
  • See post. Perhaps this will help... – FuzzyBunnySlippers Jan 18 '14 at 14:19

1 Answers1

1

I suspect the problem you are encountering is in setting the length of your second rope. How you set it will make the object swing more/less.

I took the default cocos2d-x box2d template and modified it to make the "swinging boxes" demo. Here is a screen shot of what it looks like:

enter image description here

There are three ropes attached to each box when it is created.

The first rope attaches a point at the top of the scene (relative to the ground box) to the block. If left to swing free, the box would swing back and forth like a pendulum.

The second rope is attached from the left side (at the height the box started at) and has a length equal to the distance from the x position of the top joint to the x position the box was created. This keeps the box from swinging "too far" to the right.

The third joint is on the attached like the second rope. It keeps the box from swinging too far to the left.

The swing looks very natural but if it is bumped by another box, it can't swing more than the original distance to the left/right. If you make them shorter, the box will only swing in the range of the shortened distance.

Here is the code I used to create the joints:

  // Calculate the local position of the
   // top of screen in the local space
   // of the ground box.
   CCSize scrSize = CCDirector::sharedDirector()->getWinSize();
   b2Vec2 groundWorldPos = b2Vec2((scrSize.width/2)/PTM_RATIO,(scrSize.height)/PTM_RATIO);
   b2Vec2 groundLocalPos = m_pGround->GetLocalPoint(groundWorldPos);

   // Now create the main swinging joint.
   b2RopeJointDef jointDef;
   jointDef.bodyA = m_pGround;
   jointDef.bodyB = body;
   jointDef.localAnchorA = groundLocalPos;
   jointDef.localAnchorB = b2Vec2(0.0f,0.0f);
   jointDef.maxLength = (groundWorldPos-body->GetWorldCenter()).Length();
   jointDef.collideConnected = true;
   world->CreateJoint(&jointDef);

   // Now create a second/third rope to "constrain" the swing.
   // These one will be attached to the side of the screen.
   b2Vec2 groundWorldPos2 = b2Vec2(0,body->GetWorldCenter().y);
   b2Vec2 groundLocalPos2 = m_pGround->GetLocalPoint(groundWorldPos2);

   jointDef.localAnchorA = groundLocalPos2;
   // Setting the length of the side rope...
   // What we want to do here is use the distance from the center as
   // the length of the rope.  Then add length to it so that the box
   // can have at least one full swing which ever side it is on (left or
   // right half of the scene).
   float32 distToCenter = (fabs(scrSize.width/2 - (body->GetWorldCenter().x)*PTM_RATIO))/PTM_RATIO;
   jointDef.maxLength = distToCenter + (scrSize.width/2)/PTM_RATIO;
   world->CreateJoint(&jointDef);

   // Now for the last rope, other side of the scene.
   // Now create a second/third rope to "constrain" the swing.
   // These one will be attached to the side of the screen.
   b2Vec2 groundWorldPos3 = b2Vec2((scrSize.width)/PTM_RATIO,body->GetWorldCenter().y);
   b2Vec2 groundLocalPos3 = m_pGround->GetLocalPoint(groundWorldPos3);
   jointDef.localAnchorA = groundLocalPos3;
   world->CreateJoint(&jointDef);

If you modify the value of distToCenter, for example multiplying it by 0.5, you will see the box will quickly "snap" to the shortened swing and then "bounce" against the other rope length as it completes the swing. Overall, the physics looks about right. You can even add more boxes by tapping and see the whole thing bounce around (something like a Newton Pendulum).

You can not connect either of the ropes and the box will be able to swing further in that direction.

The entire code solution is posted on github here.

Was this helpful?

FuzzyBunnySlippers
  • 3,387
  • 2
  • 18
  • 28
  • Thanks a lot, I realized that I just strung a rope obtained and need to increase their length. That I can do. But here's the rope itself I did not correct, it is not the sprite itself is stretched and a feeling that should swing. Maybe you would be able to help me with this problem? Two days already spent on its implementation, but was not very mean ( Can you say your email address so I can contact you, please. – user3079929 Jan 18 '14 at 14:51
  • I am not very skilled with using OpenGL to do drawing of items like ropes. In the one place where I had to draw a rope, I just drew the same sprite image many times along line from the start to the end of the rope and make sure they overlapped. Mine was not a "sagging" rope and I did not use verlets. See the effect here:http://www.youtube.com/watch?v=yDdJhqwTIWo. If you are looking for help with the rope, you should probably ask it as a separate question. – FuzzyBunnySlippers Jan 18 '14 at 15:14
  • If you increase the number of segments (reduced number of points and the rope looks like a stick) http://youtu.be/hn8ALt2P8pE If you increase the number of segments (reduced number of points and the rope looks like a stick) And if you reduce the surprising number of segments, it is not really too sagging look. What am I doing wrong? All code on the ropes github.com/Banck/Rope Help me please – user3079929 Jan 18 '14 at 18:13
  • I looked at the video. I am not sure I see the problem. If you turn off the Box2dDebug, the motion of the ropes looks "ok". You may want to increase the number of rope segments so that when they slack, they don't look like sticks. What is the problem you are seeing? – FuzzyBunnySlippers Jan 20 '14 at 12:51
  • Here in this video you can see that the object stops abruptly, and it should bounce http://www.youtube.com/watch?v=D1fuMB2f41k – user3079929 Jan 20 '14 at 13:33
  • Ropes are not springs. You could try using a b2DistanceJoint instead. They can be made a bit more spring like. A rope will pull tight when your length to it is the length of the rope. – FuzzyBunnySlippers Jan 20 '14 at 13:35