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
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
Related Q & A:
- How can I implement an atomic incr and decr on top of an eventually consistent key-value store?Best solution by Stack Overflow
- Can I implement a Service into an app?Best solution by Stack Overflow
- How can I implement idle timeout in android?Best solution by Stack Overflow
- How can I implement a multilayer social network in R?Best solution by Computational Science
- How can I burn a .rmvb file onto a DVD for viewing on a regular DVD player?Best solution by Yahoo! Answers
Just Added Q & A:
- How many active mobile subscribers are there in China?Best solution by Quora
- How to find the right vacation?Best solution by bookit.com
- How To Make Your Own Primer?Best solution by thekrazycouponlady.com
- How do you get the domain & range?Best solution by ChaCha
- How do you open pop up blockers?Best solution by Yahoo! Answers
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.