Slight offset in time and distance

153 Views Asked by At

I am building a teaching platform for teaching basic Physics.

From my experience in Flash development, I have met similar problems before.

The game time is not the same as real world time. In which case, for example, the distance covered by a projectile can be larger or smaller if the computer lags or for whatever reasons.

Here is a screenshot of the said platform. As shown in the screenshot, I am only developing a lesson for teaching the basic s = v * t relation.

Lesson for teaching s = u * t relation

Necessary background

The red line marks the position 69.06284 m, our target distance. The time 11.56087 s is a given value.

The user is supposed to input a speed, moving a projectile from 0 m to the right in order to reach the red line within the time given.

The green line marks the position of the projectile when time is up.

I can assure you that I input an accurate speed up to 5 decimal points so there is no human error in this case.

Ignore the yellow rectangle. It is just a UI element.

The screen is 800 pixels wide, and therefore 10 pixels represent 1 meter.

Way to solve the problem

I'm not sure what to do, quite frankly. But I heard from someone that variable time step represents real world time better. However, Farseer, being a physics simulation engine, should be used with fixed time step, isn't it?

Any advice will be greatly appreciated.

EDIT: here in the screenshot, the actual distance covered by the projectile is ~66.3 m, whereas the theoretical distance is 69.1 m. I also notice that if the target distance (currently 69.1 m) is smaller (red line moves a lot more to the left), the error is smaller.

How do I fire a projectile?

public override void ShootProjectile(Vector2 start, float angle, float speed) {
    GameTemplate g = Game as GameTemplate;
    Arrow a = new Arrow(Game, start, this);
    a.Initialize();
    a.Restitution = 0f;
    a.Friction = 0f;
    a.LinearVelocity = new Vector2(speed, 0);
    Console.WriteLine("Speed: "+a.LinearVelocity.X);
    _fireTime = g.SinceGameStarts;

    //Console.WriteLine("Fire time: "+_fireTime);
    _projectiles.Add(a);
}

In the Arrow class, I basically set up Farseer through a CreateBody method:

protected override void CreateBody() {
    GameTemplate g = Game as GameTemplate;
    Vector2 positionInMeters = _initPos / g.MeterInPixels;
    float width = 30f / g.MeterInPixels;
    float height = 40f / g.MeterInPixels;
    _body = BodyFactory.CreateRectangle(g.GameWorld.World, width, height, 1f, positionInMeters);
    _body.BodyType = BodyType.Dynamic;
    _origin = new Vector2(15f, 40f);
}

How do I calculate the flight time of projectile?

May be you are curious about the _fireTime = g.SinceGameStart line. SinceGameStart is a getter of the variable _currTime in a GameTemplate. The value of _currTime is updated once every Update(gameTime) call. So if I want to know how long the projectile has been flying, I do this:

time = _currTime - projectile.FireTime
0

There are 0 best solutions below