使用 lwjgl 为对象设置动画的正确框架?

Proper framework for animating objects with lwjgl?

我的目标是在屏幕上绘制二维 UI 元素并为其设置动画。问题是,我不确定如何在不占用大量 space 的情况下为其设置动画。 这就是我的方法在 0, 0 处绘制一个宽度和高度为 50

的红色矩形的样子
public void render() {
    Gui.drawRect(0, 0, 50, 50, Color.red); // Drawing an object would look something like this
}

现在,我要做的是定义一个变量,例如 rectanglePos = 0,并将其添加到我想要更改的轴上。 drawRect(0 + rectanglePos, 0, 50, 50, Color.red); 现在,当我想为矩形设置动画时,我创建了一个新线程并从那里为其设置了动画。

public void render() {
    Gui.drawRect(0 + rectanglePos, 0, 50, 50, Color.red); // Drawing an object would look something like this
}


public void animate() {
   Thread t = new Thread(() -> {
       float target = 50;

       for (int i = 0; i < 50; i++) {
            //ease(int start, int end, float time, EasingType type)
            rectanglePos = AnimationUtil.ease(0, target, 5, EasingType.CubicInOut);
       }
   });
   t.start();
}

这里的这个例子显然很糟糕。我的问题是,构建它的最佳方式是什么?

使用 System.currentTimeMillis(),我们可以使用缓动函数为屏幕上的二维 UI 元素设置动画,无需线程或其他花哨的东西。假设我们希望动画在 x 轴上移动,从 10 开始到 50 结束。假设我们知道何时开始和持续时间,我们就可以计算出动画何时结束。

假设time等于当前时间,startTime等于我们开始的时间,依此类推... 在一个单独的 class 中,我们需要一些方法来帮忙。一种方法returns我们动画的进度。有关标准缓动函数的列表,请参阅 Easing Functions。另一种方法将此值转换为开始和结束像素。

当前进度等于(time - startTime) / duration。这已经为我们提供了放入 ease 方法的价值。 ease 方法 returns 一个介于 0.01.0 之间的值,因此我们要做的就是将其“转换”为像素。公式为:(end - start) * ease(alpha).

下面是该概念的实现。没有什么是完美的。

long startTime = 0L;

public void animate() {
    this.startTime = System.currentTimeMillis();
}

// 10, 10 -> 50, 50
public void render() {
    // 1000 milliseconds = 1 Second
    drawRect(10 + Ease.toPixels(10, 50,Ease.getProgress(this.startTime, 1000L)), 10, ... etc);
}

帮助 class:

// easeInOutCubic
public static float ease(float alpha) {
    return (float) (alpha < 0.5 ? 4 * alpha * alpha * alpha : 1 - Math.pow(-2 * alpha + 2, 3) / 2);
}

public static float getProgress(long startTime, float duration) {
    long time = System.currentTimeMillis();
    float progress = (time - startTime) / duration;

    if (progress <= 0.0F) return 0.0F;
    if (progress >= 1.0F) return 1.0F;

    return progress;
}

public static int toPixels(float start, float end, float alpha) {
    return (int) ((end - start) * ease(alpha));
}