相机应该顺利地跟随特定点

时间:2015-08-31 16:23:51

标签: java opengl lwjgl interpolation

在我的游戏(基于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);
    }
}

1 个答案:

答案 0 :(得分:4)

您可以对相机进行一些不同的建模。将位置拆分为当前位置和目标位置。想要移动相机时,只移动目标位置。然后,每帧,更新当前相机位置以更接近目标位置。我对以下更新有很好的经验:

factor = f ^ t
currentCamera = factor * currentCamera + (1 - factor) * targetCamera

f是一个因素,可让您选择相机的反应立即程度。较高的值将导致非常失去运动,值为0将使摄像机完全遵循其目标。 t是自上次更新呼叫以来的时间。如果t以毫秒为单位进行衡量,则f的值应介于0.95和0.99之间。