How to implement a physics engine?

How can I implement a "boost pad" with Farseer/Box2D physics?

  • I'm trying to implement a boost pad in my XNA game using the Farseer Physics Engine. (This question applies to Box2D too, I would be happy to port working Box2D code to C#.) By "boost pad", I mean an object that can apply a force to the player that makes him go faster than he usually can under normal circumstances. These are most often seen in non-realistic racing games (e.g., Mario Kart, F-Zero). (For the record, my particular game is a 2D side-scroller.) I use a very simple Farseer physics Body for my player: it's just a square shape with basic linear velocity. Normally, I move my player like this: body.ApplyForce(ConvertUnits.ToSimUnits(force)); Then, in my Update loop method, I cap the player velocity like this (to make sure the player speed never goes above maxSpeed): float speed = body.LinearVelocity.Length(); if (speed > maxSpeed) body.LinearVelocity = (maxSpeed / speed) * velocity; I'm struggling to think of a good way to implement a boost pad. The issues: What would be a good way to enforce two separate max speeds? There's one maximum speed for forces that are applied by normal player input, and another maximum speed for forces applied by boost pads. If the character is going faster than the normal max speed (e.g., they just hit a boost pad), how can I still allow the player to influence his direction without increasing his overall speed?

  • Answer:

    I wouldn't cap the player velocity like that. Instead, cap the velocity vector that comes out of your steering behaviour(s), and then apply any extra forces (ie. from explosions, boost pads, etc.). You can then cap those extra forces before combining them with the forces coming from your steering behaviours. edit For example, something like: var desiredVelocity = Vector2.Zero; if (/* player can control */) { desiredVelocity = Vector2.Normalize(target - this.CurrentPosition) * this.MaxSpeed; } var additionalVelocity = Vector2.Zero; if (/* criteria for "boosting" */) additionalVelocity = /* whatever you want */ var resultantVelocity = desiredVelocity + additionalVelocity; An example of a time when a player might not be able to apply a force might be if they are airborne for eg. I took this code from my game, which has an overhead perspective, but your target could just be a unit vector to the left or right of the CurrentPosition, or anywhere if there was a jetpack or something.

Michael at Game Development Visit the source

Was this solution helpful to you?

Other answers

I gave this a try and the results I got look fine to me. http://www.youtube.com/watch?v=v2flqMBoDcc (although YouTube messed up the framerate). The only thing I did was multiply both the maximum speed and the forces by some arbitrary boost multiplier. Multiplying the maximum speed addresses your first question - The two separate maximum speeds become maxSpeedand maxSpeed * boostMultiplier respectively. But I noticed that the body lost responsiveness due to the increased speed. Multiplying the forces by the same ratio seemed to solve the problem. The body is still as responsive as before. If the video seems to be what you're looking for, here's the code: bool hasBoost = Keyboard.GetState().IsKeyDown(Keys.Space); float boostMultiplier = hasBoost ? 4f : 1f; if (Keyboard.GetState().IsKeyDown(Keys.Left)) body.ApplyForce(new Vector2(-1, 0) * boostMultiplier); // Notice the multiplier if (Keyboard.GetState().IsKeyDown(Keys.Right)) body.ApplyForce(new Vector2(1, 0) * boostMultiplier); if (Keyboard.GetState().IsKeyDown(Keys.Up)) body.ApplyForce(new Vector2(0, -1) * boostMultiplier); if (Keyboard.GetState().IsKeyDown(Keys.Down)) body.ApplyForce(new Vector2(0, 1) * boostMultiplier); float speed = body.LinearVelocity.Length(); if (speed > maxSpeed * boostMultiplier) // Here too and on the next line body.LinearVelocity = body.LinearVelocity / speed * maxSpeed * boostMultiplier; world.Step(Math.Min((float)gameTime.ElapsedGameTime.TotalSeconds, (1f / 30f)));

David Gouveia

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.