public override void UpdatePhysics(ActorComponent actor, float elapsed) { if (actor.PreviousState.Equals("inAir")) actor._jump = false; // update ground force based on the ground surface normal actor._groundForceVector = Vector2.Multiply(new Vector2(-actor._groundSurfaceNormal.Y, actor._groundSurfaceNormal.X), actor._groundSurfaceForce); // set desired ground velocity if (actor._GroundObject == null || actor._GroundObject.Physics == null) actor._groundVelocity = actor._groundForceVector; else actor._groundVelocity = actor._groundForceVector + actor._GroundObject.Physics.Velocity; // modify movement and increment inherited velocity actor._moveAccel = actor._groundAccel * elapsed * (float)Math.Pow(actor._groundFriction, 1.5); actor._moveDecel = actor._groundDecel * elapsed * (float)Math.Pow(actor._groundFriction, 1.5); // inherit ground velocity if (actor._inheritedVelocity != actor._groundVelocity) { float incrementX = (actor._groundVelocity.X - actor._inheritedVelocity.X) * (float)Math.Pow(actor._groundFriction, 2); float incrementY = (actor._groundVelocity.Y - actor._inheritedVelocity.Y) * (float)Math.Pow(actor._groundFriction, 2); actor._inheritedVelocity.X += incrementX; actor._inheritedVelocity.Y += incrementY; if (Math.Abs(actor._groundVelocity.X - actor._inheritedVelocity.X) < actor._groundAccel * actor._groundFriction) actor._inheritedVelocity.X = actor._groundVelocity.X; if (Math.Abs(actor._groundVelocity.Y - actor._inheritedVelocity.Y) < actor._groundAccel * actor._groundFriction) actor._inheritedVelocity.Y = actor._groundVelocity.Y; } // move in the direction specified, or slow to a stop based on damping if (actor._moveLeft) { actor._moveSpeed.X -= actor._moveAccel; } else if (actor._moveRight) { actor._moveSpeed.X += actor._moveAccel; } else { if (Math.Abs(actor._moveSpeed.X) > actor._moveDecel) { int dirMod; if (actor._moveSpeed.X < 0) dirMod = -1; else dirMod = 1; actor._moveSpeed.X -= actor._moveDecel * dirMod; } else { actor._moveSpeed.X = 0; } } // clamp move speed to maxMoveSpeed actor._moveSpeed.X = MathHelper.Clamp(actor._moveSpeed.X, -actor._maxMoveSpeed, actor._maxMoveSpeed); // get the modified movement vector if (actor._groundObject != null && !actor._groundSurfaceNormal.Equals(new Vector2(0, -1))) { // angled ground object: find walk vector actor._moveVector = Vector2.Multiply(new Vector2(-actor._groundSurfaceNormal.Y, actor._groundSurfaceNormal.X), actor._moveSpeed.X); } else { // no ground object or flat ground object: zero "Y walk" actor._moveVector = new Vector2(actor._moveSpeed.X, 0); } // apply move vector to actor velocity actor._actor.Physics.Velocity = actor._moveVector; // apply ground force actor._actor.Physics.Velocity += actor._inheritedVelocity; // do jumping if (actor._JumpingDown && actor._groundObjectComponent is OneWayPlatformComponent) { // clear the active platforms list so we stop colliding with these platforms actor._activePlatforms.Clear(); // set the animation state FSM.Instance.SetState(actor._animationManager, "fall"); // manually override the 'on ground' state actor._onGround = false; // use the jump-down event and any regular jump event // (this is to specifically allow for pushy controllers to just send both jump // events when a jump-down condition is met on the controller side and // not have to worry about what kind of platform the actor is on. // See PlayerController in the PlatformerDemo) actor._jumpDown = false; actor._jump = false; // record this as the last time we jumped down actor._lastJumpDownTime = TorqueEngineComponent.Instance.TorqueTime; } else if (actor._Jumping && !actor.IsMaxJumpTime()) { actor.jumpDuration += (elapsed / 100); // jump up actor._actor.Physics.VelocityY = actor._groundVelocity.Y - (actor._jumpForce * ((float)Math.Exp(actor.jumpDuration) / 2)); // set the appropriate animation state for jumping if (Math.Abs(actor._moveSpeed.X) < 0.01f) FSM.Instance.SetState(actor._animationManager, "jump"); else FSM.Instance.SetState(actor._animationManager, "runJump"); // override the 'on ground' state manually // (this allows the animation manager, among other things // to react to jumping properly) actor._onGround = false; // set actor's jump flag to false // (we used the jump 'event' - let's turn it off so it's not used again) // (without this, it's possible to launch yourself up crazy distances // by jumping off the ground through a ladder.. or 'something') // (we also want to cancel the jump-down flag in case a lazy // controller sent both events) actor._jump = false; actor._jumpDown = false; actor.isJumping = true; } else { actor._jump = false; actor.isJumping = false; actor.jumpDuration = 0.0f; } }
public override void UpdatePhysics(ActorComponent actor, float elapsed) { // air-based control actor._moveAccel = actor._airAccel * elapsed; actor._moveDecel = actor._airDecel * elapsed; // move in the direction specified, or slow to a stop based on damping if (actor._moveLeft) { actor._moveSpeed.X -= actor._moveAccel; } else if (actor._moveRight) { actor._moveSpeed.X += actor._moveAccel; } else { if (Math.Abs(actor._moveSpeed.X) > actor._moveDecel) { int dirMod; if (actor._moveSpeed.X < 0) dirMod = -1; else dirMod = 1; // only dampen moveSpeed if the resulting speed is not faster if (Math.Abs((actor._moveSpeed.X + actor._inheritedVelocity.X) - (actor._moveDecel * dirMod)) <= Math.Abs(actor._moveSpeed.X + actor._inheritedVelocity.X)) actor._moveSpeed.X -= actor._moveDecel * dirMod; } else { actor._moveSpeed.X = 0; } } // clamp move speed to maxMoveSpeed if (actor._inheritedVelocity.X > 0) actor._moveSpeed.X = MathHelper.Clamp(actor._moveSpeed.X, -actor._maxMoveSpeed - actor._inheritedVelocity.X, actor._maxMoveSpeed); else actor._moveSpeed.X = MathHelper.Clamp(actor._moveSpeed.X, -actor._maxMoveSpeed, actor._maxMoveSpeed - actor._inheritedVelocity.X); // apply x velocity to actor actor._actor.Physics.VelocityX = actor._moveSpeed.X; // apply X ground force actor._actor.Physics.VelocityX += actor._inheritedVelocity.X; // apply gravity actor._actor.Physics.VelocityY += actor.Gravity * elapsed; // do pressure sensitive jumping if (actor._Jumping && actor.isJumping) { actor.jumpDuration += (elapsed / 100); if (!actor.IsMaxJumpTime()) { actor._actor.Physics.VelocityY = actor._groundVelocity.Y - (actor._jumpForce * ((float)Math.Exp(actor.jumpDuration) / 2)); // set the appropriate animation state for jumping if (Math.Abs(actor._moveSpeed.X) < 0.01f) FSM.Instance.SetState(actor._animationManager, "jump"); else FSM.Instance.SetState(actor._animationManager, "runJump"); actor._jump = false; actor._jumpDown = false; actor._onGround = false; } } else { actor._jump = false; // this prevents the little bounce at the end of the jump actor.isJumping = false; actor.jumpDuration = 0.0f; } }