调整弹药总量显示位置,添加弹药盒弹药数量显示,添加更多动画
This commit is contained in:
parent
1aeb3d65fc
commit
3255c0754a
6 changed files with 204 additions and 115 deletions
|
@ -14,14 +14,14 @@ 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.atsuishio.superbwarfare.tools.animation.ValueAnimator;
|
||||||
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;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.FastColor;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
@ -215,10 +215,17 @@ public class AmmoBarOverlay {
|
||||||
private static final AnimationTimer ammoInfoTimer = new AnimationTimer(1500)
|
private static final AnimationTimer ammoInfoTimer = new AnimationTimer(1500)
|
||||||
.forwardAnimation(AnimationCurves.EASE_OUT_EXPO)
|
.forwardAnimation(AnimationCurves.EASE_OUT_EXPO)
|
||||||
.backwardAnimation(AnimationCurves.EASE_IN_EXPO);
|
.backwardAnimation(AnimationCurves.EASE_IN_EXPO);
|
||||||
|
private static final AnimationTimer ammoBoxTimer = new AnimationTimer(1500)
|
||||||
|
.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 ValueAnimator<Integer>[] ammoCountAnimators = ValueAnimator.create(
|
||||||
|
AmmoType.values().length, 800, 0
|
||||||
|
);
|
||||||
|
private static final ValueAnimator<Integer>[] ammoBoxAnimators = ValueAnimator.create(
|
||||||
|
AmmoType.values().length, 800, 0
|
||||||
|
);
|
||||||
|
|
||||||
private static final AnimationTimer[] ammoCountTimers = AnimationTimer.createTimers(AmmoType.values().length, 800, AnimationCurves.EASE_OUT_EXPO);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在手持弹药或弹药盒时,渲染玩家弹药总量信息
|
* 在手持弹药或弹药盒时,渲染玩家弹药总量信息
|
||||||
|
@ -229,80 +236,100 @@ public class AmmoBarOverlay {
|
||||||
Player player = Minecraft.getInstance().player;
|
Player player = Minecraft.getInstance().player;
|
||||||
if (player == null || player.isSpectator()) return;
|
if (player == null || player.isSpectator()) return;
|
||||||
|
|
||||||
|
boolean isAmmoBox = false;
|
||||||
|
|
||||||
// 动画计算
|
// 动画计算
|
||||||
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;
|
startRenderingAmmoInfo = ammoInfoTimer.getProgress(currentTime) == 0;
|
||||||
ammoInfoTimer.forward(currentTime);
|
ammoInfoTimer.forward(currentTime);
|
||||||
|
|
||||||
|
if (stack.getItem() == ModItems.AMMO_BOX.get()) {
|
||||||
|
isAmmoBox = true;
|
||||||
|
ammoBoxTimer.forward(currentTime);
|
||||||
|
} else {
|
||||||
|
ammoBoxTimer.backward(currentTime);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ammoInfoTimer.backward(currentTime);
|
ammoInfoTimer.backward(currentTime);
|
||||||
|
ammoBoxTimer.backward(currentTime);
|
||||||
}
|
}
|
||||||
if (!ammoInfoTimer.isForward() && ammoInfoTimer.finished(currentTime)) return;
|
if (!ammoInfoTimer.isForward() && ammoInfoTimer.finished(currentTime)) return;
|
||||||
|
|
||||||
var poseStack = event.getGuiGraphics().pose();
|
var poseStack = event.getGuiGraphics().pose();
|
||||||
poseStack.pushPose();
|
poseStack.pushPose();
|
||||||
|
|
||||||
var xOffset = -Mth.lerp(ammoInfoTimer.getProgress(currentTime), 0, 120);
|
|
||||||
final int fontHeight = 15;
|
|
||||||
var yOffset = -AmmoType.values().length * fontHeight;
|
|
||||||
|
|
||||||
// 渲染总弹药数量
|
|
||||||
var cap = player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables());
|
|
||||||
int w = event.getWindow().getGuiScaledWidth();
|
int w = event.getWindow().getGuiScaledWidth();
|
||||||
int h = event.getWindow().getGuiScaledHeight();
|
int h = event.getWindow().getGuiScaledHeight();
|
||||||
|
|
||||||
// 总体透明度设置
|
var ammoX = ammoInfoTimer.lerp(w + 120, (float) w / 2 + 40, currentTime);
|
||||||
RenderSystem.setShaderColor(1, 1, 1, Mth.lerp(ammoInfoTimer.getProgress(currentTime), 0, 1));
|
final int fontHeight = 15;
|
||||||
|
var yOffset = (-h - AmmoType.values().length * fontHeight) / 2f;
|
||||||
|
|
||||||
|
// 渲染总弹药数量
|
||||||
|
var cap = player.getCapability(ModVariables.PLAYER_VARIABLES_CAPABILITY, null).orElse(new ModVariables.PlayerVariables());
|
||||||
var font = Minecraft.getInstance().font;
|
var font = Minecraft.getInstance().font;
|
||||||
|
|
||||||
for (var type : AmmoType.values()) {
|
for (var type : AmmoType.values()) {
|
||||||
var index = type.ordinal();
|
var index = type.ordinal();
|
||||||
var ammoCount = type.get(cap);
|
var ammoCount = type.get(cap);
|
||||||
var holder = ammoCountHolders[index];
|
var animator = ammoCountAnimators[index];
|
||||||
var timer = ammoCountTimers[index];
|
|
||||||
|
var boxAnimator = ammoBoxAnimators[index];
|
||||||
|
var boxAmmoCount = boxAnimator.newValue();
|
||||||
|
boolean boxAmmoSelected = false;
|
||||||
|
|
||||||
|
if (isAmmoBox) {
|
||||||
|
var ammoBoxType = stack.getOrCreateTag().getString("Type");
|
||||||
|
boxAmmoCount = type.get(stack);
|
||||||
|
if (ammoBoxType.equals("All") || ammoBoxType.equals(type.name)) {
|
||||||
|
boxAnimator.forward(currentTime);
|
||||||
|
boxAmmoSelected = true;
|
||||||
|
} else {
|
||||||
|
boxAnimator.reset(boxAmmoCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 首次开始渲染弹药信息时,记录弹药数量,便于后续播放动画
|
// 首次开始渲染弹药信息时,记录弹药数量,便于后续播放动画
|
||||||
if (startRenderingAmmoInfo) {
|
if (startRenderingAmmoInfo) {
|
||||||
holder.reset(ammoCount);
|
animator.reset(ammoCount);
|
||||||
timer.endForward(currentTime);
|
animator.endForward(currentTime);
|
||||||
|
if (isAmmoBox) {
|
||||||
|
boxAnimator.reset(type.get(stack));
|
||||||
|
boxAnimator.endForward(currentTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int isAdd = ammoCount == holder.oldValue() ? 0 : (ammoCount > holder.oldValue() ? 1 : -1);
|
int ammoAdd = Integer.compare(ammoCount, animator.oldValue());
|
||||||
|
// 弹药数量变化时,更新并开始播放弹药数量更改动画
|
||||||
|
animator.compareAndUpdate(ammoCount, () -> {
|
||||||
// 弹药数量变化时,开始播放弹药数量更改动画
|
// 弹药数量变化时,开始播放弹药数量更改动画
|
||||||
if (holder.newValue() != ammoCount) {
|
animator.beginForward(currentTime);
|
||||||
// 更新初始和当前弹药数量,播放由 初始弹药数量 -> 当前弹药数量 的动画
|
});
|
||||||
holder.update(ammoCount);
|
|
||||||
// 开始播放弹药数量更改动画
|
|
||||||
timer.beginForward(currentTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
var progress = timer.getProgress(currentTime);
|
var progress = animator.getProgress(currentTime);
|
||||||
var ammoCountStr = Integer.toString(
|
var ammoCountStr = Integer.toString(
|
||||||
Math.round(Mth.lerp(progress, holder.oldValue(), ammoCount))
|
Math.round(animator.lerp(animator.oldValue(), ammoCount, currentTime))
|
||||||
);
|
);
|
||||||
|
|
||||||
// 弹药增加时,颜色由绿变白,否则由红变白
|
// 弹药增加时,颜色由绿变白,否则由红变白
|
||||||
var fontColor = switch (isAdd) {
|
var fontColor = FastColor.ARGB32.lerp(progress, switch (ammoAdd) {
|
||||||
case 1 -> Mth.color(
|
case 1 -> 0xFF00FF00;
|
||||||
Mth.lerp(progress, 0, 1),
|
case -1 -> 0xFFFF0000;
|
||||||
1,
|
default -> 0xFFFFFFFF;
|
||||||
Mth.lerp(progress, 0, 1)
|
}, 0xFFFFFFFF);
|
||||||
);
|
|
||||||
case -1 -> Mth.color(
|
RenderSystem.setShaderColor(1, 1, 1, ammoInfoTimer.lerp(0, 1, currentTime));
|
||||||
1,
|
|
||||||
Mth.lerp(progress, 0, 1),
|
|
||||||
Mth.lerp(progress, 0, 1)
|
|
||||||
);
|
|
||||||
default -> 0xFFFFFF;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 弹药数量
|
// 弹药数量
|
||||||
event.getGuiGraphics().drawString(
|
event.getGuiGraphics().drawString(
|
||||||
Minecraft.getInstance().font,
|
font,
|
||||||
ammoCountStr,
|
ammoCountStr,
|
||||||
w + xOffset + (30 - font.width(ammoCountStr)),
|
ammoX + (30 - font.width(ammoCountStr)),
|
||||||
h + yOffset,
|
h + yOffset,
|
||||||
fontColor,
|
fontColor,
|
||||||
true
|
true
|
||||||
|
@ -310,14 +337,45 @@ public class AmmoBarOverlay {
|
||||||
|
|
||||||
// 弹药类型
|
// 弹药类型
|
||||||
event.getGuiGraphics().drawString(
|
event.getGuiGraphics().drawString(
|
||||||
Minecraft.getInstance().font,
|
font,
|
||||||
Component.translatable(type.translatableKey).getString(),
|
Component.translatable(type.translatableKey).getString(),
|
||||||
w + xOffset + 35,
|
ammoX + 35,
|
||||||
h + yOffset,
|
h + yOffset,
|
||||||
fontColor,
|
fontColor,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 弹药盒信息渲染
|
||||||
|
RenderSystem.setShaderColor(1, 1, 1, ammoBoxTimer.lerp(0, 1, currentTime));
|
||||||
|
var ammoBoxX = ammoBoxTimer.lerp(-30, (float) w / 2, currentTime);
|
||||||
|
|
||||||
|
int ammoBoxAdd = Integer.compare(boxAmmoCount, boxAnimator.oldValue());
|
||||||
|
boxAnimator.compareAndUpdate(boxAmmoCount, () -> boxAnimator.beginForward(currentTime));
|
||||||
|
|
||||||
|
// 选中时显示为黄色,否则为白色
|
||||||
|
var targetColor = boxAmmoSelected ? 0xFFFFFF00 : 0xFFFFFFFF;
|
||||||
|
|
||||||
|
var boxFontColor = FastColor.ARGB32.lerp(boxAnimator.getProgress(currentTime),
|
||||||
|
switch (ammoBoxAdd) {
|
||||||
|
case 1 -> 0xFF00FF00;
|
||||||
|
case -1 -> 0xFFFF0000;
|
||||||
|
default -> targetColor;
|
||||||
|
},
|
||||||
|
targetColor
|
||||||
|
);
|
||||||
|
|
||||||
|
// 弹药盒内弹药数量
|
||||||
|
event.getGuiGraphics().drawString(
|
||||||
|
Minecraft.getInstance().font,
|
||||||
|
Integer.toString(
|
||||||
|
Math.round(boxAnimator.lerp(boxAnimator.oldValue(), boxAmmoCount, currentTime))
|
||||||
|
),
|
||||||
|
ammoBoxX - 70,
|
||||||
|
h + yOffset,
|
||||||
|
boxFontColor,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
yOffset += fontHeight;
|
yOffset += fontHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,9 +68,9 @@ public class VehicleHudOverlay {
|
||||||
|
|
||||||
public static final int ANIMATION_TIME = 300;
|
public static final int ANIMATION_TIME = 300;
|
||||||
private static final AnimationTimer[] weaponSlotsTimer = AnimationTimer.createTimers(9, ANIMATION_TIME, AnimationCurves.EASE_OUT_CIRC);
|
private static final AnimationTimer[] weaponSlotsTimer = AnimationTimer.createTimers(9, ANIMATION_TIME, AnimationCurves.EASE_OUT_CIRC);
|
||||||
private static boolean lastTimeRenderingWeapons = false;
|
private static boolean wasRenderingWeapons = false;
|
||||||
private static int lastTimeWeaponIndex = 0;
|
private static int oldWeaponIndex = 0;
|
||||||
private static int lastTimeRenderWeaponIndex = 0;
|
private static int oldRenderWeaponIndex = 0;
|
||||||
private static final AnimationTimer weaponIndexUpdateTimer = new AnimationTimer(ANIMATION_TIME).animation(AnimationCurves.EASE_OUT_CIRC);
|
private static final AnimationTimer weaponIndexUpdateTimer = new AnimationTimer(ANIMATION_TIME).animation(AnimationCurves.EASE_OUT_CIRC);
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ public class VehicleHudOverlay {
|
||||||
Player player = Minecraft.getInstance().player;
|
Player player = Minecraft.getInstance().player;
|
||||||
|
|
||||||
if (!shouldRenderHud(player)) {
|
if (!shouldRenderHud(player)) {
|
||||||
lastTimeRenderingWeapons = false;
|
wasRenderingWeapons = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,8 +456,8 @@ public class VehicleHudOverlay {
|
||||||
private static void renderWeaponInfo(GuiGraphics guiGraphics, VehicleEntity vehicle, int w, int h) {
|
private static void renderWeaponInfo(GuiGraphics guiGraphics, VehicleEntity vehicle, int w, int h) {
|
||||||
if (!(vehicle instanceof WeaponVehicleEntity weaponVehicle)) return;
|
if (!(vehicle instanceof WeaponVehicleEntity weaponVehicle)) return;
|
||||||
|
|
||||||
var temp = lastTimeRenderingWeapons;
|
var temp = wasRenderingWeapons;
|
||||||
lastTimeRenderingWeapons = false;
|
wasRenderingWeapons = false;
|
||||||
|
|
||||||
Player player = Minecraft.getInstance().player;
|
Player player = Minecraft.getInstance().player;
|
||||||
assert player != null;
|
assert player != null;
|
||||||
|
@ -471,37 +471,33 @@ public class VehicleHudOverlay {
|
||||||
int weaponIndex = weaponVehicle.getWeaponIndex(index);
|
int weaponIndex = weaponVehicle.getWeaponIndex(index);
|
||||||
if (weaponIndex == -1) return;
|
if (weaponIndex == -1) return;
|
||||||
|
|
||||||
lastTimeRenderingWeapons = temp;
|
wasRenderingWeapons = temp;
|
||||||
|
|
||||||
var currentTime = System.currentTimeMillis();
|
var currentTime = System.currentTimeMillis();
|
||||||
|
|
||||||
// 若上一帧未在渲染武器信息,则初始化动画相关变量
|
// 若上一帧未在渲染武器信息,则初始化动画相关变量
|
||||||
if (!lastTimeRenderingWeapons) {
|
if (!wasRenderingWeapons) {
|
||||||
weaponSlotsTimer[weaponIndex].begin();
|
weaponSlotsTimer[weaponIndex].beginForward(currentTime);
|
||||||
weaponSlotsTimer[weaponIndex].forward(currentTime);
|
|
||||||
|
|
||||||
if (lastTimeWeaponIndex != weaponIndex) {
|
if (oldWeaponIndex != weaponIndex) {
|
||||||
weaponSlotsTimer[lastTimeWeaponIndex].backward(currentTime);
|
weaponSlotsTimer[oldWeaponIndex].endBackward(currentTime);
|
||||||
weaponSlotsTimer[lastTimeWeaponIndex].end();
|
|
||||||
|
|
||||||
lastTimeWeaponIndex = weaponIndex;
|
oldWeaponIndex = weaponIndex;
|
||||||
lastTimeRenderWeaponIndex = weaponIndex;
|
oldRenderWeaponIndex = weaponIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
weaponIndexUpdateTimer.begin();
|
weaponIndexUpdateTimer.beginForward(currentTime);
|
||||||
weaponIndexUpdateTimer.forward(currentTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 切换武器时,更新上一个武器槽位和当前武器槽位的动画信息
|
// 切换武器时,更新上一个武器槽位和当前武器槽位的动画信息
|
||||||
if (weaponIndex != lastTimeWeaponIndex) {
|
if (weaponIndex != oldWeaponIndex) {
|
||||||
weaponSlotsTimer[weaponIndex].forward(currentTime);
|
weaponSlotsTimer[weaponIndex].forward(currentTime);
|
||||||
weaponSlotsTimer[lastTimeWeaponIndex].backward(currentTime);
|
weaponSlotsTimer[oldWeaponIndex].backward(currentTime);
|
||||||
|
|
||||||
lastTimeRenderWeaponIndex = lastTimeWeaponIndex;
|
oldRenderWeaponIndex = oldWeaponIndex;
|
||||||
lastTimeWeaponIndex = weaponIndex;
|
oldWeaponIndex = weaponIndex;
|
||||||
|
|
||||||
weaponIndexUpdateTimer.begin();
|
weaponIndexUpdateTimer.beginForward(currentTime);
|
||||||
weaponIndexUpdateTimer.forward(currentTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var pose = guiGraphics.pose();
|
var pose = guiGraphics.pose();
|
||||||
|
@ -537,7 +533,7 @@ public class VehicleHudOverlay {
|
||||||
// 当前选中武器
|
// 当前选中武器
|
||||||
if (weaponIndex == i) {
|
if (weaponIndex == i) {
|
||||||
var startY = Mth.lerp(progress,
|
var startY = Mth.lerp(progress,
|
||||||
h - (weapons.size() - 1 - lastTimeRenderWeaponIndex) * 18 - 16,
|
h - (weapons.size() - 1 - oldRenderWeaponIndex) * 18 - 16,
|
||||||
h - (weapons.size() - 1 - weaponIndex) * 18 - 16
|
h - (weapons.size() - 1 - weaponIndex) * 18 - 16
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -562,10 +558,10 @@ public class VehicleHudOverlay {
|
||||||
pose.popPose();
|
pose.popPose();
|
||||||
|
|
||||||
// 切换武器光标动画播放结束后,更新上次选择槽位
|
// 切换武器光标动画播放结束后,更新上次选择槽位
|
||||||
if (lastTimeWeaponIndex != lastTimeRenderWeaponIndex && weaponIndexUpdateTimer.finished(currentTime)) {
|
if (oldWeaponIndex != oldRenderWeaponIndex && weaponIndexUpdateTimer.finished(currentTime)) {
|
||||||
lastTimeRenderWeaponIndex = lastTimeWeaponIndex;
|
oldRenderWeaponIndex = oldWeaponIndex;
|
||||||
}
|
}
|
||||||
lastTimeRenderingWeapons = true;
|
wasRenderingWeapons = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void renderNumber(GuiGraphics guiGraphics, int number, boolean percent, float x, float y, float scale) {
|
private static void renderNumber(GuiGraphics guiGraphics, int number, boolean percent, float x, float y, float scale) {
|
||||||
|
|
|
@ -55,6 +55,6 @@ public class AmmoSupplierItem extends Item {
|
||||||
player.displayClientMessage(Component.translatable("item.superbwarfare.ammo_supplier.supply", Component.translatable(this.type.translatableKey), ammoToAdd * count), true);
|
player.displayClientMessage(Component.translatable("item.superbwarfare.ammo_supplier.supply", Component.translatable(this.type.translatableKey), ammoToAdd * count), true);
|
||||||
level.playSound(null, player.blockPosition(), ModSounds.BULLET_SUPPLY.get(), SoundSource.PLAYERS, 1, 1);
|
level.playSound(null, player.blockPosition(), ModSounds.BULLET_SUPPLY.get(), SoundSource.PLAYERS, 1, 1);
|
||||||
}
|
}
|
||||||
return InteractionResultHolder.consume(stack);
|
return InteractionResultHolder.success(stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,7 @@ public class AnimationTimer {
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
initialized = true;
|
initialized = true;
|
||||||
startTime = currentTime + (isStart ? 0 : duration);
|
startTime = currentTime + (isStart ? 0 : duration);
|
||||||
} else {
|
} else if (reversed) {
|
||||||
startTime = currentTime - getElapsedTime(currentTime);
|
startTime = currentTime - getElapsedTime(currentTime);
|
||||||
}
|
}
|
||||||
reversed = false;
|
reversed = false;
|
||||||
|
@ -181,7 +181,7 @@ public class AnimationTimer {
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
initialized = true;
|
initialized = true;
|
||||||
startTime = currentTime + (isStart ? duration : 0);
|
startTime = currentTime + (isStart ? duration : 0);
|
||||||
} else {
|
} else if (!reversed) {
|
||||||
startTime = currentTime + getElapsedTime(currentTime);
|
startTime = currentTime + getElapsedTime(currentTime);
|
||||||
}
|
}
|
||||||
reversed = true;
|
reversed = true;
|
||||||
|
@ -203,4 +203,8 @@ public class AnimationTimer {
|
||||||
backward(currentTime);
|
backward(currentTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float lerp(float start, float end, long currentTime) {
|
||||||
|
return Mth.lerp(getProgress(currentTime), start, end);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
package com.atsuishio.superbwarfare.tools.animation;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可以存储额外的新旧数值的AnimationTimer
|
||||||
|
*/
|
||||||
|
public class ValueAnimator<T> extends AnimationTimer {
|
||||||
|
private T oldValue;
|
||||||
|
private T newValue;
|
||||||
|
|
||||||
|
public ValueAnimator(long duration, T defaultValue) {
|
||||||
|
super(duration);
|
||||||
|
reset(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ValueAnimator<T>[] create(int size, long duration, T defaultValue) {
|
||||||
|
// 傻逼Java
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
ValueAnimator<T>[] animators = (ValueAnimator<T>[]) new ValueAnimator[size];
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
animators[i] = new ValueAnimator<>(duration, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return animators;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(T value) {
|
||||||
|
this.oldValue = this.newValue;
|
||||||
|
this.newValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 比较当前值和新值,如果不同则更新
|
||||||
|
*
|
||||||
|
* @param value 当前值
|
||||||
|
*/
|
||||||
|
public void compareAndUpdate(T value) {
|
||||||
|
compareAndUpdate(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 比较当前值和新值,如果不同则更新
|
||||||
|
*
|
||||||
|
* @param value 当前值
|
||||||
|
* @param callback 更新成功后的回调函数
|
||||||
|
*/
|
||||||
|
public void compareAndUpdate(T value, @Nullable Runnable callback) {
|
||||||
|
if (!this.newValue.equals(value)) {
|
||||||
|
update(value);
|
||||||
|
|
||||||
|
if (callback != null) {
|
||||||
|
callback.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset(T value) {
|
||||||
|
this.oldValue = value;
|
||||||
|
this.newValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T oldValue() {
|
||||||
|
return this.oldValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T newValue() {
|
||||||
|
return this.newValue;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue