public void PlayerUpdateVelocity(cpVect gravity, float damping, float dt) { bool jumpState = key.y > 0.0f; cpVect groundNormal = cpVect.Zero; mPlayerBody.EachArbiter((arbiter, o) => BodyArbiterIteratorFunc(arbiter, ref groundNormal), null); grounded = (groundNormal.y > ground); if (groundNormal.y < ground) { remainingBoost = ground; } bool boost = (jumpState && remainingBoost > ground); cpVect g = (boost ? cpVect.Zero : gravity); mPlayerBody.UpdateVelocity(g, damping, dt); float target_vx = PLAYER_VELOCITY * key.x; cpVect surface_v = new cpVect(-target_vx, 0.0f); mPlayerShape.surfaceV = surface_v; mPlayerShape.u = (grounded ? PLAYER_GROUND_ACCEL / GRAVITY : ground); if (!grounded) { mPlayerBody.v.x = cp.cpflerpconst(mPlayerBody.v.x, target_vx, PLAYER_AIR_ACCEL * dt); } mPlayerBody.v.y = cp.cpfclamp(mPlayerBody.v.y, -FALL_VELOCITY, cp.Infinity); }
public override void Update(float dt) { base.Update(dt); space.Step(dt); SetSubTitle("Place objects on the scale to weigh them. The ball marks the shapes it's sitting on.\n"); // Sum the total impulse applied to the scale from all collision pairs in the contact graph. // If your compiler supports blocks, your life is a little easier. // You can use the "Block" versions of the functions without needing the callbacks above. cpVect impulseSum = cpVect.Zero; scaleStaticBody.EachArbiter( (a, o) => ScaleIterator(scaleStaticBody, a, ref impulseSum) , null); // Force is the impulse divided by the timestep. float force = cpVect.cpvlength(impulseSum) / dt; // Weight can be found similarly from the gravity vector. cpVect g = space.GetGravity(); // cpSpaceGetGravity(); float weight = cpVect.cpvdot(g, impulseSum) / (cpVect.cpvlengthsq(g) * dt); SetSubTitle(string.Format("Total force: {0}, Total weight: {1}. ", force, weight)); // Highlight and count the number of shapes the ball is touching. int count = 0; ballBody.EachArbiter((a, o) => BallIterator(ballBody, a, ref count), null); SetSubTitle(string.Format("The ball is touching {0} shapes.", count)); CrushingContext crush = new CrushingContext(0.0f, cpVect.Zero); ballBody.EachArbiter((a, o) => EstimateCrushing(ballBody, a, ref crush), null); float crushForce = (crush.magnitudeSum - cpVect.cpvlength(crush.vectorSum)) * dt; if (crushForce > 10.0f) { SetSubTitle(string.Format("The ball is being crushed. (f: {0})", crushForce)); } else { SetSubTitle(string.Format("The ball is not being crushed. (f: {0})", crushForce)); } draw.Clear(); }
public void playerUpdateVelocity(cpBody body, cpVect gravity, float damping, float dt) { bool jumpState = (CCMouse.Instance.dblclick); // Grab the grounding normal from last frame cpVect groundNormal = cpVect.Zero; playerBody.EachArbiter( (arbiter, o) => SelectPlayerGroundNormal(arbiter, ref groundNormal) , null); grounded = (groundNormal.y > 0.0f); if (groundNormal.y < 0.0f) { remainingBoost = 0f; } // Do a normal-ish update bool boost = (jumpState && remainingBoost > 0.0f); cpVect g = (boost ? cpVect.Zero : gravity); body.UpdateVelocity(g, damping, dt); // Target horizontal speed for air/ground control float 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 = new cpVect(-target_vx, 0.0f); playerShape.surfaceV = surface_v; playerShape.u = (grounded ? PLAYER_GROUND_ACCEL / GRAVITY : 0f); // Apply air control if not grounded if (!grounded) { // Smoothly accelerate the velocity playerBody.v.x = cp.cpflerpconst(playerBody.v.x, target_vx, PLAYER_AIR_ACCEL * dt); } body.v.y = cp.cpfclamp(body.v.y, -FALL_VELOCITY, cp.Infinity); }