2014-11-01 1 views
1

До недавнего времени я просто менял координату x моего спрайта на каждое обновление, и я был доволен этим. Но вчера, когда я находился в режиме debugDraw, я узнал, что после определенной физики физика скорости не будет правильно выравниваться со спрайтом, например: enter image description here Позже мне сообщили, что (по Birkemose в форуме cocos2d) предпочтительный способ переместить физическое тело от А к В - применить к нему импульс. Но я понятия не имею, как достичь постоянной скорости таким образом. Это код, который я использовал, чтобы переместить его без применения какого-либо импульса:Как перемещать спрайт с динамическим физическим телом с постоянной скоростью

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

Так, чтобы создать ощущение перемещения прокручивает узел физики и герой в противоположных направлениях с одинаковой скоростью прокрутки. Я пробовал много разных вариантов применения импульсов, но я никогда не двигался с постоянной скоростью. Скорость ускоряется, и герой получает заставку. Я был бы очень признателен, если бы кто-то разместил образец кода.

ответ

4

Причина, по которой импульс не работает, чтобы поддерживать персонаж на постоянной скорости, заключается в том, что импульс преобразуется непосредственно в изменение импульса (и, следовательно, изменение скорости). Поэтому, если вы попытаетесь поддерживать постоянную скорость через импульс, вам сначала нужно будет проверить скорость вашего спрайта, и хотя вы можете приблизиться к постоянной скорости, это не будет по-настоящему постоянным.

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

Лучший способ сделать это, чтобы выйти на уровень C в Chipmunk2D physics engine that powers Cocos2D physics.

-(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.

+0

Спасибо за прекрасный и подробный ответ –