我正在建立一个教授基础物理的教学平台。
根据我在Flash开发方面的经验,我之前遇到过类似的问题。
游戏时间与现实世界时间不同。在这种情况下,例如,如果计算机滞后或出于任何原因,射弹所覆盖的距离可以更大或更小。
以下是该平台的屏幕截图。如截图所示,我只是在教授基本的s = v * t关系。
必要的背景
红线标志着我们的目标距离69.06284米。时间11.56087 s是给定值。
用户应该输入一个速度,将射弹从0米向右移动,以便在给定的时间内到达红线。
绿线表示时间到了时弹丸的位置。
我可以向您保证,我输入的精确速度最多可达5个小数点,因此在这种情况下没有人为错误。
忽略黄色矩形。它只是一个UI元素。
屏幕宽度为800像素,因此10个像素代表1米。
解决问题的方法
坦白说,我不知道该怎么做。但我从某人那里听到,可变时间步骤更能代表现实世界时间。但是,作为物理模拟引擎的Farseer应该使用固定的时间步长,不是吗?
非常感谢任何建议。
编辑:在屏幕截图中,射弹覆盖的实际距离为~66.3米,而理论距离为69.1米。我还注意到,如果目标距离(目前为69.1米)较小(红线向左移动更多),则误差较小。如何射击射弹?
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行感到好奇。 SinceGameStart是GameTemplate中变量_currTime的getter。每次更新(gameTime)调用时,_currTime的值都会更新一次。所以,如果我想知道射弹飞行了多长时间,我会这样做:
time = _currTime - projectile.FireTime