cocos2dx + box2d:对象突然停止,用两条绳子绑住 [英] cocos2dx+box2d:Object stops abruptly, tied two ropes

查看:155
本文介绍了cocos2dx + box2d:对象突然停止,用两条绳子绑住的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

cocos2dx + box2d:
您好。我实际上有问题。
我做了些绳索,她的举止正常。但是,如果物体绑住两条绳子,它会以某种方式突然停止。谁能理解为什么会这样并且可以提供帮助吗?我用两根绳子录制了一个视频,该视频显示该物体清晰地显示了ostanavliaetsya。还有一根绳子,一切都很好的视频:



一根绳子:。



这有帮助吗?


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

解决方案

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:

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?

这篇关于cocos2dx + box2d:对象突然停止,用两条绳子绑住的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆