平滑的 2d 炮塔旋转占包裹
Smooth 2d turret rotation accounting for wrapping
我想在2d游戏中做一个炮塔,它应该平滑地旋转到鼠标的角度。我想出了两个解决方案,但都不令人满意。第一个:
currentRot = targetRot; // Produces snapping + doesn't look realistic
第二个,灵感来自Smoothly rotate turret and retain accuracy:
if (currentRot < targetRot)
{
currentRot += 2;
if(currentRot > targetRot)
{
currentRot = targetRot;
}
}
if (currentRot > targetRot)
{
currentRot -= 2;
if(currentRot < targetRot)
{
currentRot = targetRot;
}
}
然而,第二种方法并不总是在最佳方向上旋转。代码不“知道”哪种旋转方式更短。我不能使用库,我认为四元数太过分了,所以我不确定如何解决这个问题。另外,有没有第三种方法simpler/better?
其他信息:targetRot
是从0°-360°
我找到了一个奶酪解决方案,好久不见!这非常具有挑战性。我仍然觉得我的解决方案是 sub-optimal 虽然
它只是检查哪条路更短
var dp = /*world distance from currentRot to targetRot+5 on unitcircle*/
var dp = /*world distance from currentRot to targetRot-5 on unitcircle*/
if (currentRot < targetRot) {
currentRot += rate * (dp < dm ? -1 : 1);
if (currentRot > targetRot) {
currentRot = targetRot;
}
}
if (currentRot > targetRot) {
currentRot -= rate * (dp < dm ? 1 : -1);
if(currentRot < targetRot) {
currentRot = targetRot;
}
}
而且这一行还修复了一些错误
if (currentRot < 0) {currentRot += 360;}
我想在2d游戏中做一个炮塔,它应该平滑地旋转到鼠标的角度。我想出了两个解决方案,但都不令人满意。第一个:
currentRot = targetRot; // Produces snapping + doesn't look realistic
第二个,灵感来自Smoothly rotate turret and retain accuracy:
if (currentRot < targetRot)
{
currentRot += 2;
if(currentRot > targetRot)
{
currentRot = targetRot;
}
}
if (currentRot > targetRot)
{
currentRot -= 2;
if(currentRot < targetRot)
{
currentRot = targetRot;
}
}
然而,第二种方法并不总是在最佳方向上旋转。代码不“知道”哪种旋转方式更短。我不能使用库,我认为四元数太过分了,所以我不确定如何解决这个问题。另外,有没有第三种方法simpler/better?
其他信息:targetRot
是从0°-360°
我找到了一个奶酪解决方案,好久不见!这非常具有挑战性。我仍然觉得我的解决方案是 sub-optimal 虽然
它只是检查哪条路更短
var dp = /*world distance from currentRot to targetRot+5 on unitcircle*/
var dp = /*world distance from currentRot to targetRot-5 on unitcircle*/
if (currentRot < targetRot) {
currentRot += rate * (dp < dm ? -1 : 1);
if (currentRot > targetRot) {
currentRot = targetRot;
}
}
if (currentRot > targetRot) {
currentRot -= rate * (dp < dm ? 1 : -1);
if(currentRot < targetRot) {
currentRot = targetRot;
}
}
而且这一行还修复了一些错误
if (currentRot < 0) {currentRot += 360;}