在我的游戏(基于LWJGL的3D游戏)中,我走进了一个体素(块)世界。这个角色上下移动的速度相当快,所以我希望相机能够顺畅地跟随角色。我尝试了插值,但是我必须插入的点一直在变化,因为角色不是立即采取步骤(大约5-8帧)。这会导致一些看起来不太好的晃动。有没有办法更好地做到这一点?
问候
cameraYPosition = MathHelper.sinerp(cameraYCorrectionPoint, player.y, ((float)glfwGetTime() - cameraYCorrectionTime) * (1/cameraYCorrectionDuration));
这是决定性的。 cameraYCorrectionPoint是摄像机开始插值的点,而player.y是插入的位置(显然可以改变每一帧)。另一部分是计算通过的时间并将其放大,使其范围从0到1.
这并不是真的有效,因为在初始插值完成之前位置可能会再次发生变化,从而导致丑陋的插值。那么我能做些什么才能有更好的方法呢?
这是其余的代码,但我认为这不会有多大帮助:
if(cameraYPosition == Float.MIN_VALUE) cameraYPosition = player.y;
if(player.y != cameraYPosition) {
if(cameraYCorrectionPoint == Float.MIN_VALUE) {
cameraYCorrectionPoint = cameraYPosition;
cameraYCorrectionTime = (float)glfwGetTime();
}
if(cameraYCorrectionTime <= glfwGetTime()) {
float absoluteDistance = cameraYCorrectionPoint - player.y;
float relativeDistance = cameraYPosition - player.y;
if(glfwGetTime() - cameraYCorrectionTime <= cameraYCorrectionDuration) {
cameraYPosition = MathHelper.sinerp(cameraYCorrectionPoint, player.y, ((float)glfwGetTime() - cameraYCorrectionTime) * (1/cameraYCorrectionDuration));
}
else {
cameraYPosition = player.y;
}
lastPlayerY = player.y;
if(absoluteDistance > 0 && cameraYPosition < player.y || absoluteDistance < 0 && cameraYPosition > player.y) {
cameraYCorrectionDuration = cameraYBaseCorrectionDuration;
if(relativeDistance < 0 && cameraYPosition - player.y > 0 || relativeDistance > 0 && cameraYPosition - player.y < 0) {
cameraYPosition = player.y;
}
else {
cameraYCorrectionPoint = cameraYPosition;
}
}
}
}
else {
cameraYCorrectionDuration = cameraYBaseCorrectionDuration;
cameraYCorrectionPoint = Float.MIN_VALUE;
}
我的插值代码:
package main;
public class MathHelper {
public static float hermite(float start, float end, float value) {
return lerp(start, end, value * value * (3.0f - 2.0f * value));
}
public static float sinerp(float start, float end, float value) {
return lerp(start, end, (float)Math.sin(value * Math.PI * 0.5f));
}
public static float coserp(float start, float end, float value) {
return lerp(start, end, 1.0f - (float)Math.cos(value * Math.PI * 0.5f));
}
public static float lerp(float start, float end, float value) {
return ((1.0f - value) * start) + (value * end);
}
}
答案 0 :(得分:4)
您可以对相机进行一些不同的建模。将位置拆分为当前位置和目标位置。想要移动相机时,只移动目标位置。然后,每帧,更新当前相机位置以更接近目标位置。我对以下更新有很好的经验:
factor = f ^ t
currentCamera = factor * currentCamera + (1 - factor) * targetCamera
f
是一个因素,可让您选择相机的反应立即程度。较高的值将导致非常失去运动,值为0将使摄像机完全遵循其目标。 t
是自上次更新呼叫以来的时间。如果t
以毫秒为单位进行衡量,则f
的值应介于0.95和0.99之间。