0

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
Felastine
  • 793
  • 2
  • 8
  • 18
  • 1
    Maybe you could show the relevant bit of your code. It would probably help a lot to understand what is going on. – Paolo Tedesco Oct 15 '12 at 06:37
  • @PaoloTedesco See edit. I have edited with my code. – Felastine Oct 15 '12 at 09:45
  • Are you getting the same result (66.3 instead of 69.1) each time or the result varies from one execution to another? – Paolo Tedesco Oct 15 '12 at 11:08
  • Wouldn't it be better and easier just to animate the `s = v * t` equation (and most other basic physics equations), than to run a full physics engine? Farseer isn't really designed for accuracy or reproducibility. – Andrew Russell Oct 15 '12 at 12:12
  • @AndrewRussell Yes, if I'm just teaching one equation. But in later lessons of the platform, more complicated concepts and stuff are to be taught (such as force). If Farseer is not designed for accuracy, could you suggest some alternatives? – Felastine Oct 15 '12 at 12:56
  • @PaoloTedesco I have tested with distance set to 69.0 and time set to 10.0, in which case a speed of 6.9 is required for the projectile to reach the line. The error seems reproducable. Two tests yield the same actual distance of 662.4019 m. – Felastine Oct 15 '12 at 12:58
  • @AndrewRussell By the way, when I test Farseer with the potential-kinetic energy conversion equation, Farseer simulated correctly the height reached by a projectile. Why's that? – Felastine Oct 15 '12 at 13:03
  • 1
    I am suggesting straight-up animation. Increment the `t` variable over time, run it through your formula, draw a sprite at the resulting `s` position. This method should work for most simple physics equations - which includes things like force. Example: `s = ut + 0.5at^2`, substitute in force: `s = ut + 0.5(F/m)t^2`. Works in 2D as well, just use vectors. – Andrew Russell Oct 15 '12 at 13:05
  • @AndrewRussell Thanks for the suggestion. May be I will stick to this method when such offset errors show up. – Felastine Oct 15 '12 at 13:27

0 Answers0