Моя первая работа можете лого и бэкграунд под себя
Код:
package im.expensive.ui.mainmenu;
import com.mojang.blaze3d.matrix.MatrixStack;
import im.expensive.Expensive;
import im.expensive.utils.client.ClientUtil;
import im.expensive.utils.client.IMinecraft;
import im.expensive.utils.client.Vec2i;
import im.expensive.utils.math.MathUtil;
import im.expensive.utils.math.StopWatch;
import im.expensive.utils.render.ColorUtils;
import im.expensive.utils.render.DisplayUtils;
import im.expensive.utils.render.font.Fonts;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.MultiplayerScreen;
import net.minecraft.client.gui.screen.OptionsScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.WorldSelectionScreen;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import java.util.ArrayList;
import java.util.List;
public class MainScreen extends Screen implements IMinecraft {
private static final String VERSION_TEXT = "Версия - Alpha";
private static final String WELCOME_TEXT = "Приветствую в наш клиент";
private static final String SINGLE_PLAYER_TEXT = "Single Player";
private static final String MULTI_PLAYER_TEXT = "Multi Player";
private static final String SETTINGS_TEXT = "Settings";
private static final String EXIT_TEXT = "Exit";
public MainScreen() {
super(ITextComponent.getTextComponentOrEmpty(""));
}
private final ResourceLocation backmenu = new ResourceLocation("expensive/images/mainmenu/background.png");
private final ResourceLocation logo = new ResourceLocation("expensive/images/mainmenu/icon.png");
private final List<Button> buttons = new ArrayList<>();
private static final float BUTTON_WIDTH = 160f;
private static final float BUTTON_HEIGHT = 32f;
private static final float BUTTON_SPACING = 4f;
private float targetLogoY;
private float animatedLogoY;
private final StopWatch stopWatch = new StopWatch();
@Override
public void init(Minecraft minecraft, int width, int height) {
super.init(minecraft, width, height);
float centerX = width / 2f;
float centerY = height / 2f;
targetLogoY = centerY - 90f; // финальная позиция логотипа
animatedLogoY = -120f; // стартовая позиция (сверху)
buttons.clear();
float totalHeight = (BUTTON_HEIGHT * 4) + (BUTTON_SPACING * 3);
float startY = centerY - (totalHeight / 2f) + 40f;
float buttonX = centerX - BUTTON_WIDTH / 2f;
float y1 = startY;
buttons.add(new Button(buttonX, y1, BUTTON_WIDTH, BUTTON_HEIGHT, SINGLE_PLAYER_TEXT, () ->
mc.displayGuiScreen(new WorldSelectionScreen(this))
));
buttons.add(new Button(buttonX, y1 + BUTTON_HEIGHT + BUTTON_SPACING, BUTTON_WIDTH, BUTTON_HEIGHT, MULTI_PLAYER_TEXT, () ->
mc.displayGuiScreen(new MultiplayerScreen(this))
));
buttons.add(new Button(buttonX, y1 + (BUTTON_HEIGHT + BUTTON_SPACING) * 2, BUTTON_WIDTH, BUTTON_HEIGHT, SETTINGS_TEXT, () ->
mc.displayGuiScreen(new OptionsScreen(this, mc.gameSettings))
));
buttons.add(new Button(buttonX, y1 + (BUTTON_HEIGHT + BUTTON_SPACING) * 3, BUTTON_WIDTH, BUTTON_HEIGHT, EXIT_TEXT, () ->
mc.shutdown()
));
}
@Override
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
super.render(matrixStack, mouseX, mouseY, partialTicks);
if (stopWatch.isReached(100)) stopWatch.reset();
// фон
DisplayUtils.drawImage(backmenu, 0, 0, width, height, -1);
// анимация логотипа сверху вниз
animatedLogoY += (targetLogoY - animatedLogoY) * 0.06f;
float logoWidth = 80f;
float logoHeight = 70f;
DisplayUtils.drawImage(logo, width / 2f - logoWidth / 2f, animatedLogoY, logoWidth, logoHeight, -1);
// кнопки
drawButtons(matrixStack, mouseX, mouseY, partialTicks);
// версия и подпись
Fonts.montserrat.drawText(matrixStack, VERSION_TEXT, 10f, 10f,
ColorUtils.rgba(255, 255, 255, 140), 7.5F);
Fonts.montserrat.drawText(matrixStack, WELCOME_TEXT, 10f, height - 20f,
ColorUtils.rgba(255, 255, 255, 140), 7.5F);
// альт-менеджер
Expensive.getInstance().getAltWidget().render(matrixStack, mouseX, mouseY);
}
private void drawButtons(MatrixStack stack, int mX, int mY, float pt) {
buttons.forEach(b -> b.render(stack, mX, mY, pt));
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
Vec2i fixed = ClientUtil.getMouse((int) mouseX, (int) mouseY);
buttons.forEach(b -> b.click(fixed.getX(), fixed.getY(), button));
Expensive.getInstance().getAltWidget().click(fixed.getX(), fixed.getY(), button);
return super.mouseClicked(mouseX, mouseY, button);
}
// ================= Button Class =================
private class Button {
private final float x, targetY, width, height;
private final String text;
private final Runnable action;
private float animatedY;
private float glowAlpha = 0f;
public Button(float x, float targetY, float width, float height, String text, Runnable action) {
this.x = x;
this.targetY = targetY;
this.width = width;
this.height = height;
this.text = text;
this.action = action;
this.animatedY = Minecraft.getInstance().getMainWindow().getScaledHeight() + height;
}
public void render(MatrixStack stack, int mouseX, int mouseY, float pt) {
// движение к targetY
animatedY += (targetY - animatedY) * 0.08f;
boolean hovered = MathUtil.isHovered(mouseX, mouseY, x, animatedY, width, height);
// плавное свечение кнопки
if (hovered) glowAlpha += (1f - glowAlpha) * 0.1f;
else glowAlpha += (0f - glowAlpha) * 0.1f;
int baseColor = ColorUtils.rgba(0, 0, 0, 150);
DisplayUtils.drawRoundedRect(x, animatedY, width, height, 5, baseColor);
// мягкое свечение вокруг
int glow = (int)(glowAlpha * 120);
if (glow > 0) DisplayUtils.drawRoundedRect(x - 2, animatedY - 2, width + 4, height + 4, 7,
(glow << 24) | 0xFFFFFF);
int textColor = hovered ? ColorUtils.rgb(255, 255, 255) : ColorUtils.rgb(230, 230, 230);
Fonts.montserrat.drawCenteredText(stack, text, x + width / 2f, animatedY + height / 2f - 4f, textColor, 9f);
}
public void click(int mouseX, int mouseY, int button) {
if (MathUtil.isHovered(mouseX, mouseY, x, animatedY, width, height)) {
action.run();
}
}
}
}