static void playerUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt) { int jumpState = (ChipmunkDemoKeyboard.y > 0.0f); // Grab the grounding normal from last frame cpVect groundNormal = cpvzero; cpBodyEachArbiter(playerBody, (cpBodyArbiterIteratorFunc)SelectPlayerGroundNormal, &groundNormal); grounded = (groundNormal.y > 0.0); if(groundNormal.y < 0.0f) remainingBoost = 0.0f; // Do a normal-ish update cpBool boost = (jumpState && remainingBoost > 0.0f); cpVect g = (boost ? cpvzero : gravity); cpBodyUpdateVelocity(body, g, damping, dt); // Target horizontal speed for air/ground control cpFloat target_vx = PLAYER_VELOCITY*ChipmunkDemoKeyboard.x; // Update the surface velocity and friction // Note that the "feet" move in the opposite direction of the player. cpVect surface_v = cpv(-target_vx, 0.0); playerShape->surfaceV = surface_v; playerShape->u = (grounded ? PLAYER_GROUND_ACCEL/GRAVITY : 0.0); // Apply air control if not grounded if(!grounded){ // Smoothly accelerate the velocity playerBody->v.x = cpflerpconst(playerBody->v.x, target_vx, PLAYER_AIR_ACCEL*dt); } body->v.y = cpfclamp(body->v.y, -FALL_VELOCITY, INFINITY); }
static VALUE rb_cpflerpconst(VALUE self, VALUE f1, VALUE f2, VALUE d) { cpFloat result = cpflerpconst(NUM2DBL(f1), NUM2DBL(f2), NUM2DBL(d)); return rb_float_new(result); }