Platformer Character Controls?

Aug 24, 2012 at 3:16 PM

I've kinda got it working with my recent games, but it still has a lot of things that don't work well. I simply created a dynamic rectangle body and controlled the movement via ApplyLinearForce() and ApplyLinearImpulse() for jumping.

Then there was a problem with friction. Using body.friction doesn't work while jumping and lineardamping was too weak on the x-axis compared to the y-axis (made jumps bad or movement too fast). To avoid this, I've simply subtracted a certain value (multiplied with time) each update from body.linearvelocity. 

Now I was trying to create jump-pads that launch you into the air. It's working fine for vertical forces, but my horizontal forces are being limited by movement friction and make those jump-pads very weak.

There are probably another 100 workarounds to fix every upcoming problem, but is this how it's usually being handled? I keep thinking that there must be another, a lot easier way.

Aug 25, 2012 at 8:54 AM

Firstoff, I am not very good with Farseer, so just take whatever I say with a gain of salt.

 

I think you issue is because you are using Force.

In my experimentations, I found Force and Impulse to greatly different to use in the sort of way you are.

I use just Impulse:

 

My body, is four parts,

A Square,

A FixedAngleJoint

A WeldJoint

And a Circle,

The square acts as body for collision and keeping the thing upright, while the round circle slides across my multiple tiles smoothly. It dose not rotate, it just sleds across.

            Circle.ApplyLinearImpulse(new Vector2(Math.Sign(motion.X) * MathHelper.SmoothStep(0f, 2f, Math.Abs(motion.X)), 0));

(Motion being 1/-1 depending on input method)

Jump:

Circle.ApplyLinearImpulse(new Vector2(0, -(Circle.Mass + Square.Mass) * 12) + impulse);

(Mass is 5? for each object)

 

my setup:

            Square.Restitution = .25f;
            Square.Friction = .45f;
            AngleJoint = JointFactory.CreateFixedAngleJoint(WorldManager.world, Square);

            Circle.Restitution = .25f;
            Circle.Friction = .9f;

            WeldJoint = JointFactory.CreateWeldJoint(WorldManager.world, Square, Circle, Vector2.Zero);

This may not make sence, or be ugly, but it is what worked for me in the end, and it comes out pretty clean.

 

There are a few posts out there about this, also, the testbed, and samples help quite a bit, Furthermore, the Box2D samples can be of benefit as well.


Anyway, check it out:

http://amazingretardo.simiansoftwerks.com/2010/02/17/platformer-character-control-farseer-physics-engine/

 

 /ramble

Nov 23, 2013 at 3:09 AM
Man I feel you. It took me a while to get platformer controls working, the best way I found it to work out was while the character is receiving movement control input, set the character's friction to zero, and while he isn't receiving movement input set it back to whatever it was before.

This is what I've been doing for the last year or so and it comes across as pretty much seamless.