So, a little a while ago I posted a tutorial on updating the Sgt. Conker Farseer Platformer tutorial by @roytries to Farseer 3.0. Hopefully later today I'll get a chance to repost that tutorial with an update for xna 4.0 and Farseer 3.2.
But first, I wanted to post a quick sample of how I did the character movement dynamics in Mario using Farseer (as requested by @chounard and a couple of others).
If you want to skip ahead to the sample, its linked to at the end of this post.
First thing to mention is the fact that its quite a different approach to the one used in @roytries tutorial. I orignally used the method from the tutorial almost verbatim, but ran into some issues. The main problem I had with the original method was caused by a combination of the composite nature of the character (a rectangle attached to a wheel) and the high friction used on the wheel.
The result of these two factors was that everytime the character ran into a wall it launched into the air as a result. I tried a number of different approaches to fix this, but nothing was quite right.
In the end I decided to switch my approach to something simpler. I chose to use a simple rectangle with a FixedAngleJoint to keep it upright. Obviously this removed the ability of the character to go up and down slopes, but that's not a problem in a Mario clone.
With the loss of the wheel, and therefore the use of a motor to create movement, I had to find an alternative method of locamotion. At first I attempted to use a force to create an acceleration, but although this provided a realistic motion, realism isn't really what I was going for in a Mario clone!
In the end I decided to modify the LinearVelocity property of the rectangle directly. Although this wasn't quite how Farseer was designed to be used, it didn't seem to break the simulation (apart from in one instance, which I'll come onto in a moment).
For jumping, I simply applied a LinearImpulse, much as I did in my upgrade to @roytries's tutorial.
For moving left/ right in the air, I limited the horizontal velocity in the air to that on takeoff. This isn't quite what @roytries did in his tutorial, but I found it gave a more Mario-like movement.
There was one last thing to add to the mechanics. As a result of manipulating LinearVelocity directly, anytime the character collided with the side of an object, it 'stuck' to it for as long as the player was still holding the thumbstick in that direction.
This was simple to overcome by simply setting the friction values of the platforms and walls to zero. Normally this might be an issue, with the character sliding straight off of the platforms, but as we are manipulating LinearVelocity directly we can simply set LinearVelocity.X to zero whenever we aren't airbourne and there is no left/right input from the thumbstick.
That's pretty much it. There are a couple of flaws, like the fact that when the character runs off the edge of a platform and falls they can still perform a jump, but I've left that in for the moment (just because I thought it worked quite well as a gameplay mechanic!) but it should be easy enough to remove by checking whether LinearVelocity.Y < 0 before calling Jump().
Below is the sample, not the prettiest code, but should give you the idea. If you haven't already, I suggest reading @roytries's tutorial: http://www.sgtconker.com/2010/09/article-xna-farseer-platform-physics-tutorial/ followed by my own update to that tutorial on this blog http://www.rabidlion.com/2010/11/updating-farseer-tutorial-to-farseer-30.html
Between them they should explain most of what is going on in the sample (including anomalies like having to add a pixel to the width and height of the rectangle being drawn to avoid a gaps between touching surfaces).
Hopefully I'll be able to fit in my update to my upgrade tutorial later today, but in the mean time, have fun with the sample!
http://simplefpplatformer.codeplex.com/
Hey!!! great article!!!! so so simple! this is what i was looking for! my game colition detection system was a mess and i was trying to replace it so i came to farseer, and yours article (also roytries too ;) were so simple to follow!
ReplyDeletethanks you very much man!
greetings from Argentina
Hernan
Thanks for the article...
ReplyDeleteLike you, I quickly realized that the "rectangle balancing on a ball" wasn't the way to go. That was lifted from a very specific game, but wasn't conducive to Mario-type games (with square tiles).
And, like you, I have a rectangle that I'm pushing around by applying force with some success, actually. I'm a little leery of mucking around with the velocity directly, but nice to know that's an option.
I'll keep plugging away at it... Thanks for this post!
Adam