Creating a Character

Jun 25, 2009 at 9:34 PM

Hello, I've just started using the Farseer physics engine and it seems pretty awesome!

However, after I got over how fun it was to bounce around in a small level with a ball, I started trying to figure out how I would make a platformer.

The problem I'm having is, I don't know the best way to make a "character".  I was thinking simply having the Sphere to test collisions against would be fine, but if I use a sphere as a character, Sometimes I have problems, such as the character "bouncing" as I run, I even have the restitution coefficient set to -1.  I set the MOI to float.MaxValue, and it helped a bit.

I'm just wondering if there are any tutorials for doing something like this, or any tried and true methods.  Because atm I'm just applying a force left or right along the x axis, but if I have a slant, wouldn't I want to move in the direction of the slope?

I guess I'm just looking for pointers, because what I have now just feels hacked together, and I don't want it to come back to bite me later.

Coordinator
Jun 25, 2009 at 10:00 PM

I'm happy to hear that Farseer Physics Engine inspire you to create a platformer.

As for your character; It is up to you to create a character using the shapes you want. If a ball is what you need, then I would go for a ball. You have to remember that circles in Farseer Physics is created using polygons. This means that they are not perfectly round, but an approximation of a circle. This can give some weird bouncing when the circle hits the ground or walls.

Making your character not rotate by setting the MOI to float.MaxValue can reduce this, but if the circle hits something, it still has a chance of incorrectly bouncing.

There are several ways of getting around this. Most of them are too advanced for new users and include the use of ray casts. Someone here on the forums might be able to give you a simple way of reducing this that I'm not aware of. A good thing is that we are working on getting real circles to work in Farseer Physics Engine 3.0. This means that circles are no longer an approximation, but a real circle. They will bounce correctly every time they hit something. We are working on Farseer Physics Engine 3.0, but it will take some time before it is ready. We still need to implemement a lot of features.

Jun 26, 2009 at 1:53 PM
Edited Jun 30, 2009 at 8:27 AM

I made my character out of a box and a ball, connected with a revolute joint so the ball is like a wheel. To move I apply torque to the ball, and when standing still I use an angle joint as a brake, to stop it rolling. I also use an angle joint to keep the player upright.

This approach works well in having my player interact physically with the enviroment, (eg when running on a ball, the ball will spin in the opposite direction). However if you want a more traditional platformer feel you might be better off with another solution.

My games here, you can see it working: http://boxycraft.wordpress.com/game/

Jun 26, 2009 at 6:55 PM

thanks robert, your game looks like a lot of fun btw!

Those are some good ideas I'm going to have to give a try.  By the looks of your game I think your solution will work for me.

I had been using torque to move the ball, but I had been increasing the rotational drag and friction to try and keep the char in place.  of course then I'd have to increase the torque that I applied, and I ended up with some funky results sometimes where the char would go flying off the level.  I hadn't thought of using an angle joint as a brake.

Once again, thanks!

 

Jun 27, 2009 at 6:36 AM
Edited Jun 27, 2009 at 6:37 AM

Hi Cipher

I made a modified revolute-joint which has a motor ability. Basically you set the speed you want the joint to rotate at, and the maximum power to apply, and the joint will rotate the bodies at a constant speed. Its exactly like an ordinary revolute joint, but if you want the motor enabled you set Motor_Enabled = true;

Itl help keep your character speed constant when running up and down slopes, and also by setting the speed to 0 itl act like a brake, so you might not need an angle joint.

You can find it in the patches section if you want. I got the code from the Box2Dx engine.

Jun 29, 2009 at 9:41 PM
Edited Jun 29, 2009 at 10:08 PM

Hi Robert

can you describe more the way how you did your character. Sliding any object (circle, ellipse) with LinearVelocity along ground made from several rectangles causes weird jumps. Using circle and applying AngularVelocity just spins circle in same place or sometimes insanely rotates and makes jumps like hell.

I linked PhysicsSimulatorView to my project to see what's going on, but I'm not any smarter from anything I see. Applying torque only on circle also only spins... no fluent movement along ground. Do I have to play with friction more? I have to default to everything..

Thnx

EDIT: Damn, ok.. I answered my own question with the friction coeficient there.. still would like to know how you did your character or where is here 'Patch section'.. can't find anything like it.

Jun 30, 2009 at 8:23 AM
Edited Jun 30, 2009 at 8:26 AM

Hi Dusho, click on "Source Code", at the top of the page. Then click on the small sub heading titled "Patches". You should see a post there by me about a Motor-Joint. Download that and replace your existing Revolute-Joint code with that.

Theres no difference at all to the original joints unless you set Motor_Enabled to True, so you wont have to change any of your code.

And I wrote a small article about my character here: http://boxycraft.wordpress.com/  I hope that explain it OK.

Jul 1, 2009 at 10:23 PM

Robert Dodd,

 

I tried imitating what you did with your character, but when I try to stop the character's movement it will often hop backwards. I'm pretty sure this is because the angle joint forces the circle to immediately rotate to the rotation of the rectangle.  Also, the way I have it set up when the character stops moving it doesn't stop in place. It takes some time to slow all the way down to a complete halt. This is some of the code I have been using to try to do this:

public void Stop()
        {           
            angleJoint.Enabled = true;
            revJoint.Motor_Enabled = false;           
            revJoint.Motor_Speed = 0f;
            revJoint.Motor_MaxTorque = 0f;
        }

        public void MoveLeft()
        {
            angleJoint.Enabled = false;
            revJoint.Motor_Enabled = true;
            revJoint.Motor_Speed = -6f;
            revJoint.Motor_MaxTorque = 30f;
        }

        public void MoveRight()
        {
            angleJoint.Enabled = false;
            revJoint.Motor_Enabled = true;
            revJoint.Motor_Speed = 6f;
            revJoint.Motor_MaxTorque = 30f;
        }

 

any advice anyone could give would be greatly appreciated.

 

Jul 2, 2009 at 4:40 AM

hi elpollo

When you stop you dont have to turn the motor off, only set the speed to 0. This will make it stiff, and depending on the MaxTorque you might not even need an AngleJoint as a brake.

Anyway, to get the AngleJoint to work use this: angleJoint.TargetAngle = Wheelbody.TotalRotation - Boxbody.TotalRotation; before enabling it.

Hope that helps, Cheers

Jul 4, 2009 at 11:30 PM

I was checking the forums for solution how to detect that you're on ground and you can jump.

Solution with Arbiters and using Tag to identify collision effect seems fine, also OnCollision event. Thing is, that those ways will detect even collision with side wall, without ground under your feet and thus for a moment you can jump.

I was thinking about casting a ray in +Y direction from legs (represented by circle) and checking for distance of first contact point. But all methods in RayTester seems to check all contact points along ray. There isn't a 'light' method that will return on first contact?

Jul 13, 2009 at 8:51 PM
Edited Jul 13, 2009 at 9:21 PM

Hi

another question regarding character represented by rotating circle (Legs). When running over rectangles that are not static and the weight of rectangle is similar to player, rotating circle (legs) is creating forces that will move rectangles beneath legs even when Restitution of both objects is 0. Is this correct? I thought that if restitution is 0, objects won't receive feedback forces from each other.

EDIT: video: http://www.youtube.com/watch?v=c-2109lqd8g

Jul 14, 2009 at 3:02 AM

hi dusho

Restitution affects how high the object will bounce when it collides with something. Whats making the boxes spin is the friction of the ball when it spins. I found this to be pretty realistic, as it also allows the player to stay on rolling balls by running in the opposite direction (like you do in real life). Its basically the newtons law that every action has an equal and opposite reaction. To run forward you have to push in the opposite direction with your feet, so same here.

Jul 14, 2009 at 4:46 PM

yes, friction of ball generates forces on boxes, I think. As you wrote, constitution clamps amount of force generated after collision - and I thought that same applies to this case.

And yes, it is kind of realistic, if you have wheels as legs, but bipeds (e.g. humans) shouldn't produce such a continual force on box, so I wanted at least to limit the forces applied to box. Maybe I can reduce forces on box in OnCollision (if there isn't solution using simple paramater) or I won't allow to have such a light objects in game..

Aug 19, 2009 at 11:43 AM

My circle representing legs consist of 32 vertices - so I don't see bouncing when moving. I do see bouncing when landing from fall or jump, though. Even when restitution of both geometries colliding is set to 0, there is still some bouncing - what I don't get completely.

 

Coordinator
Aug 20, 2009 at 3:58 PM

@sensorium7: Can I ask what you used instead? Farseer Physics has what I call a trippy feeling while other engines with more accurate integrators have what I call plastic feeling (should not be read as fake). It is a matter of taste and sometimes it requires a lot of tweaking to get it just right.

Coordinator
Aug 20, 2009 at 10:22 PM

@Sensorium7: That sounds great. I was hoping someone someday told me that he actually used our source as a reference. That is one of the goals of the engine source code.

As for raycasting, the SAP algorithm is OK with raycasting but you can get better performance using a hash/grid/tree algorithm instead. In all cell based broadphase algorithms you simply make a line-cell test using a fast cell traversal algorithm like Voxel or something similar. Just to sum it up and give you a head start:

Imagine a grid of cells (dynamic or static size - does not matter) and a ray. Since a ray is a single point with a direction, you can create a line versus cell test. All the cells the line intersect are gathered for later use in the narrow phase. A fast algorithm for doing this is the Voxel algorithm. Parts of it is explained here: Raytracing - Part 4: Spatial Subdivisions under the Grid Traversal section. I'm sure you can find the rest using Google.

The spatial hash algorithm in FPE is really simple and easy to implement and change. If you manage to implement a query function into it using raycasting I would very much like to hear about it. I've not had the time to implement one myself (It has been on the todo list for ages).