不确定libgdx是否提供此功能,因此它可能是一个数学问题。我将各种3D相机坐标存储为Vector3
,我想将相机从一个移动到另一个。
Vector3 CAM_POSITION_DEFAULT = new Vector3(0f, 1f, -5f);
Vector3 CAM_POSITION_TOP = new Vector3(0f, 10f, -5f);
我可以将相机位置设置为新位置,但这太过分了。一个很好的平滑过渡,有一些缓和(慢启动,快中速,慢速结束)将是理想的。
这只是一个简单的矩阵操作,还是有一种通过缓和来获得此功能的整洁方法?其次,如果可以使用缓存,是否可以使用不同形式的缓动(如在javascript的jQuery库中)?
非常感谢。
答案 0 :(得分:2)
您正在寻找的是两个位置之间的简单线性插值。
要实现这一点,您可以使用libgdx提供的lerp(...)方法。
如果要计算CAM_POSITION_DEFAULT
和CAM_POSITION_TOP
之间的位置,只需在两个向量之间进行插值:
Vector3 inbetween = CAM_POSITION_DEFAULT.lerp(CAM_POSITION_TOP, alpha);
如果你提供alpha = 0的值,你会得到CAM_POSITION_DEFAULT,如果你提供alpha = 1,你将获得CAM_POSITION_TOP ... alpha = 0.5f因此将直接在两个位置的中间点...
现在的诀窍是如何为平滑过渡选择alpha值,该过渡需要一定的秒数:
class CameraTransition {
private final Vector3 startPos;
private final Vector3 goalPos;
private final float duration;
private float stateTime = 0.0f;
public CameraTransition(final Vector3 startPos, final Vector3 goalPos, float duration) {
this.startPos = startPos;
this.goalPos = goalPos;
this.duration = duration;
}
public Vector3 act(float delta) {
stateTime += delta;
return startPos.lerp(goalPos, MathUtils.clamp(stateTime/duration, 0.0f,1.0f));
}
}
所以你可以使用这段代码(未经测试,对不起)...创建一个新的CameraTransition并设置持续时间。
然后在你的render(float delta)
中你必须调用act()方法并传递增量时间。
当然,只有在希望运行转换时才应调用act()方法。
希望这有助于......:)
<强>更新强>
在看到你正在寻找一个缓慢开始并缓慢结束的平滑过渡之后,我已经将插值更改为使用更平滑的曲线而不是线性插值的东西:
class CameraTransition {
private final Vector3 startPos;
private final Vector3 goalPos;
private final float duration;
private float stateTime = 0.0f;
private float alpha;
public CameraTransition(final Vector3 startPos, final Vector3 goalPos, float duration) {
this.startPos = startPos;
this.goalPos = goalPos;
this.duration = duration;
}
public Vector3 act(float delta) {
stateTime += delta;
alpha = MathUtils.clamp(stateTime/duration, 0.0f,1.0f);
return startPos.lerp(goalPos, -2 * alpha*alpha*alpha + 3 * alpha*alpha);
}
}
在这个版本中,我正在进行线性插值以使用此曲线:
f(x) = -2*alpha^3 + 3*alpha^2
http://www.wolframalpha.com/input/?i=plot+f%28x%29+%3D+-2x%5E3+%2B3x%5E2+from+0+to+1