优化动画曲线

This commit is contained in:
Light_Quanta 2025-03-20 10:16:31 +08:00
parent c95fefe681
commit c237cca842
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
5 changed files with 49 additions and 22 deletions

View file

@ -211,7 +211,9 @@ public class AmmoBarOverlay {
}
}
private static final AnimationTimer ammoInfoTimer = new AnimationTimer(500, AnimationCurves.EASE_OUT_CIRC);
private static final AnimationTimer ammoInfoTimer = new AnimationTimer(1500)
.forwardAnimation(AnimationCurves.EASE_OUT_EXPO)
.backwardAnimation(AnimationCurves.EASE_IN_EXPO);
/**
* 在手持弹药或弹药盒时渲染玩家弹药总量信息

View file

@ -71,7 +71,7 @@ public class VehicleHudOverlay {
private static boolean lastTimeRenderingWeapons = false;
private static int lastTimeWeaponIndex = 0;
private static int lastTimeRenderWeaponIndex = 0;
private static final AnimationTimer weaponIndexUpdateTimer = new AnimationTimer(ANIMATION_TIME, AnimationCurves.EASE_OUT_CIRC);
private static final AnimationTimer weaponIndexUpdateTimer = new AnimationTimer(ANIMATION_TIME).animation(AnimationCurves.EASE_OUT_CIRC);
@SubscribeEvent(priority = EventPriority.HIGH)

View file

@ -16,6 +16,7 @@ import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.perk.PerkHelper;
import com.atsuishio.superbwarfare.tools.*;
import com.atsuishio.superbwarfare.tools.animation.AnimationCurves;
import net.minecraft.client.CameraType;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
@ -1045,8 +1046,8 @@ public class ClientEventHandler {
} else {
zoomTime = Mth.clamp(zoomTime - 0.04 * speed * times, 0, 1);
}
zoomPos = 0.5 * Math.cos(Math.PI * Math.pow(Math.pow(zoomTime, 2) - 1, 2)) + 0.5;
zoomPosZ = -Math.pow(2 * zoomTime - 1, 2) + 1;
zoomPos = AnimationCurves.EASE_IN_OUT_QUINT.apply(zoomTime);
zoomPosZ = AnimationCurves.PARABOLA.apply(zoomTime);
}
private static void handleWeaponFire(ViewportEvent.ComputeCameraAngles event, LivingEntity entity) {

View file

@ -3,7 +3,15 @@ package com.atsuishio.superbwarfare.tools.animation;
import java.util.function.Function;
// https://easings.net/
public class AnimationCurves {
public static final Function<Float, Float> LINEAR = progress -> progress;
public static final Function<Float, Float> EASE_OUT_CIRC = progress -> (float) Math.sqrt(1 - Math.pow(progress - 1, 2));
public static final Function<Double, Double> LINEAR = x -> x;
public static final Function<Double, Double> EASE_OUT_CIRC = x -> Math.sqrt(1 - Math.pow(x - 1, 2));
public static final Function<Double, Double> EASE_IN_EXPO = x -> x == 0 ? 0 : Math.pow(2, 10 * x - 10);
public static final Function<Double, Double> EASE_OUT_EXPO = x -> x == 1 ? 1 : (1 - Math.pow(2, -10 * x));
public static final Function<Double, Double> EASE_IN_OUT_QUINT = x -> x < 0.5 ? 4 * x * x * x : (1 - Math.pow(-2 * x + 2, 3) / 2);
// wtf
public static final Function<Double, Double> PARABOLA = x -> -Math.pow(2 * x - 1, 2) + 1;
}

View file

@ -11,26 +11,30 @@ public class AnimationTimer {
private boolean initialized;
private boolean isStart = true;
private final Function<Float, Float> animationCurve;
private Function<Double, Double> forwardAnimationCurve = AnimationCurves.LINEAR;
private Function<Double, Double> backwardAnimationCurve = AnimationCurves.LINEAR;
/**
* 创建一个反向线性动画计时器
* 创建一个动画计时器
*
* @param duration 动画持续时间单位为毫秒
*/
public AnimationTimer(long duration) {
this(duration, AnimationCurves.LINEAR);
this.duration = duration;
}
/**
* 创建一个反向动画计时器
*
* @param duration 动画持续时间单位为毫秒
* @param animationCurve 动画曲线函数
*/
public AnimationTimer(long duration, Function<Float, Float> animationCurve) {
this.duration = duration;
this.animationCurve = animationCurve;
public AnimationTimer animation(Function<Double, Double> animationCurve) {
return this.forwardAnimation(animationCurve).backwardAnimation(animationCurve);
}
public AnimationTimer forwardAnimation(Function<Double, Double> animationCurve) {
this.forwardAnimationCurve = animationCurve;
return this;
}
public AnimationTimer backwardAnimation(Function<Double, Double> animationCurve) {
this.backwardAnimationCurve = animationCurve;
return this;
}
/**
@ -51,11 +55,23 @@ public class AnimationTimer {
* @param duration 动画持续时间单位为毫秒
* @param animationCurve 动画曲线函数
*/
public static AnimationTimer[] createTimers(int size, long duration, Function<Float, Float> animationCurve) {
public static AnimationTimer[] createTimers(int size, long duration, Function<Double, Double> animationCurve) {
return createTimers(size, duration, animationCurve, animationCurve);
}
/**
* 创建多个动画计时器
*
* @param size 计时器数量
* @param duration 动画持续时间单位为毫秒
* @param forwardAnimationCurve 正向动画曲线函数
* @param backwardAnimationCurve 反向动画曲线函数
*/
public static AnimationTimer[] createTimers(int size, long duration, Function<Double, Double> forwardAnimationCurve, Function<Double, Double> backwardAnimationCurve) {
var timers = new AnimationTimer[size];
var currentTime = System.currentTimeMillis();
for (int i = 0; i < size; i++) {
timers[i] = new AnimationTimer(duration, animationCurve);
timers[i] = new AnimationTimer(duration).forwardAnimation(forwardAnimationCurve).backwardAnimation(backwardAnimationCurve);
timers[i].end();
timers[i].backward(currentTime);
}
@ -74,9 +90,9 @@ public class AnimationTimer {
*/
public float getProgress(long currentTime) {
if (reversed) {
return 1 - animationCurve.apply(Mth.clamp(1 - getElapsedTime(currentTime) / (float) duration, 0, 1));
return 1 - backwardAnimationCurve.apply(Mth.clamp(1 - getElapsedTime(currentTime) / (double) duration, 0, 1)).floatValue();
} else {
return animationCurve.apply(Mth.clamp(getElapsedTime(currentTime) / (float) duration, 0, 1));
return forwardAnimationCurve.apply(Mth.clamp(getElapsedTime(currentTime) / (double) duration, 0, 1)).floatValue();
}
}