Newbie help -- what is up with World.Step

Topics: Developer Forum
Feb 2, 2011 at 3:00 AM

Hi,

I'm trying to get Farseer working with Monotouch.  I've built the latest Farseer code for use with Monotouch (only had to make one change -- replacing HashSet<T> with non-generic type).

I have one simple screen that contains two shapes: one dynamic Circle and one static EdgeShape.  The idea is to just get the circle to bounce off the edge.  This is working fine with one problem: the circle just won't go fast enough.  It is all very slow.  I know the frame rate is not the problem -- it's smooth and showing about 120fs.  I've tried tweaking gravity, applying an impulse, changing the step... all of which change the behavior, but none of which make the circle fall and bounce with any sort of speed (takes a few seconds for the circle to bounce off the edge).

Also, I don't understand the argument to World.Step at all.  I thought this was a measure of time.  Changing it should change how much is moved in a step, but here's what I'm observing:

1. The lower the value sent to Step, the faster the ball moves (but never fast enough).

2. Increasing the value to Step changes the physics.  Instead of bouncing off the edge the ball vibrates along the edge.

Please help.  Here's some of the code:

		private void CreateBody()
		{
			if (this.world == null)
			{
				this.world = new World(new Vector2(0, 100));
				
			}
			if (this.ballBody != null)
			{
				this.ballBody.FixtureList[0].AfterCollision -= AfterBallCollisionEventHandler;
				this.world.RemoveBody(this.ballBody);
			}
			this.ballBody = BodyFactory.CreateBody(this.world, new Vector2(Rand.Next(300), 0));
			this.ballBody.BodyType = BodyType.Dynamic;
			Vector2 impulseV = new Vector2(0, 100);
			this.ballBody.ApplyLinearImpulse(impulseV);
			CircleShape cs = new CircleShape(10f, 0.5f);				
			Fixture fix = this.ballBody.CreateFixture(cs);
			fix.Friction = 0;
			fix.Restitution = 1f; 
			fix.AfterCollision += AfterBallCollisionEventHandler;
		}

		private void Start()
		{
			CreateBody();
			this.thread = new Thread(PlayThread as ThreadStart);
			thread.Start();
			
		}

		void PlayThread()
		{
			using(var pool = new NSAutoreleasePool())
		    {
				while (this.playing)
				{
				
					this.world.Step(1f/60f);
					Vector2 pos = this.ballBody.Position;
					// reset the ball when it goes off screen
					if (pos.Y > 520 || pos.X < -40 || pos.X > 360 || pos.Y < -40)
					{
						CreateBody();
					}
					pool.InvokeOnMainThread(delegate{
						Draw();
					});
				}
			}
		}

Many thanks,

Mike

Coordinator
Feb 2, 2011 at 7:16 AM
You have to scale your World to use the MKS system. The value you give
step is the time between steps.
Feb 2, 2011 at 7:00 PM

Thank you for the reply, it is very much appreciated!  Scaling the world makes a lot of sense but, er, how do I do that?  

What is the MKS system?

I get that the value is the time between steps, what I don't understand is why changing that value changes the speed and the physics.  My expectation is that it would just change granularity.

Feb 3, 2011 at 4:01 AM

Nevermind, I found the answer here: http://farseerphysics.codeplex.com/Thread/View.aspx?ThreadId=236232

Makes perfect sense, thank you!