如何进行火车转弯运动?
How to make a train turning movement?
我正在尝试开发一种类似火车的游戏,玩家将在其中沿着预先确定的轨道移动。而且我在制作沿轨道转动和移动播放器的功能时遇到了麻烦。仅供参考,游戏在整个关卡中只有 L 形和 U 形转弯(90 度和 180 度)。所以我的问题是,你如何制作一个移动功能,让玩家转动并沿着他的轨道/轨迹移动,而不考虑速度(会有不同类型的 "trains" 具有不同的速度设置)和 FPS(设备会有所不同,因此 FPS 也会有所不同)。这是我到目前为止所做的:
/// <summary>
/// Rotate and translate each tick if we are turning.
/// This will be called each tick when we are at a junction and need to turn.
/// </summary>
/// <param name="dt"> The delta time in mili seconds. </param>
/// <param name="turnRate"> The turn rate each second in degree. + if CW, - if CCW. </param>
/// <param name="targetHeading"> The target angle in degree. Can be 0, 90, 180, 270. In world space coordinate. </param>
/// <param name="speed"> The speed of the train. </param>
void TurnAndMoveEachTick(float dt, float turnRate, float targetHeading, float speed)
{
float currentHeading = getHeading();
float nextHeading = currentHeading + turnRate * dt; //Get thenext heading this tick
//Clamp the turning based on the targetHeading
if ( (turnRate > 0.0 && nextHeading > targetHeading) ||
(turnRate < 0.0 && nextHeading < targetHeading) )
nextHeading = targetHeading;
//Turn
this.rotate(nextHeading, Coordinate::WORLD); //Rotate to nextHeading usng the world space coordinate.
//Move
float displacement = speed * dt;
this.translateBy(getHeading(), displacement); //Translate by displacement with the direction of the new heading.
}
当我尝试使用不同的速度时,它变得非常错误。所以我还必须相应地调整 turnRate。但是有多少?那是我不明白的。而且,我认为如果 FPS 下降(我在我的相当高端的工作站上试过这个),这个函数也会被搞砸,因为每个滴答的增量时间也会不同。那么我该如何解决呢?
提前致谢。
turnRate 度数是速度/周长 * dt * 360
周长是 2*pi*半径
对于 20 的固定 FPS,您会得到 dt=0.05。请注意您的 100 km/h 和半径仅为 10 m 的示例,因为您在转弯中只花费了几个刻度。根据您的代码示例,火车不再在轨道上也就不足为奇了:)
正如我在评论中所建议的那样,我将放弃 turnRate 概念并使用距离作为参数来计算火车在给定时间点行驶的角度。只需将当前速度*dt加上一个距离,则
角度=距离/周长*360
不需要 fiddle turnRate,那只会累积每次报价中的错误。
这有帮助吗?
我正在尝试开发一种类似火车的游戏,玩家将在其中沿着预先确定的轨道移动。而且我在制作沿轨道转动和移动播放器的功能时遇到了麻烦。仅供参考,游戏在整个关卡中只有 L 形和 U 形转弯(90 度和 180 度)。所以我的问题是,你如何制作一个移动功能,让玩家转动并沿着他的轨道/轨迹移动,而不考虑速度(会有不同类型的 "trains" 具有不同的速度设置)和 FPS(设备会有所不同,因此 FPS 也会有所不同)。这是我到目前为止所做的:
/// <summary>
/// Rotate and translate each tick if we are turning.
/// This will be called each tick when we are at a junction and need to turn.
/// </summary>
/// <param name="dt"> The delta time in mili seconds. </param>
/// <param name="turnRate"> The turn rate each second in degree. + if CW, - if CCW. </param>
/// <param name="targetHeading"> The target angle in degree. Can be 0, 90, 180, 270. In world space coordinate. </param>
/// <param name="speed"> The speed of the train. </param>
void TurnAndMoveEachTick(float dt, float turnRate, float targetHeading, float speed)
{
float currentHeading = getHeading();
float nextHeading = currentHeading + turnRate * dt; //Get thenext heading this tick
//Clamp the turning based on the targetHeading
if ( (turnRate > 0.0 && nextHeading > targetHeading) ||
(turnRate < 0.0 && nextHeading < targetHeading) )
nextHeading = targetHeading;
//Turn
this.rotate(nextHeading, Coordinate::WORLD); //Rotate to nextHeading usng the world space coordinate.
//Move
float displacement = speed * dt;
this.translateBy(getHeading(), displacement); //Translate by displacement with the direction of the new heading.
}
当我尝试使用不同的速度时,它变得非常错误。所以我还必须相应地调整 turnRate。但是有多少?那是我不明白的。而且,我认为如果 FPS 下降(我在我的相当高端的工作站上试过这个),这个函数也会被搞砸,因为每个滴答的增量时间也会不同。那么我该如何解决呢?
提前致谢。
turnRate 度数是速度/周长 * dt * 360
周长是 2*pi*半径
对于 20 的固定 FPS,您会得到 dt=0.05。请注意您的 100 km/h 和半径仅为 10 m 的示例,因为您在转弯中只花费了几个刻度。根据您的代码示例,火车不再在轨道上也就不足为奇了:)
正如我在评论中所建议的那样,我将放弃 turnRate 概念并使用距离作为参数来计算火车在给定时间点行驶的角度。只需将当前速度*dt加上一个距离,则
角度=距离/周长*360
不需要 fiddle turnRate,那只会累积每次报价中的错误。
这有帮助吗?