Platformer Physics

Topics: User Forum
Jun 19, 2009 at 2:02 AM

Hey guys! I just started to play around with Farseer and it's pretty amazing! I have a few questions about the engine though.

Right now I'm using a modified Agent class that has a head(circle) + 3 rectangles. And to make it not rotate, i set the MOI to float.MaxValue. Is there another way to do this? It seemed like a hack to me.

I also attached event handlers for both the OnCollision and OnSeperation events for the bottom rectangle Geom so when you move in air, it applies less movement force. This also seemed like hack for air speed vs ground speed. If there was a better way, I'd also like to know.

The problem right now is that there's acceleration for the character. I'd like it so that it doesn't have such a thing, or has less acceleration or has some limit on the maximum velocity. I was thinking about setting the velocity to a specific length every update. But that seemed like another hack to me.

Any help is appreciated.

Thanks guys!

Jun 19, 2009 at 3:12 AM

Whatever works :)

The solutions seems fine to me. You can also stop a geometry from rotating by using a limit angle joint. Just set the max and min limit to the same value. This should only be used instead of the MOI trick if you need to change the angle of the geometry at some point.

As for the acceleration. You only have linear drag to play with here. Or get creative. If setting the velocity manually works for you, I'd say go for it.

Jun 19, 2009 at 5:06 AM
Edited Jun 19, 2009 at 5:09 AM

Oh I see haha.

Also, how do display things in "world" position? I see there's a GetWorldPosition. What exactly does that do?

I'm using the PhysicsSimulatorView from the samples to display things. How could I make it so that it follows a character?

I've implemented a camera system that converts WorldPosition to ScreenPosition using where the camera is on other projects. Is the same thing required here?



Also, I see that some objects tunnel through walls and other Agents on the screen at high velocities. Is there a way to prevent that?

Thanks again

Jun 19, 2009 at 10:52 AM
Edited Jun 19, 2009 at 10:57 AM

for the rotation, we use the MOI approach

for air movement, we use 2 different states for the player. on ground, we use acceleration/deceleration/velocity physics. in air, we use force/drag physics (classic Farseer).

for tunneling, see Farseer manual (last chapter irc).

GetWorldPosition are "real" coordinates. GetLocalPosition is relative to your body.

also have a look at this thread:

Jun 19, 2009 at 5:50 PM

How did you word with the OnCollision handlers? I don't know how to work with those (still don't know a lot to programming).

Jun 19, 2009 at 8:43 PM

yobiv: Thanks so much! I just read through the class you wrote. I created something similar but your method seems to work better! Thanks!

sonic4305: They're basically like this:

class Entity 
    Body body
    Geom geom;
    public Entity(Body body, Geom geom)
        // you can create your body/geoms here also, just doing this for simplicity
this.body = body; this.geom = geom; this.geom.OnCollision += this.OnCollision; } private bool OnCollision( Geom g1, Geom g2, ContactList contactList ) { //do your stuff } }
the link that yobiv provided has an example of a good platformer oncollision/onsep code

Jun 21, 2009 at 3:06 AM
Edited Jun 21, 2009 at 3:08 AM

Still having trouble with tunneling. Some projectiles like sniper bullets need to travel at a fast speed. So some of these are not possible for me.

1)    Make your objects move slower
2)    Make your objects larger
3)    Decrease your time step
4)    Use ray casting
5)    Swept collision detection (info here)
6)    Multisampling

First 2 isn't possible since these bullets need to be fast. I'm not sure how to decrease the time step. And the last 3 I don't really understand even with that link.


Edit: sorry something went weird when i tried to copy and paste from word





Jun 21, 2009 at 11:06 AM

I can elaborate a little on this to narrow down your possibilities.

First off, the problem is that when geometries travel too fast and have a small area, they simply pass each other because the physics engine only gets updated each 10 ms (if your timestep is 10 ms). Imagine a bullet of 5px width and a wall of 20px width. If you shoot the bullet at the wall, the physics engine starts out the bullet... let's say 200px from the wall. Then it moves 25px on each update (each 10ms). When it each the wall, it might be just before the wall, move 25px and be behind the wall.

Now that we have this knowledge, we can find a solution to it.

1) Making your objects slower is obviosly going to solve the problem. Instead of traveling 25px each update it only travel 5px. When it eaches the wall, it will collide with the wall and the correct reaction occurs. Making it slower is not always a possibility.

2) Make your objects larger does not mean you have to make your bullet the size of an elephant. You can actually just make it longer without making the texture of the bullet longer. This would statisfy the physics engine while the game still looks right.

3) Decrease your time step is just saying: Update your physics engine more often. If you update more often, it have a better chance of knowing when the bullet hits the wall.

4) Ray casting is a method where you create an infinite (in computers: very long) line with an angle. So instead of actually creating a geometry that travels from the gun to the wall, you create a line that goes from your player towards the wall. Farseer Physics can do this for you (Using RayTester), it can even tell you what geometry the ray hits (Like the wall for example). You still need to display the graphics and you still need to know the distance to the geometry and calculate the right time of impact.

5) Swept collision detection is a method of CCD (Continuous Collision Detection) that prevents tunneling by sweeping the geometry along the geometry path and checks for collisions. This is not yet in Farseer Physics, but we are working hard to get it to work in the next version (3.0). The method we use is not by sweeping, it is by having a skin around geometries.

6) This one should not be here anymore.


I hope you are able to remove or at least minimize the amount of tunneling you get by using one or more of the items on the list. It is a question about trying them out and tweaking until you get something that works. Unfurtnatly it is a limitation of the computer (not powerful enough) that is hard to get rid off without any sideeffects.

Jun 22, 2009 at 5:19 AM

Ahh okay thanks!

Good luck on version 3.0! Can't wait!

I have another question,

For a bullet or something similar, how do you make it fall/go forward head first? or should I just rotate it visually and check which direction the velocity is?

Thanks again!

Jun 22, 2009 at 11:47 AM

> yobiv: Thanks so much!

that's always nice to hear! :)

>the link that yobiv provided has an example of a good platformer oncollision/onsep code

the current version still has some flaws which i noticed later on in our game and didn't mention in the thread yet

> how do you make it fall/go forward head first

simply use the body.Rotation for the XNA Sprite rotation

Jun 22, 2009 at 9:04 PM

yobiv: the problem right now isn't drawing the rotations, it's that the body doesn't rotate in mid-air.

It has no angular velocity.

Do if I offset the center of the body, would that make go head first?

Jun 23, 2009 at 11:34 AM
Edited Jun 23, 2009 at 11:42 AM

i think the only indicator for your orientation is the velocity so you have to convert the velocity vector to an angle and use this as the orientation

interesting use case btw.

Jun 24, 2009 at 12:38 AM

Thanks yobiv for the suggestion, that was what I assumed.

I ended up updating the projectile body's rotation depending on the velocity. And I also hooked up OnCollision/Separation event handlers so that it doesn't update the rotation when colliding. For those of you who want to do this

Oh and I think I may have found a "bug" in the engine.

When my projectile's MOI was around .0000001f (when i was playing around).

After collision, it broke every Body's position in the simulator. They all turned into { NaN, NaN }

I'm not sure if genbox knows about this or not. Just a heads up.


Thanks guys!