cocos2dx + box2d:对象突然停止,绑两根绳子

时间:2014-01-18 11:47:15

标签: box2d cocos2d-x

cocos2dx + Box2D的: 你好。我其实有问题。 我做了一点绳子,她表现得很正常。但如果物体系上两根绳子,它就会以某种方式突然停止。任何人都可以理解为什么会这样,可以帮助吗?我录制了一个带有两条绳索的视频,这表明该物体陡然ostanavliaetsya。用一根绳子拍摄视频,一切都很好:

一根绳子:http://youtu.be/Yh4x8qrgmgo

两根绳子: http://youtu.be/iRPVPLrC9ZQ 因为物体可能突然停止了什么?

添加绳索:

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);

创建绳索:

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 - 绳索排列在同一高度。基本上相同的物体应该上下摆动

事实上,绳子绷紧,但精灵看起来并不拉伸,因此它似乎应该摆动。我不知道如何解决它... 创建绳索:

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);
        }
    }
}

如果我增加绳子拉伸的段数,但看起来不漂亮。是的,我用关节切割,所以切割不准确....

如果你增加了段数(减少了点数,绳子就像一根棍子)

http://youtu.be/hn8ALt2P8pE

如果你增加了细分数量(减少了点数,绳子看起来像一根棍子)如果你减少了令人惊讶的细分数量,它看起来并不是太松弛了。我究竟做错了什么?绳索上的所有代码

http://github.com/Banck/Rope

请帮帮我

1 个答案:

答案 0 :(得分:1)

我怀疑你遇到的问题是设置第二根绳子的长度。如何设置它将使对象摆动更多/更少。

我使用了默认的cocos2d-x box2d模板并对其进行了修改以制作&#34;摆动框&#34;演示。这是一个屏幕截图:

enter image description here

创建时,每个盒子上都附有三根绳索。

第一根绳子将场景顶部(相对于地面盒)的一个点连接到块上。如果让它自由摆动,盒子会像钟摆一样来回摆动。

第二根绳子从左侧(盒子开始处的高度)连接,其长度等于从顶部关节的x位置到盒子的x位置的距离。这使得盒子不会摆动太远&#34;在右边。

第三个关节就像第二根绳子一样在附着物上。它使盒子不会向左摆动太远。

挥杆看起来非常自然,但如果它被另一个箱子碰撞,它的摆动不能超过原来的左/右距离。如果你让它们变短,那么盒子只会在缩短的距离范围内摆动。

以下是我用来创建关节的代码:

  // 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);

如果您修改distToCenter的值,例如将其乘以0.5,您会看到该框会快速&#34;捕捉&#34;在缩短的挥杆然后&#34;反弹&#34;在完成挥杆时对着另一根绳索长度。总的来说,物理学看起来是对的。你甚至可以通过点击添加更多的盒子,然后看到整个物体反弹(像Newton Pendulum)。

你可以连接其中任何一根绳子,并且盒子可以朝这个方向进一步摆动。

整个代码解决方案is posted on github here

这有用吗?