diff --git a/src/main/java/com/atsuishio/superbwarfare/client/overlay/AmmoBarOverlay.java b/src/main/java/com/atsuishio/superbwarfare/client/overlay/AmmoBarOverlay.java index 52907b1e2..21944d54b 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/overlay/AmmoBarOverlay.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/overlay/AmmoBarOverlay.java @@ -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); /** * 在手持弹药或弹药盒时,渲染玩家弹药总量信息 diff --git a/src/main/java/com/atsuishio/superbwarfare/client/overlay/VehicleHudOverlay.java b/src/main/java/com/atsuishio/superbwarfare/client/overlay/VehicleHudOverlay.java index 6941af38d..b02dc9175 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/overlay/VehicleHudOverlay.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/overlay/VehicleHudOverlay.java @@ -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) diff --git a/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java index 76b1810f1..622a8564e 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java @@ -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) { diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/animation/AnimationCurves.java b/src/main/java/com/atsuishio/superbwarfare/tools/animation/AnimationCurves.java index 352e87361..ad8cc6200 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/animation/AnimationCurves.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/animation/AnimationCurves.java @@ -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 LINEAR = progress -> progress; - public static final Function EASE_OUT_CIRC = progress -> (float) Math.sqrt(1 - Math.pow(progress - 1, 2)); + + public static final Function LINEAR = x -> x; + public static final Function EASE_OUT_CIRC = x -> Math.sqrt(1 - Math.pow(x - 1, 2)); + public static final Function EASE_IN_EXPO = x -> x == 0 ? 0 : Math.pow(2, 10 * x - 10); + public static final Function EASE_OUT_EXPO = x -> x == 1 ? 1 : (1 - Math.pow(2, -10 * x)); + public static final Function 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 PARABOLA = x -> -Math.pow(2 * x - 1, 2) + 1; } diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/animation/AnimationTimer.java b/src/main/java/com/atsuishio/superbwarfare/tools/animation/AnimationTimer.java index 33f3b8956..5cf56e9e5 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/animation/AnimationTimer.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/animation/AnimationTimer.java @@ -11,26 +11,30 @@ public class AnimationTimer { private boolean initialized; private boolean isStart = true; - private final Function animationCurve; + private Function forwardAnimationCurve = AnimationCurves.LINEAR; + private Function 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 animationCurve) { - this.duration = duration; - this.animationCurve = animationCurve; + public AnimationTimer animation(Function animationCurve) { + return this.forwardAnimation(animationCurve).backwardAnimation(animationCurve); + } + + public AnimationTimer forwardAnimation(Function animationCurve) { + this.forwardAnimationCurve = animationCurve; + return this; + } + + public AnimationTimer backwardAnimation(Function 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 animationCurve) { + public static AnimationTimer[] createTimers(int size, long duration, Function animationCurve) { + return createTimers(size, duration, animationCurve, animationCurve); + } + + /** + * 创建多个动画计时器 + * + * @param size 计时器数量 + * @param duration 动画持续时间,单位为毫秒 + * @param forwardAnimationCurve 正向动画曲线函数 + * @param backwardAnimationCurve 反向动画曲线函数 + */ + public static AnimationTimer[] createTimers(int size, long duration, Function forwardAnimationCurve, Function 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(); } }