如何使用动态物理体以恒定速度移动精灵

时间:2014-11-01 09:27:05

标签: cocos2d-iphone position physics spritebuilder

直到最近我才在每次更新时更改我的精灵的x坐标,我很满意。但是昨天当我处于debugDraw模式时,我发现在某些速度之后,物理体不会与精灵正确对齐,如下所示: enter image description here 后来我被告知,(通过cocos2d论坛中的Birkemose)将物理体从A移动到B的首选方法是对它施加冲动。但我不知道如何以这种方式实现恒速。这是我用来移动它而不应用任何冲动的代码:

-(void)update:(CCTime)delta{
    rollingHero.position=ccp(rollingHero.position.x+scrollSpeed*delta,    
                         rollingHero.position.y);
    physicsNode.position=ccp(physicsNode.position.x-scrollSpeed*delta,
                         physicsNode.position.y);
}

因此,为了创造一种移动的感觉,我以相同的滚动速度滚动物理节点和相反方向的英雄。 我尝试了许多应用冲动的不同变体,但我从来没有以恒定速度移动它。速度加快,英雄脱离屏幕。如果有人发布示例代码,我将非常感激。

1 个答案:

答案 0 :(得分:5)

冲动不能使你的角色保持恒定速度的原因是因为冲动直接转化为动量的变化(因此速度的变化)。因此,如果你试图通过冲动保持恒定的速度,你必须首先检查你的精灵速度,虽然你可以非常接近恒定速度,但它不会真正恒定。

static const float kRollingHeroMoveSpeed     = 10.f;
static const float kRollingHeroAccelConstant = 10.f;

-(void)update:(CCTime)delta {

    // check velocity of sprite
    if(_rollingHero.physicsBody.velocity.x < kRollingHeroMoveSpeed) {

        // if velocity is under limit, push character
        [_rollingHero.physicsBody applyImpulse:ccp(kRollingHeroAccelConstant, 0)];
    }
}

更好的方法是进入Chipmunk2D physics engine that powers Cocos2D physics的C级。

-(void)onEnter {
    [super onEnter];

    // tell physics engine to use our C function to update physics body
    _rollingHero.physicsBody.body.body->velocity_func = playerUpdateVelocity;
}

static void playerUpdateVelocity(cpBody *body, 
                                 cpVect gravity, 
                                 cpFloat damping, 
                                 cpFloat dt) {

    // check validity of cpBody
    cpAssertSoft(body->m > 0.0f && body->i > 0.0f, "Body's mass and moment must be positive to simulate. (Mass: %f Moment: %f)", body->m, body->i);

    // update velocity and angular velocity
    body->v = cpvadd(cpvmult(body->v, damping), cpvmult(cpvadd(gravity, cpvmult(body->f, body->m_inv)), dt));
    body->w = body->w*damping + body->t*body->i_inv*dt;

    // reset force vector
    body->f = cpvzero;
    // reset torque
    body->t = 0.0f;

    // set body's velocity to desired velocity
    body->v.x = kRollingHeroMoveSpeed;
}

Here's cpBody.h on Github