添加子弹数量更改时的颜色和数值更改动画
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.animation.AnimationCurves;
|
||||
import com.atsuishio.superbwarfare.tools.animation.AnimationTimer;
|
||||
import com.atsuishio.superbwarfare.tools.animation.DualValueHolder;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.ChatFormatting;
|
||||
|
@ -215,11 +216,16 @@ public class AmmoBarOverlay {
|
|||
.forwardAnimation(AnimationCurves.EASE_OUT_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
|
||||
public static void renderAmmoInfo(RenderGuiEvent.Pre event) {
|
||||
boolean startRenderingAmmoInfo = false;
|
||||
Player player = Minecraft.getInstance().player;
|
||||
if (player == null || player.isSpectator()) return;
|
||||
|
||||
|
@ -227,6 +233,8 @@ public class AmmoBarOverlay {
|
|||
var currentTime = System.currentTimeMillis();
|
||||
ItemStack stack = player.getMainHandItem();
|
||||
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);
|
||||
} else {
|
||||
ammoInfoTimer.backward(currentTime);
|
||||
|
@ -245,25 +253,68 @@ public class AmmoBarOverlay {
|
|||
int w = event.getWindow().getGuiScaledWidth();
|
||||
int h = event.getWindow().getGuiScaledHeight();
|
||||
|
||||
// 总体透明度设置
|
||||
RenderSystem.setShaderColor(1, 1, 1, Mth.lerp(ammoInfoTimer.getProgress(currentTime), 0, 1));
|
||||
var font = Minecraft.getInstance().font;
|
||||
|
||||
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(
|
||||
Minecraft.getInstance().font,
|
||||
ammoCountStr,
|
||||
w + xOffset + (30 - font.width(ammoCountStr)),
|
||||
h + yOffset,
|
||||
0xFFFFFF,
|
||||
fontColor,
|
||||
true
|
||||
);
|
||||
|
||||
// 弹药类型
|
||||
event.getGuiGraphics().drawString(
|
||||
Minecraft.getInstance().font,
|
||||
Component.translatable(type.translatableKey).getString(),
|
||||
w + xOffset + 35,
|
||||
h + yOffset,
|
||||
0xFFFFFF,
|
||||
fontColor,
|
||||
true
|
||||
);
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ import net.minecraft.util.Mth;
|
|||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 可以更改计时方向的动画计时器
|
||||
*/
|
||||
public class AnimationTimer {
|
||||
private final long duration;
|
||||
private long startTime;
|
||||
|
@ -23,15 +26,25 @@ public class AnimationTimer {
|
|||
this.duration = duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置正向和反向计时时采用的动画曲线
|
||||
*/
|
||||
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;
|
||||
|
@ -72,12 +85,14 @@ public class AnimationTimer {
|
|||
var currentTime = System.currentTimeMillis();
|
||||
for (int i = 0; i < size; i++) {
|
||||
timers[i] = new AnimationTimer(duration).forwardAnimation(forwardAnimationCurve).backwardAnimation(backwardAnimationCurve);
|
||||
timers[i].end();
|
||||
timers[i].backward(currentTime);
|
||||
timers[i].endBackward(currentTime);
|
||||
}
|
||||
return timers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前计时方向是否为正向
|
||||
*/
|
||||
public boolean isForward() {
|
||||
return !reversed;
|
||||
}
|
||||
|
@ -130,7 +145,7 @@ public class AnimationTimer {
|
|||
}
|
||||
|
||||
/**
|
||||
* 正向开始计时
|
||||
* 将计时方向更改为正向
|
||||
*/
|
||||
public void forward(long currentTime) {
|
||||
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) {
|
||||
if (!initialized) {
|
||||
|
@ -155,4 +187,20 @@ public class AnimationTimer {
|
|||
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