0

我正在搭建一个教授基础物理的教学平台。

根据我在 Flash 开发方面的经验,我之前也遇到过类似的问题。

游戏时间与现实世界时间不同。在这种情况下,例如,如果计算机滞后或出于其他原因,弹丸所覆盖的距离可能会更大或更小。

这是该平台的屏幕截图。如屏幕截图所示,我只是在开发一个课程来教授基本的 s = v * t 关系。

教学课 s = u * t 关系

必要的背景

红线标记位置 69.06284 m,即我们的目标距离。时间 11.56087 秒是给定值。

用户应该输入一个速度,将弹丸从 0 m 向右移动,以便在给定的时间内到达红线。

当时间到时,绿线标记弹丸的位置。

我可以向您保证,我输入了精确到小数点后 5 位的速度,因此在这种情况下不会出现人为错误。

忽略黄色矩形。它只是一个 UI 元素。

屏幕宽 800 像素,因此 10 像素代表 1 米。

解决问题的方法

坦率地说,我不确定该怎么做。但我从某人那里听说可变时间步更能代表真实世界的时间。但是,Farseer 作为物理模拟引擎,应该是固定时间步长使用的吧?

任何建议将不胜感激。

编辑:在屏幕截图中,弹丸覆盖的实际距离约为 66.3 m,而理论距离为 69.1 m。我还注意到,如果目标距离(当前为 69.1 m)更小(红线向左移动更多),则误差更小。

如何发射弹丸?

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);
}

在Arrow类中,我基本上是通过一个CreateBody方法来设置Farseer的:

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);
}

如何计算弹丸的飞行时间?

可能您对 _fireTime = g.SinceGameStart 行感到好奇。因为GameStart 是GameTemplate 中变量_currTime 的getter。_currTime 的值在每次 Update(gameTime) 调用时更新一次。所以如果我想知道弹丸飞行了多长时间,我这样做:

time = _currTime - projectile.FireTime
4

0 回答 0