【问题标题】:How to move a sprite with dynamic physics body with constant speed如何以恒定速度移动具有动态物理体的精灵
【发布时间】:2014-11-01 09:27:05
【问题描述】:

直到最近,我一直只是在每次更新时更改我的精灵的 x 坐标,我对此很满意。但是昨天在 debugDraw 模式下,我发现在一定速度后物理体不会与精灵正确对齐,如下所示: 后来我被告知,(由 Birkemose 在 cocos2d 论坛中)将物理体从 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);
}

为了营造一种移动的感觉,我以相同的滚动速度沿相反的方向滚动物理节点和英雄。 我尝试了许多不同的施加脉冲的变体,但我从来没有让它以恒定的速度移动。速度加快,英雄离开屏幕。如果有人能发布示例代码,我将不胜感激。

【问题讨论】:

    标签: cocos2d-iphone position physics spritebuilder


    【解决方案1】:

    冲动不能让你的角色保持恒定速度的原因是因为冲动直接转化为动量的变化(从而导致速度的变化)。所以如果你想通过脉冲来保持一个恒定的速度,你必须首先检查你的精灵的速度,虽然你可以非常接近一个恒定的速度,但它并不是真正的恒定。

    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.

    【讨论】:

    • 感谢完美详细的回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多