添加子弹数量更改时的颜色和数值更改动画
This commit is contained in:
parent
c237cca842
commit
1aeb3d65fc
3 changed files with 147 additions and 7 deletions
|
@ -14,6 +14,7 @@ import com.atsuishio.superbwarfare.tools.GunsTool;
|
||||||
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
import com.atsuishio.superbwarfare.tools.InventoryTool;
|
||||||
import com.atsuishio.superbwarfare.tools.animation.AnimationCurves;
|
import com.atsuishio.superbwarfare.tools.animation.AnimationCurves;
|
||||||
import com.atsuishio.superbwarfare.tools.animation.AnimationTimer;
|
import com.atsuishio.superbwarfare.tools.animation.AnimationTimer;
|
||||||
|
import com.atsuishio.superbwarfare.tools.animation.DualValueHolder;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
|
@ -215,11 +216,16 @@ public class AmmoBarOverlay {
|
||||||
.forwardAnimation(AnimationCurves.EASE_OUT_EXPO)
|
.forwardAnimation(AnimationCurves.EASE_OUT_EXPO)
|
||||||
.backwardAnimation(AnimationCurves.EASE_IN_EXPO);
|
.backwardAnimation(AnimationCurves.EASE_IN_EXPO);
|
||||||
|
|
||||||
|
private static final DualValueHolder<Integer>[] ammoCountHolders = DualValueHolder.create(AmmoType.values().length, 0);
|
||||||
|
|
||||||
|
private static final AnimationTimer[] ammoCountTimers = AnimationTimer.createTimers(AmmoType.values().length, 800, AnimationCurves.EASE_OUT_EXPO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在手持弹药或弹药盒时,渲染玩家弹药总量信息
|
* 在手持弹药或弹药盒时,渲染玩家弹药总量信息
|
||||||
*/
|
*/
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void renderAmmoInfo(RenderGuiEvent.Pre event) {
|
public static void renderAmmoInfo(RenderGuiEvent.Pre event) {
|
||||||
|
boolean startRenderingAmmoInfo = false;
|
||||||
Player player = Minecraft.getInstance().player;
|
Player player = Minecraft.getInstance().player;
|
||||||
if (player == null || player.isSpectator()) return;
|
if (player == null || player.isSpectator()) return;
|
||||||
|
|
||||||
|
@ -227,6 +233,8 @@ public class AmmoBarOverlay {
|
||||||
var currentTime = System.currentTimeMillis();
|
var currentTime = System.currentTimeMillis();
|
||||||
ItemStack stack = player.getMainHandItem();
|
ItemStack stack = player.getMainHandItem();
|
||||||
if ((stack.getItem() instanceof AmmoSupplierItem || stack.getItem() == ModItems.AMMO_BOX.get()) && !(player.getVehicle() instanceof ArmedVehicleEntity vehicle && vehicle.banHand(player))) {
|
if ((stack.getItem() instanceof AmmoSupplierItem || stack.getItem() == ModItems.AMMO_BOX.get()) && !(player.getVehicle() instanceof ArmedVehicleEntity vehicle && vehicle.banHand(player))) {
|
||||||
|
// 刚拿出弹药物品时,视为开始弹药信息渲染
|
||||||
|
startRenderingAmmoInfo = ammoInfoTimer.getProgress(currentTime) == 0;
|
||||||
ammoInfoTimer.forward(currentTime);
|
ammoInfoTimer.forward(currentTime);
|
||||||
} else {
|
} else {
|
||||||
ammoInfoTimer.backward(currentTime);
|
ammoInfoTimer.backward(currentTime);
|
||||||
|
@ -245,25 +253,68 @@ public class AmmoBarOverlay {
|
||||||
int w = event.getWindow().getGuiScaledWidth();
|
int w = event.getWindow().getGuiScaledWidth();
|
||||||
int h = event.getWindow().getGuiScaledHeight();
|
int h = event.getWindow().getGuiScaledHeight();
|
||||||
|
|
||||||
|
// 总体透明度设置
|
||||||
RenderSystem.setShaderColor(1, 1, 1, Mth.lerp(ammoInfoTimer.getProgress(currentTime), 0, 1));
|
RenderSystem.setShaderColor(1, 1, 1, Mth.lerp(ammoInfoTimer.getProgress(currentTime), 0, 1));
|
||||||
var font = Minecraft.getInstance().font;
|
var font = Minecraft.getInstance().font;
|
||||||
|
|
||||||
for (var type : AmmoType.values()) {
|
for (var type : AmmoType.values()) {
|
||||||
var ammoCountStr = Integer.toString(type.get(cap));
|
var index = type.ordinal();
|
||||||
|
var ammoCount = type.get(cap);
|
||||||
|
var holder = ammoCountHolders[index];
|
||||||
|
var timer = ammoCountTimers[index];
|
||||||
|
|
||||||
|
// 首次开始渲染弹药信息时,记录弹药数量,便于后续播放动画
|
||||||
|
if (startRenderingAmmoInfo) {
|
||||||
|
holder.reset(ammoCount);
|
||||||
|
timer.endForward(currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
int isAdd = ammoCount == holder.oldValue() ? 0 : (ammoCount > holder.oldValue() ? 1 : -1);
|
||||||
|
// 弹药数量变化时,开始播放弹药数量更改动画
|
||||||
|
if (holder.newValue() != ammoCount) {
|
||||||
|
// 更新初始和当前弹药数量,播放由 初始弹药数量 -> 当前弹药数量 的动画
|
||||||
|
holder.update(ammoCount);
|
||||||
|
// 开始播放弹药数量更改动画
|
||||||
|
timer.beginForward(currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
var progress = timer.getProgress(currentTime);
|
||||||
|
var ammoCountStr = Integer.toString(
|
||||||
|
Math.round(Mth.lerp(progress, holder.oldValue(), ammoCount))
|
||||||
|
);
|
||||||
|
|
||||||
|
// 弹药增加时,颜色由绿变白,否则由红变白
|
||||||
|
var fontColor = switch (isAdd) {
|
||||||
|
case 1 -> Mth.color(
|
||||||
|
Mth.lerp(progress, 0, 1),
|
||||||
|
1,
|
||||||
|
Mth.lerp(progress, 0, 1)
|
||||||
|
);
|
||||||
|
case -1 -> Mth.color(
|
||||||
|
1,
|
||||||
|
Mth.lerp(progress, 0, 1),
|
||||||
|
Mth.lerp(progress, 0, 1)
|
||||||
|
);
|
||||||
|
default -> 0xFFFFFF;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 弹药数量
|
||||||
event.getGuiGraphics().drawString(
|
event.getGuiGraphics().drawString(
|
||||||
Minecraft.getInstance().font,
|
Minecraft.getInstance().font,
|
||||||
ammoCountStr,
|
ammoCountStr,
|
||||||
w + xOffset + (30 - font.width(ammoCountStr)),
|
w + xOffset + (30 - font.width(ammoCountStr)),
|
||||||
h + yOffset,
|
h + yOffset,
|
||||||
0xFFFFFF,
|
fontColor,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 弹药类型
|
||||||
event.getGuiGraphics().drawString(
|
event.getGuiGraphics().drawString(
|
||||||
Minecraft.getInstance().font,
|
Minecraft.getInstance().font,
|
||||||
Component.translatable(type.translatableKey).getString(),
|
Component.translatable(type.translatableKey).getString(),
|
||||||
w + xOffset + 35,
|
w + xOffset + 35,
|
||||||
h + yOffset,
|
h + yOffset,
|
||||||
0xFFFFFF,
|
fontColor,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,9 @@ import net.minecraft.util.Mth;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可以更改计时方向的动画计时器
|
||||||
|
*/
|
||||||
public class AnimationTimer {
|
public class AnimationTimer {
|
||||||
private final long duration;
|
private final long duration;
|
||||||
private long startTime;
|
private long startTime;
|
||||||
|
@ -23,15 +26,25 @@ public class AnimationTimer {
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置正向和反向计时时采用的动画曲线
|
||||||
|
*/
|
||||||
public AnimationTimer animation(Function<Double, Double> animationCurve) {
|
public AnimationTimer animation(Function<Double, Double> animationCurve) {
|
||||||
return this.forwardAnimation(animationCurve).backwardAnimation(animationCurve);
|
return this.forwardAnimation(animationCurve).backwardAnimation(animationCurve);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置反向计时时采用的动画曲线
|
||||||
|
*/
|
||||||
public AnimationTimer forwardAnimation(Function<Double, Double> animationCurve) {
|
public AnimationTimer forwardAnimation(Function<Double, Double> animationCurve) {
|
||||||
this.forwardAnimationCurve = animationCurve;
|
this.forwardAnimationCurve = animationCurve;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置反向计时时采用的动画曲线
|
||||||
|
*/
|
||||||
|
|
||||||
public AnimationTimer backwardAnimation(Function<Double, Double> animationCurve) {
|
public AnimationTimer backwardAnimation(Function<Double, Double> animationCurve) {
|
||||||
this.backwardAnimationCurve = animationCurve;
|
this.backwardAnimationCurve = animationCurve;
|
||||||
return this;
|
return this;
|
||||||
|
@ -72,12 +85,14 @@ public class AnimationTimer {
|
||||||
var currentTime = System.currentTimeMillis();
|
var currentTime = System.currentTimeMillis();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
timers[i] = new AnimationTimer(duration).forwardAnimation(forwardAnimationCurve).backwardAnimation(backwardAnimationCurve);
|
timers[i] = new AnimationTimer(duration).forwardAnimation(forwardAnimationCurve).backwardAnimation(backwardAnimationCurve);
|
||||||
timers[i].end();
|
timers[i].endBackward(currentTime);
|
||||||
timers[i].backward(currentTime);
|
|
||||||
}
|
}
|
||||||
return timers;
|
return timers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前计时方向是否为正向
|
||||||
|
*/
|
||||||
public boolean isForward() {
|
public boolean isForward() {
|
||||||
return !reversed;
|
return !reversed;
|
||||||
}
|
}
|
||||||
|
@ -130,7 +145,7 @@ public class AnimationTimer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 正向开始计时
|
* 将计时方向更改为正向
|
||||||
*/
|
*/
|
||||||
public void forward(long currentTime) {
|
public void forward(long currentTime) {
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
|
@ -143,7 +158,24 @@ public class AnimationTimer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 反向开始计时
|
* 开始正向计时
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void beginForward(long currentTime) {
|
||||||
|
begin();
|
||||||
|
forward(currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束正向计时
|
||||||
|
*/
|
||||||
|
public void endForward(long currentTime) {
|
||||||
|
end();
|
||||||
|
forward(currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将计时方向更改为反向
|
||||||
*/
|
*/
|
||||||
public void backward(long currentTime) {
|
public void backward(long currentTime) {
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
|
@ -155,4 +187,20 @@ public class AnimationTimer {
|
||||||
reversed = true;
|
reversed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始反向计时
|
||||||
|
*/
|
||||||
|
public void beginBackward(long currentTime) {
|
||||||
|
begin();
|
||||||
|
backward(currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束反向计时
|
||||||
|
*/
|
||||||
|
public void endBackward(long currentTime) {
|
||||||
|
end();
|
||||||
|
backward(currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.atsuishio.superbwarfare.tools.animation;
|
||||||
|
|
||||||
|
public class DualValueHolder<T> {
|
||||||
|
private T oldValue;
|
||||||
|
private T newValue;
|
||||||
|
|
||||||
|
public static <T> DualValueHolder<T>[] create(int size, T defaultValue) {
|
||||||
|
// 傻逼Java
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
DualValueHolder<T>[] holders = new DualValueHolder[size];
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
holders[i] = new DualValueHolder<>();
|
||||||
|
holders[i].reset(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return holders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(T value) {
|
||||||
|
this.oldValue = this.newValue;
|
||||||
|
this.newValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset(T value) {
|
||||||
|
this.oldValue = value;
|
||||||
|
this.newValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T oldValue() {
|
||||||
|
return this.oldValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T newValue() {
|
||||||
|
return this.newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean changed() {
|
||||||
|
return this.oldValue.equals(this.newValue);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue