Начинающий
- Статус
- Оффлайн
- Регистрация
- 24 Фев 2025
- Сообщения
- 3
- Реакции
- 1
- Выберите загрузчик игры
- Fabric
Первая тема, не срите пж
Сделал этот тх за 15 - 20 с чем то минут
SS:
Сделал этот тх за 15 - 20 с чем то минут
TargetHUD:
package idk.relake.hud.impl;
import idk.relake.hud.HudElement;
import idk.relake.themes.ThemeManager;
import idk.relake.ui.UIRenderContext;
import idk.relake.utilities.ColorUtility;
import idk.relake.utilities.RenderUtility;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.Identifier;
public final class TargetHUD extends HudElement {
private LivingEntity target;
private float lastHealth = 20f;
private float animatedHealth = 20f;
private float displayHealth = 20f;
private long lastHealthChangeTime = 0;
private float lastAbsorption = 0f;
private float animatedAbsorption = 0f;
private float displayAbsorption = 0f;
private long lastAbsorptionChangeTime = 0;
private float displayedHpNumber = 20f;
private float targetHpNumber = 20f;
private long lastHpNumberChange = 0;
private float displayedAbsorptionNumber = 0f;
private float targetAbsorptionNumber = 0f;
private long lastAbsorptionNumberChange = 0;
private String lastDisplayedName = "";
private boolean wasNameTruncated = false;
private long nameChangeTime = 0;
private float nameAlphaAnimation = 1f;
private boolean tookDamage = false;
private long damageTime = 0;
private final java.util.List<TearParticle> tears = new java.util.ArrayList<>();
private static class TearParticle {
float x, y;
float velocityY;
long spawnTime;
TearParticle(float x, float y) {
this.x = x;
this.y = y;
this.velocityY = 0.5f + (float) Math.random() * 0.5f;
this.spawnTime = System.currentTimeMillis();
}
void update() {
y += velocityY;
velocityY += 0.05f;
}
boolean isExpired() {
return System.currentTimeMillis() - spawnTime > 1000;
}
}
public TargetHUD() {
super("TargetHUD", 10, 30);
}
@Override
public void render(UIRenderContext ctx) {
MinecraftClient mc = MinecraftClient.getInstance();
if (mc.player == null) {
return;
}
this.target = mc.player;
if (this.target == null) {
return;
}
float width = 115f;
float height = 34f;
float headSize = 22f;
float padding = 6f;
this.width = width;
this.height = height;
int accent = ThemeManager.INSTANCE.getCurrentColor();
ctx.rectangles().add(
this.x, this.y, width, height,
RenderUtility.vectorFromSingle(6),
0xFF1A1D22, 0xFF3A3D42, 1);
float headX = this.x + padding;
float headY = this.y + (height - headSize) / 2f;
ctx.images().add(Identifier.of("relake", "images/head.png"),
headX, headY, headSize, headSize, -1);
long timeSinceDamage = System.currentTimeMillis() - damageTime;
if (tookDamage && timeSinceDamage < 500) {
float damageProgress = timeSinceDamage / 500f;
float c1 = 1.70158f;
float c3 = c1 + 1f;
float easedProgress = 1f + c3 * (float) Math.pow(damageProgress - 1, 3) + c1 * (float) Math.pow(damageProgress - 1, 2);
int redAlpha = (int) ((1f - easedProgress) * 100);
if (redAlpha > 0) {
int redOverlay = ColorUtility.withAlpha(0xFFFF0000, redAlpha);
ctx.rectangles().add(
headX, headY, headSize, headSize,
RenderUtility.vectorFromSingle(0f),
redOverlay);
}
}
String name = target.getName().getString();
float textStartX = headX + headSize + padding;
float nameY = this.y + 8f;
float hp = target.getHealth();
float absorption = 0f;
if (target instanceof PlayerEntity player) {
absorption = player.getAbsorptionAmount();
}
if (Math.abs(hp - targetHpNumber) > 0.1f) {
targetHpNumber = hp;
lastHpNumberChange = System.currentTimeMillis();
}
if (Math.abs(absorption - targetAbsorptionNumber) > 0.1f) {
targetAbsorptionNumber = absorption;
lastAbsorptionNumberChange = System.currentTimeMillis();
}
long hpTimeSinceChange = System.currentTimeMillis() - lastHpNumberChange;
float hpAnimDuration = 400f;
if (hpTimeSinceChange < hpAnimDuration) {
float progress = hpTimeSinceChange / hpAnimDuration;
float easedProgress = 1f - (float) Math.pow(1 - progress, 3);
displayedHpNumber = displayedHpNumber + (targetHpNumber - displayedHpNumber) * easedProgress;
} else {
displayedHpNumber = targetHpNumber;
}
long absTimeSinceChange = System.currentTimeMillis() - lastAbsorptionNumberChange;
float absAnimDuration = 400f;
if (absTimeSinceChange < absAnimDuration) {
float progress = absTimeSinceChange / absAnimDuration;
float easedProgress = 1f - (float) Math.pow(1 - progress, 3);
displayedAbsorptionNumber = displayedAbsorptionNumber + (targetAbsorptionNumber - displayedAbsorptionNumber) * easedProgress;
} else {
displayedAbsorptionNumber = targetAbsorptionNumber;
}
String hpMainText = String.valueOf((int) displayedHpNumber);
String hpAbsorptionText = "";
if (displayedAbsorptionNumber > 0.05f) {
if (displayedAbsorptionNumber % 1 < 0.1f) {
hpAbsorptionText = String.format(" + %d AB", (int) displayedAbsorptionNumber);
} else {
hpAbsorptionText = String.format(" + %.1f AB", displayedAbsorptionNumber);
}
}
String fullHpText = hpMainText + hpAbsorptionText;
float hpTextWidth = ctx.fontsMedium().getTextWidth(fullHpText, 8f);
float maxNameWidth = width - (headSize + padding * 3) - hpTextWidth - 5f;
String displayName = name;
boolean isNameTruncated = false;
if (ctx.fontsMedium().getTextWidth(name, 8f) > maxNameWidth) {
isNameTruncated = true;
while (ctx.fontsMedium().getTextWidth(displayName + "...", 8f) > maxNameWidth && displayName.length() > 0) {
displayName = displayName.substring(0, displayName.length() - 1);
}
displayName += "...";
}
if (!displayName.equals(lastDisplayedName)) {
lastDisplayedName = displayName;
nameChangeTime = System.currentTimeMillis();
}
long nameTimeSinceChange = System.currentTimeMillis() - nameChangeTime;
float nameAnimDuration = 300f;
if (nameTimeSinceChange < nameAnimDuration) {
float progress = nameTimeSinceChange / nameAnimDuration;
nameAlphaAnimation = 1f - (float) Math.pow(1 - progress, 3);
} else {
nameAlphaAnimation = 1f;
}
if (isNameTruncated) {
String mainPart = displayName.substring(0, displayName.length() - 3);
String dotsPart = "...";
ctx.fontsMedium().add(mainPart, textStartX, nameY, 8f, 0xFFFFFFFF);
float dotsX = textStartX + ctx.fontsMedium().getTextWidth(mainPart, 8f);
int dotsAlpha = (int) (nameAlphaAnimation * 255);
int dotsColor = (dotsAlpha << 24) | 0x00FFFFFF;
ctx.fontsMedium().add(dotsPart, dotsX, nameY, 8f, dotsColor);
} else {
ctx.fontsMedium().add(displayName, textStartX, nameY, 8f, 0xFFFFFFFF);
}
wasNameTruncated = isNameTruncated;
float hpX = this.x + width - padding - hpTextWidth;
int hpAlpha = 255;
if (hpTimeSinceChange < 100) {
float fadeProgress = hpTimeSinceChange / 100f;
hpAlpha = (int) (200 + fadeProgress * 55);
}
int hpColor = (hpAlpha << 24) | 0x00FFFFFF;
ctx.fontsMedium().add(hpMainText, hpX, nameY, 8f, hpColor);
if (!hpAbsorptionText.isEmpty()) {
float mainTextWidth = ctx.fontsMedium().getTextWidth(hpMainText, 8f);
float currentX = hpX + mainTextWidth;
int absBaseAlpha = 255;
if (absTimeSinceChange < 100) {
float fadeProgress = absTimeSinceChange / 100f;
absBaseAlpha = (int) (200 + fadeProgress * 55);
}
for (int glowLayer = 5; glowLayer >= 1; glowLayer--) {
int glowAlpha = (20 / glowLayer);
int glowColor = (glowAlpha << 24) | 0x00FFD700;
ctx.fontsMedium().add(hpAbsorptionText, currentX, nameY, 8f, glowColor);
}
int mainColor = (absBaseAlpha << 24) | 0x00FFD700;
ctx.fontsMedium().add(hpAbsorptionText, currentX, nameY, 8f, mainColor);
}
float maxHp = target.getMaxHealth();
float currentHp = hp;
if (currentHp < lastHealth - 0.5f) {
if (!tookDamage) {
tookDamage = true;
damageTime = System.currentTimeMillis();
int tearCount = 3 + (int) (Math.random() * 3);
for (int i = 0; i < tearCount; i++) {
float tearX = headX + headSize / 2f + (float) (Math.random() * 6 - 3);
float tearY = headY + headSize * 0.7f;
tears.add(new TearParticle(tearX, tearY));
}
}
} else if (currentHp >= lastHealth) {
tookDamage = false;
}
tears.removeIf(TearParticle::isExpired);
for (TearParticle tear : tears) {
tear.update();
float tearSize = 2f;
ctx.rectangles().add(
tear.x - tearSize / 2f,
tear.y - tearSize / 2f,
tearSize, tearSize,
RenderUtility.vectorFromSingle(tearSize / 2f),
0xFF87CEEB);
}
if (Math.abs(currentHp - lastHealth) > 0.1f) {
lastHealth = currentHp;
lastHealthChangeTime = System.currentTimeMillis();
}
long timeSinceChange = System.currentTimeMillis() - lastHealthChangeTime;
float animationDuration = 500f;
if (timeSinceChange < animationDuration) {
float progress = timeSinceChange / animationDuration;
float c1 = 1.70158f;
float c3 = c1 + 1f;
float easedProgress = 1f + c3 * (float) Math.pow(progress - 1, 3) + c1 * (float) Math.pow(progress - 1, 2);
animatedHealth = animatedHealth + (currentHp - animatedHealth) * easedProgress;
} else {
animatedHealth = currentHp;
}
displayHealth = displayHealth + (animatedHealth - displayHealth) * 0.15f;
float healthPercent = Math.min(1f, Math.max(0f, displayHealth / maxHp));
float barY = this.y + height - 13f;
float barHeight = 6f;
float barWidth = width - (headSize + padding * 3);
float barX = textStartX;
ctx.rectangles().add(
barX, barY, barWidth, barHeight,
RenderUtility.vectorFromSingle(2f),
0xFF1A1D22);
if (healthPercent > 0f) {
float pulseScale = 1f;
if (timeSinceChange < 200) {
float pulseProgress = timeSinceChange / 200f;
pulseScale = 1f + (1f - pulseProgress) * 0.15f;
}
float animatedBarHeight = barHeight * pulseScale;
float barOffsetY = (barHeight - animatedBarHeight) / 2f;
float barFilledWidth = barWidth * healthPercent;
for (int glowLayer = 5; glowLayer >= 1; glowLayer--) {
float glowSize = glowLayer * 1.5f;
int glowAlpha = 20 / glowLayer;
int glowColor = ColorUtility.withAlpha(0xFFFFFFFF, glowAlpha);
ctx.rectangles().add(
barX - glowSize / 2f,
barY + barOffsetY - glowSize / 2f,
barFilledWidth + glowSize,
animatedBarHeight + glowSize,
RenderUtility.vectorFromSingle(2f + glowSize / 2f),
glowColor);
}
ctx.rectangles().add(
barX, barY + barOffsetY, barFilledWidth, animatedBarHeight,
RenderUtility.vectorFromSingle(2f),
0xFFB0B0B0, 0xFFFFFFFF);
}
if (target instanceof PlayerEntity player) {
float absorptionAmount = player.getAbsorptionAmount();
if (absorptionAmount > 0f) {
if (Math.abs(absorptionAmount - lastAbsorption) > 0.1f) {
lastAbsorption = absorptionAmount;
lastAbsorptionChangeTime = System.currentTimeMillis();
}
long absorptionTimeSinceChange = System.currentTimeMillis() - lastAbsorptionChangeTime;
float absorptionAnimDuration = 500f;
if (absorptionTimeSinceChange < absorptionAnimDuration) {
float progress = absorptionTimeSinceChange / absorptionAnimDuration;
float c1 = 1.70158f;
float c3 = c1 + 1f;
float easedProgress = 1f + c3 * (float) Math.pow(progress - 1, 3) + c1 * (float) Math.pow(progress - 1, 2);
animatedAbsorption = animatedAbsorption + (absorptionAmount - animatedAbsorption) * easedProgress;
} else {
animatedAbsorption = absorptionAmount;
}
displayAbsorption = displayAbsorption + (animatedAbsorption - displayAbsorption) * 0.15f;
float absorptionPercent = Math.min(1f, displayAbsorption / 20f);
float absorptionPulseScale = 1f;
if (absorptionTimeSinceChange < 200) {
float pulseProgress = absorptionTimeSinceChange / 200f;
absorptionPulseScale = 1f + (1f - pulseProgress) * 0.15f;
}
float absorptionBarHeight = barHeight * absorptionPulseScale;
float absorptionBarOffsetY = (barHeight - absorptionBarHeight) / 2f;
float absorptionBarWidth = barWidth * absorptionPercent;
int absorptionColorFull = 0xFFFFD700;
int absorptionColorFade = 0x00FFD700;
float absorptionBarX = this.x + width - padding - absorptionBarWidth;
float absorptionBarY = barY;
for (int glowLayer = 3; glowLayer >= 1; glowLayer--) {
float glowSize = glowLayer * 1.5f;
int glowAlpha = 20 / glowLayer;
int glowColor = ColorUtility.withAlpha(absorptionColorFull, glowAlpha);
ctx.rectangles().add(
absorptionBarX - glowSize / 2f,
absorptionBarY + absorptionBarOffsetY - glowSize / 2f,
absorptionBarWidth + glowSize,
absorptionBarHeight + glowSize,
RenderUtility.vectorFromSingle(2f + glowSize / 2f),
glowColor);
}
ctx.rectangles().add(
absorptionBarX, absorptionBarY + absorptionBarOffsetY, absorptionBarWidth, absorptionBarHeight,
RenderUtility.vectorFromSingle(2f),
absorptionColorFade, absorptionColorFull);
}
}
}
public void setTarget(LivingEntity target) {
this.target = target;
}
}