Розыгрыш Premium и Уникальной юзергруппы на форуме! Перейти

Визуальная часть MainMenu ExosWare 1.21.4 fabric

Начинающий
Начинающий
Статус
Онлайн
Регистрация
21 Ноя 2024
Сообщения
67
Реакции
0
Выберите загрузчик игры
  1. Fabric
Первая тема
класс MainMenu
Код:
Expand Collapse Copy
package ru.levin.screens.mainmenu;

import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.option.OptionsScreen;
import net.minecraft.client.gui.screen.world.SelectWorldScreen;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import ru.levin.screens.altmanager.AltManager;
import ru.levin.util.color.ColorUtil;
import ru.levin.manager.fontManager.FontUtils;
import ru.levin.util.render.RenderUtil;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

@SuppressWarnings("All")
public class MainMenu extends Screen {

    private Button singleplayerButton;
    private Button multiplayerButton;
    private Button altmanagerButton;
    private CombinedButton optionsQuitButton;

    private final String title = "ExosWare";

    private final Color PRIMARY_COLOR = new Color(138, 43, 226);
    private final Color SECONDARY_COLOR = new Color(75, 0, 130);
    private final Color ACCENT_COLOR = new Color(255, 20, 147);
    private final Color BACKGROUND_COLOR = new Color(25, 25, 35, 240);

    private int shakeTime = 0;
    private float shakeOffsetY = 0f;
    private float backgroundOffset = 0f;
    private float cameraRotation = 0f;

    private List<Particle> particles = new ArrayList<>();
    private Random random = new Random();
    private long lastParticleTime = 0;

    private final Identifier BACKGROUND_TEXTURE = Identifier.of("exosware", "images/gui/background360.png");

    public MainMenu() {
        super(Text.literal("Custom Main Menu"));
    }

    @Override
    protected void init() {
        int buttonWidth = 160;
        int buttonHeight = 24;

        singleplayerButton = new Button("Singleplayer", 0, 0, buttonWidth, buttonHeight);
        multiplayerButton = new Button("Multiplayer", 0, 0, buttonWidth, buttonHeight);
        altmanagerButton = new Button("AltManager", 0, 0, buttonWidth, buttonHeight);
        optionsQuitButton = new CombinedButton(0, 0, buttonWidth, buttonHeight, "Options", "Quit");

        initializeParticles();
    }

    private void initializeParticles() {
        particles.clear();
        for (int i = 0; i < 25; i++) {
            particles.add(new Particle(
                random.nextFloat() * this.width,
                random.nextFloat() * this.height,
                random.nextFloat() * 2 - 1,
                random.nextFloat() * 2 - 1,
                random.nextInt(3)
            ));
        }
    }

    @Override
    public void render(DrawContext context, int mouseX, int mouseY, float delta) {
        renderBackground(context, delta);
        updateAndRenderParticles(context, delta);
        if (shakeTime > 0) {
            shakeTime--;
            shakeOffsetY = (float)(Math.sin(shakeTime * 0.5) * 3);
        } else {
            shakeOffsetY = 0f;
        }

        int titleSize = 48;
        int titleWidth = (int) FontUtils.gilroy[titleSize].getWidth(title);
        float titleX = (this.width - titleWidth) / 2f;
        float titleBaseY = this.height / 4f;
        float titleY = titleBaseY + shakeOffsetY;

        float time = (System.currentTimeMillis() % 4000L) / 1500f;
        int startColor = PRIMARY_COLOR.getRGB();
        int endColor = ACCENT_COLOR.getRGB();
        FontUtils.gilroy[titleSize].renderAnimatedGradientText(context.getMatrices(), title, titleX, titleY, startColor, endColor, time);

        float titleHeight = titleSize;

        int spacing = 6;
        int buttonWidth = 160;
        int buttonHeight = 24;

        float buttonsStartY = titleBaseY + titleHeight + spacing * 4;

        int centerX = this.width / 2 - buttonWidth / 2;

        singleplayerButton.x = centerX;
        singleplayerButton.y = (int)buttonsStartY;

        multiplayerButton.x = centerX;
        multiplayerButton.y = (int)(buttonsStartY + buttonHeight + spacing);

        altmanagerButton.x = centerX;
        altmanagerButton.y = (int)(buttonsStartY + 2 * (buttonHeight + spacing));

        optionsQuitButton.x = centerX;
        optionsQuitButton.y = (int)(buttonsStartY + 3 * (buttonHeight + spacing));
        optionsQuitButton.width = buttonWidth;

        singleplayerButton.render(context, mouseX, mouseY, delta);
        multiplayerButton.render(context, mouseX, mouseY, delta);
        altmanagerButton.render(context, mouseX, mouseY, delta);
        optionsQuitButton.render(context, mouseX, mouseY, delta);

        renderVersion(context);
    }

    private void renderBackground(DrawContext context, float delta) {
        backgroundOffset += delta * 0.01f;
        cameraRotation += delta * 0.005f;
        RenderUtil.drawRoundedRect(context.getMatrices(), 0, 0, this.width, this.height, 0, BACKGROUND_COLOR.getRGB());
        try {
            context.getMatrices().push();
            context.getMatrices().translate(this.width / 2f, this.height / 2f, 0);
            context.getMatrices().multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotation(cameraRotation));
            context.getMatrices().translate(-this.width / 2f, -this.height / 2f, 0);

            RenderUtil.drawTexture(context.getMatrices(), BACKGROUND_TEXTURE,
                0, 0, this.width, this.height, 0,
                ColorUtil.applyAlpha(Color.WHITE.getRGB(), 0.3f));

            context.getMatrices().pop();
        } catch (Exception e) {
        }
    }

    private void updateAndRenderParticles(DrawContext context, float delta) {
        long currentTime = System.currentTimeMillis();

        if (currentTime - lastParticleTime > 2000 && particles.size() < 30) {
            particles.add(new Particle(
                random.nextBoolean() ? -10 : this.width + 10,
                random.nextFloat() * this.height,
                random.nextFloat() * 2 - 1,
                random.nextFloat() * 2 - 1,
                random.nextInt(3)
            ));
            lastParticleTime = currentTime;
        }

        particles.removeIf(particle -> particle.update(delta) && particle.isOffScreen(this.width, this.height));

        for (Particle particle : particles) {
            particle.render(context);
        }
    }

    private void renderVersion(DrawContext context) {
        String version = "1.21.4";
        int fontSize = 14;
        int versionWidth = (int) FontUtils.gilroy[fontSize].getWidth(version);
        float versionX = this.width - versionWidth - 10;
        float versionY = this.height - 20;

        FontUtils.gilroy[fontSize].drawLeftAligned(context.getMatrices(), version, versionX, versionY,
            new Color(200, 200, 200, 150).getRGB());
    }

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {
        int titleSize = 40;
        int titleWidth = (int) FontUtils.sf_bold[titleSize].getWidth(title);
        float titleX = (this.width - titleWidth) / 2f;
        float titleY = this.height / 5f;

        if (mouseX >= titleX && mouseX <= titleX + titleWidth && mouseY >= titleY && mouseY <= titleY + titleSize) {
            shakeTime = 20;
            return true;
        }

        if (singleplayerButton.isHovered(mouseX, mouseY)) {
            this.client.setScreen(new SelectWorldScreen(this));
            return true;
        }
        if (multiplayerButton.isHovered(mouseX, mouseY)) {
            this.client.setScreen(new MultiplayerScreen(this));
            return true;
        }
        if (altmanagerButton.isHovered(mouseX, mouseY)) {
            this.client.setScreen(new AltManager(this));
            return true;
        }
        if (optionsQuitButton.isOptionHovered(mouseX, mouseY)) {
            this.client.setScreen(new OptionsScreen(this, client.options));
            return true;
        }
        if (optionsQuitButton.isQuitHovered(mouseX, mouseY)) {
            this.client.scheduleStop();
            return true;
        }

        return super.mouseClicked(mouseX, mouseY, button);
    }

    private class Particle {
        float x, y, vx, vy;
        int type;
        float life = 1.0f;
        float rotation = 0f;
        float scale = 1f;

        Particle(float x, float y, float vx, float vy, int type) {
            this.x = x;
            this.y = y;
            this.vx = vx;
            this.vy = vy;
            this.type = type;
        }

        boolean update(float delta) {
            x += vx * delta * 30;
            y += vy * delta * 30;
            rotation += delta * 0.5f;
            life -= delta * 0.001f;

            vy += Math.sin(System.currentTimeMillis() * 0.001f + x * 0.01f) * 0.01f;

            return life <= 0;
        }

        boolean isOffScreen(int screenWidth, int screenHeight) {
            return x < -20 || x > screenWidth + 20 || y < -20 || y > screenHeight + 20;
        }

        void render(DrawContext context) {
            String texturePath = switch (type) {
                case 0 -> "images/particles/snowflake.png";
                case 1 -> "images/particles/firefly.png";
                case 2 -> "images/particles/spark.png";
                default -> "images/particles/star.png";
            };

            try {
                context.getMatrices().push();
                context.getMatrices().translate(x, y, 0);
                context.getMatrices().multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotation(rotation));
                context.getMatrices().scale(scale, scale, 1);

                int alpha = (int)(life * 255);
                int color = (alpha << 24) | 0xFFFFFF;

                RenderUtil.drawTexture(context.getMatrices(),
                    Identifier.of("exosware", texturePath),
                    -8, -8, 16, 16, 4, color);

                context.getMatrices().pop();
            } catch (Exception e) {
                RenderUtil.drawCircle(context.getMatrices(), x, y, 3, ColorUtil.applyAlpha(Color.WHITE.getRGB(), life));
            }
        }
    }

    private class Button {
        final String name;
        int x, y, width, height;

        private float hoverAnim = 0f;
        private float scale = 1f;

        Button(String name, int x, int y, int width, int height) {
            this.name = name;
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }

        void render(DrawContext context, int mouseX, int mouseY, float delta) {
            boolean hovered = isHovered(mouseX, mouseY);

            float animSpeed = 0.06f;

            if (hovered) {
                hoverAnim = Math.min(1f, hoverAnim + animSpeed);
                scale = Math.min(1.05f, scale + animSpeed * 0.3f);
            } else {
                hoverAnim = Math.max(0f, hoverAnim - animSpeed);
                scale = Math.max(1f, scale - animSpeed * 0.3f);
            }

            int baseBgColor = new Color(20, 20, 30, 180).getRGB();
            int hoverBgColor = new Color(40, 40, 60, 220).getRGB();
            int bgColor = ColorUtil.blendColorsInt(baseBgColor, hoverBgColor, hoverAnim);

            int baseOutlineColor = new Color(PRIMARY_COLOR.getRed(), PRIMARY_COLOR.getGreen(), PRIMARY_COLOR.getBlue(), 100).getRGB();
            int hoverOutlineColor = new Color(ACCENT_COLOR.getRed(), ACCENT_COLOR.getGreen(), ACCENT_COLOR.getBlue(), 200).getRGB();
            int outlineColor = ColorUtil.blendColorsInt(baseOutlineColor, hoverOutlineColor, hoverAnim);

            if (hovered) {
                RenderUtil.drawBlur(context.getMatrices(), x - 5, y - 5, width + 10, height + 10, 8, 2f,
                    ColorUtil.applyAlpha(outlineColor, hoverAnim * 0.5f));
            }

            float textHeight = 18;
            float textY = y + (height - textHeight) / 2f + 3.5f;

            context.getMatrices().push();
            context.getMatrices().translate(x + width / 2f, y + height / 2f, 0);
            context.getMatrices().scale(scale, scale, 1);
            context.getMatrices().translate(-(x + width / 2f), -(y + height / 2f), 0);

            RenderUtil.drawRoundedRect(context.getMatrices(), x, y, width, height, 6, bgColor);
            RenderUtil.drawRoundedBorder(context.getMatrices(), x, y, width, height, 6, 2f, outlineColor);

            FontUtils.gilroy[18].centeredDraw(context.getMatrices(), name, x + width / 2f, textY,
                ColorUtil.blendColorsInt(Color.WHITE.getRGB(),
                    ColorUtil.blendColorsInt(PRIMARY_COLOR.getRGB(), ACCENT_COLOR.getRGB(), hoverAnim), hoverAnim * 0.3f));

            context.getMatrices().pop();
        }

        boolean isHovered(double mouseX, double mouseY) {
            return mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
        }
    }

    private class CombinedButton {
        int x, y, width, height;
        final String leftName, rightName;

        private float leftHoverAnim = 0f;
        private float rightHoverAnim = 0f;
        private float leftScale = 1f;
        private float rightScale = 1f;

        CombinedButton(int x, int y, int width, int height, String leftName, String rightName) {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
            this.leftName = leftName;
            this.rightName = rightName;
        }

        void render(DrawContext context, int mouseX, int mouseY, float delta) {
            int buttonGap = 2;
            int halfWidth = width / 2;
            int shrink = 3;

            boolean leftHovered = isOptionHovered(mouseX, mouseY);
            boolean rightHovered = isQuitHovered(mouseX, mouseY);

            float animSpeed = 0.04f;

            if (leftHovered) {
                leftHoverAnim = Math.min(1f, leftHoverAnim + animSpeed);
                leftScale = Math.min(1.02f, leftScale + animSpeed * 0.5f);
            } else {
                leftHoverAnim = Math.max(0f, leftHoverAnim - animSpeed);
                leftScale = Math.max(1f, leftScale - animSpeed * 0.5f);
            }

            if (rightHovered) {
                rightHoverAnim = Math.min(1f, rightHoverAnim + animSpeed);
                rightScale = Math.min(1.02f, rightScale + animSpeed * 0.5f);
            } else {
                rightHoverAnim = Math.max(0f, rightHoverAnim - animSpeed);
                rightScale = Math.max(1f, rightScale - animSpeed * 0.5f);
            }

            int baseBgColor = new Color(20, 20, 30, 180).getRGB();
            int hoverBgColor = new Color(40, 40, 60, 220).getRGB();
            int baseOutlineColor = new Color(PRIMARY_COLOR.getRed(), PRIMARY_COLOR.getGreen(), PRIMARY_COLOR.getBlue(), 100).getRGB();
            int hoverOutlineColor = new Color(ACCENT_COLOR.getRed(), ACCENT_COLOR.getGreen(), ACCENT_COLOR.getBlue(), 200).getRGB();

            int buttonWidth = halfWidth - shrink;

            int leftX = x + shrink / 2;
            int leftBg = ColorUtil.blendColorsInt(baseBgColor, hoverBgColor, leftHoverAnim);
            int leftOutline = ColorUtil.blendColorsInt(baseOutlineColor, hoverOutlineColor, leftHoverAnim);

            if (leftHovered) {
                RenderUtil.drawBlur(context.getMatrices(), leftX - 3, y - 3, buttonWidth + 6, height + 6, 6, 1.5f,
                    ColorUtil.applyAlpha(leftOutline, leftHoverAnim * 0.4f));
            }

            context.getMatrices().push();
            context.getMatrices().translate(leftX + buttonWidth / 2f, y + height / 2f, 0);
            context.getMatrices().scale(leftScale, leftScale, 1);
            context.getMatrices().translate(-(leftX + buttonWidth / 2f), -(y + height / 2f), 0);
            RenderUtil.drawRoundedRect(context.getMatrices(), leftX, y, buttonWidth, height, 6, leftBg);
            RenderUtil.drawRoundedBorder(context.getMatrices(), leftX, y, buttonWidth, height, 6, 2f, leftOutline);
            FontUtils.gilroy[18].centeredDraw(context.getMatrices(), leftName, leftX + buttonWidth / 2f, y + (height - 9) / 2.2f,
                ColorUtil.blendColorsInt(Color.WHITE.getRGB(),
                    ColorUtil.blendColorsInt(PRIMARY_COLOR.getRGB(), ACCENT_COLOR.getRGB(), leftHoverAnim), leftHoverAnim * 0.3f));
            context.getMatrices().pop();

            int rightX = x + halfWidth + shrink / 2;
            int rightBg = ColorUtil.blendColorsInt(baseBgColor, hoverBgColor, rightHoverAnim);
            int rightOutline = ColorUtil.blendColorsInt(baseOutlineColor, hoverOutlineColor, rightHoverAnim);

            if (rightHovered) {
                RenderUtil.drawBlur(context.getMatrices(), rightX - 3, y - 3, buttonWidth + 6, height + 6, 6, 1.5f,
                    ColorUtil.applyAlpha(rightOutline, rightHoverAnim * 0.4f));
            }

            context.getMatrices().push();
            context.getMatrices().translate(rightX + buttonWidth / 2f, y + height / 2f, 0);
            context.getMatrices().scale(rightScale, rightScale, 1);
            context.getMatrices().translate(-(rightX + buttonWidth / 2f), -(y + height / 2f), 0);
            RenderUtil.drawRoundedRect(context.getMatrices(), rightX, y, buttonWidth, height, 6, rightBg);
            RenderUtil.drawRoundedBorder(context.getMatrices(), rightX, y, buttonWidth, height, 6, 2f, rightOutline);
            FontUtils.gilroy[18].centeredDraw(context.getMatrices(), rightName, rightX + buttonWidth / 2f, y + (height - 9) / 2.2f,
                ColorUtil.blendColorsInt(Color.WHITE.getRGB(),
                    ColorUtil.blendColorsInt(PRIMARY_COLOR.getRGB(), ACCENT_COLOR.getRGB(), rightHoverAnim), rightHoverAnim * 0.3f));
            context.getMatrices().pop();
        }

        boolean isOptionHovered(double mouseX, double mouseY) {
            return mouseX >= x && mouseX < x + width / 2 && mouseY >= y && mouseY <= y + height;
        }

        boolean isQuitHovered(double mouseX, double mouseY) {
            return mouseX >= x + width / 2 && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
        }
    }

    @Override
    public boolean shouldCloseOnEsc() {
        return false;
    }
}
 

Вложения

  • image.png
    image.png
    650.5 KB · Просмотры: 292
Первая тема
класс MainMenu
Код:
Expand Collapse Copy
package ru.levin.screens.mainmenu;

import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.option.OptionsScreen;
import net.minecraft.client.gui.screen.world.SelectWorldScreen;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import ru.levin.screens.altmanager.AltManager;
import ru.levin.util.color.ColorUtil;
import ru.levin.manager.fontManager.FontUtils;
import ru.levin.util.render.RenderUtil;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

@SuppressWarnings("All")
public class MainMenu extends Screen {

    private Button singleplayerButton;
    private Button multiplayerButton;
    private Button altmanagerButton;
    private CombinedButton optionsQuitButton;

    private final String title = "ExosWare";

    private final Color PRIMARY_COLOR = new Color(138, 43, 226);
    private final Color SECONDARY_COLOR = new Color(75, 0, 130);
    private final Color ACCENT_COLOR = new Color(255, 20, 147);
    private final Color BACKGROUND_COLOR = new Color(25, 25, 35, 240);

    private int shakeTime = 0;
    private float shakeOffsetY = 0f;
    private float backgroundOffset = 0f;
    private float cameraRotation = 0f;

    private List<Particle> particles = new ArrayList<>();
    private Random random = new Random();
    private long lastParticleTime = 0;

    private final Identifier BACKGROUND_TEXTURE = Identifier.of("exosware", "images/gui/background360.png");

    public MainMenu() {
        super(Text.literal("Custom Main Menu"));
    }

    @Override
    protected void init() {
        int buttonWidth = 160;
        int buttonHeight = 24;

        singleplayerButton = new Button("Singleplayer", 0, 0, buttonWidth, buttonHeight);
        multiplayerButton = new Button("Multiplayer", 0, 0, buttonWidth, buttonHeight);
        altmanagerButton = new Button("AltManager", 0, 0, buttonWidth, buttonHeight);
        optionsQuitButton = new CombinedButton(0, 0, buttonWidth, buttonHeight, "Options", "Quit");

        initializeParticles();
    }

    private void initializeParticles() {
        particles.clear();
        for (int i = 0; i < 25; i++) {
            particles.add(new Particle(
                random.nextFloat() * this.width,
                random.nextFloat() * this.height,
                random.nextFloat() * 2 - 1,
                random.nextFloat() * 2 - 1,
                random.nextInt(3)
            ));
        }
    }

    @Override
    public void render(DrawContext context, int mouseX, int mouseY, float delta) {
        renderBackground(context, delta);
        updateAndRenderParticles(context, delta);
        if (shakeTime > 0) {
            shakeTime--;
            shakeOffsetY = (float)(Math.sin(shakeTime * 0.5) * 3);
        } else {
            shakeOffsetY = 0f;
        }

        int titleSize = 48;
        int titleWidth = (int) FontUtils.gilroy[titleSize].getWidth(title);
        float titleX = (this.width - titleWidth) / 2f;
        float titleBaseY = this.height / 4f;
        float titleY = titleBaseY + shakeOffsetY;

        float time = (System.currentTimeMillis() % 4000L) / 1500f;
        int startColor = PRIMARY_COLOR.getRGB();
        int endColor = ACCENT_COLOR.getRGB();
        FontUtils.gilroy[titleSize].renderAnimatedGradientText(context.getMatrices(), title, titleX, titleY, startColor, endColor, time);

        float titleHeight = titleSize;

        int spacing = 6;
        int buttonWidth = 160;
        int buttonHeight = 24;

        float buttonsStartY = titleBaseY + titleHeight + spacing * 4;

        int centerX = this.width / 2 - buttonWidth / 2;

        singleplayerButton.x = centerX;
        singleplayerButton.y = (int)buttonsStartY;

        multiplayerButton.x = centerX;
        multiplayerButton.y = (int)(buttonsStartY + buttonHeight + spacing);

        altmanagerButton.x = centerX;
        altmanagerButton.y = (int)(buttonsStartY + 2 * (buttonHeight + spacing));

        optionsQuitButton.x = centerX;
        optionsQuitButton.y = (int)(buttonsStartY + 3 * (buttonHeight + spacing));
        optionsQuitButton.width = buttonWidth;

        singleplayerButton.render(context, mouseX, mouseY, delta);
        multiplayerButton.render(context, mouseX, mouseY, delta);
        altmanagerButton.render(context, mouseX, mouseY, delta);
        optionsQuitButton.render(context, mouseX, mouseY, delta);

        renderVersion(context);
    }

    private void renderBackground(DrawContext context, float delta) {
        backgroundOffset += delta * 0.01f;
        cameraRotation += delta * 0.005f;
        RenderUtil.drawRoundedRect(context.getMatrices(), 0, 0, this.width, this.height, 0, BACKGROUND_COLOR.getRGB());
        try {
            context.getMatrices().push();
            context.getMatrices().translate(this.width / 2f, this.height / 2f, 0);
            context.getMatrices().multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotation(cameraRotation));
            context.getMatrices().translate(-this.width / 2f, -this.height / 2f, 0);

            RenderUtil.drawTexture(context.getMatrices(), BACKGROUND_TEXTURE,
                0, 0, this.width, this.height, 0,
                ColorUtil.applyAlpha(Color.WHITE.getRGB(), 0.3f));

            context.getMatrices().pop();
        } catch (Exception e) {
        }
    }

    private void updateAndRenderParticles(DrawContext context, float delta) {
        long currentTime = System.currentTimeMillis();

        if (currentTime - lastParticleTime > 2000 && particles.size() < 30) {
            particles.add(new Particle(
                random.nextBoolean() ? -10 : this.width + 10,
                random.nextFloat() * this.height,
                random.nextFloat() * 2 - 1,
                random.nextFloat() * 2 - 1,
                random.nextInt(3)
            ));
            lastParticleTime = currentTime;
        }

        particles.removeIf(particle -> particle.update(delta) && particle.isOffScreen(this.width, this.height));

        for (Particle particle : particles) {
            particle.render(context);
        }
    }

    private void renderVersion(DrawContext context) {
        String version = "1.21.4";
        int fontSize = 14;
        int versionWidth = (int) FontUtils.gilroy[fontSize].getWidth(version);
        float versionX = this.width - versionWidth - 10;
        float versionY = this.height - 20;

        FontUtils.gilroy[fontSize].drawLeftAligned(context.getMatrices(), version, versionX, versionY,
            new Color(200, 200, 200, 150).getRGB());
    }

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {
        int titleSize = 40;
        int titleWidth = (int) FontUtils.sf_bold[titleSize].getWidth(title);
        float titleX = (this.width - titleWidth) / 2f;
        float titleY = this.height / 5f;

        if (mouseX >= titleX && mouseX <= titleX + titleWidth && mouseY >= titleY && mouseY <= titleY + titleSize) {
            shakeTime = 20;
            return true;
        }

        if (singleplayerButton.isHovered(mouseX, mouseY)) {
            this.client.setScreen(new SelectWorldScreen(this));
            return true;
        }
        if (multiplayerButton.isHovered(mouseX, mouseY)) {
            this.client.setScreen(new MultiplayerScreen(this));
            return true;
        }
        if (altmanagerButton.isHovered(mouseX, mouseY)) {
            this.client.setScreen(new AltManager(this));
            return true;
        }
        if (optionsQuitButton.isOptionHovered(mouseX, mouseY)) {
            this.client.setScreen(new OptionsScreen(this, client.options));
            return true;
        }
        if (optionsQuitButton.isQuitHovered(mouseX, mouseY)) {
            this.client.scheduleStop();
            return true;
        }

        return super.mouseClicked(mouseX, mouseY, button);
    }

    private class Particle {
        float x, y, vx, vy;
        int type;
        float life = 1.0f;
        float rotation = 0f;
        float scale = 1f;

        Particle(float x, float y, float vx, float vy, int type) {
            this.x = x;
            this.y = y;
            this.vx = vx;
            this.vy = vy;
            this.type = type;
        }

        boolean update(float delta) {
            x += vx * delta * 30;
            y += vy * delta * 30;
            rotation += delta * 0.5f;
            life -= delta * 0.001f;

            vy += Math.sin(System.currentTimeMillis() * 0.001f + x * 0.01f) * 0.01f;

            return life <= 0;
        }

        boolean isOffScreen(int screenWidth, int screenHeight) {
            return x < -20 || x > screenWidth + 20 || y < -20 || y > screenHeight + 20;
        }

        void render(DrawContext context) {
            String texturePath = switch (type) {
                case 0 -> "images/particles/snowflake.png";
                case 1 -> "images/particles/firefly.png";
                case 2 -> "images/particles/spark.png";
                default -> "images/particles/star.png";
            };

            try {
                context.getMatrices().push();
                context.getMatrices().translate(x, y, 0);
                context.getMatrices().multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotation(rotation));
                context.getMatrices().scale(scale, scale, 1);

                int alpha = (int)(life * 255);
                int color = (alpha << 24) | 0xFFFFFF;

                RenderUtil.drawTexture(context.getMatrices(),
                    Identifier.of("exosware", texturePath),
                    -8, -8, 16, 16, 4, color);

                context.getMatrices().pop();
            } catch (Exception e) {
                RenderUtil.drawCircle(context.getMatrices(), x, y, 3, ColorUtil.applyAlpha(Color.WHITE.getRGB(), life));
            }
        }
    }

    private class Button {
        final String name;
        int x, y, width, height;

        private float hoverAnim = 0f;
        private float scale = 1f;

        Button(String name, int x, int y, int width, int height) {
            this.name = name;
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }

        void render(DrawContext context, int mouseX, int mouseY, float delta) {
            boolean hovered = isHovered(mouseX, mouseY);

            float animSpeed = 0.06f;

            if (hovered) {
                hoverAnim = Math.min(1f, hoverAnim + animSpeed);
                scale = Math.min(1.05f, scale + animSpeed * 0.3f);
            } else {
                hoverAnim = Math.max(0f, hoverAnim - animSpeed);
                scale = Math.max(1f, scale - animSpeed * 0.3f);
            }

            int baseBgColor = new Color(20, 20, 30, 180).getRGB();
            int hoverBgColor = new Color(40, 40, 60, 220).getRGB();
            int bgColor = ColorUtil.blendColorsInt(baseBgColor, hoverBgColor, hoverAnim);

            int baseOutlineColor = new Color(PRIMARY_COLOR.getRed(), PRIMARY_COLOR.getGreen(), PRIMARY_COLOR.getBlue(), 100).getRGB();
            int hoverOutlineColor = new Color(ACCENT_COLOR.getRed(), ACCENT_COLOR.getGreen(), ACCENT_COLOR.getBlue(), 200).getRGB();
            int outlineColor = ColorUtil.blendColorsInt(baseOutlineColor, hoverOutlineColor, hoverAnim);

            if (hovered) {
                RenderUtil.drawBlur(context.getMatrices(), x - 5, y - 5, width + 10, height + 10, 8, 2f,
                    ColorUtil.applyAlpha(outlineColor, hoverAnim * 0.5f));
            }

            float textHeight = 18;
            float textY = y + (height - textHeight) / 2f + 3.5f;

            context.getMatrices().push();
            context.getMatrices().translate(x + width / 2f, y + height / 2f, 0);
            context.getMatrices().scale(scale, scale, 1);
            context.getMatrices().translate(-(x + width / 2f), -(y + height / 2f), 0);

            RenderUtil.drawRoundedRect(context.getMatrices(), x, y, width, height, 6, bgColor);
            RenderUtil.drawRoundedBorder(context.getMatrices(), x, y, width, height, 6, 2f, outlineColor);

            FontUtils.gilroy[18].centeredDraw(context.getMatrices(), name, x + width / 2f, textY,
                ColorUtil.blendColorsInt(Color.WHITE.getRGB(),
                    ColorUtil.blendColorsInt(PRIMARY_COLOR.getRGB(), ACCENT_COLOR.getRGB(), hoverAnim), hoverAnim * 0.3f));

            context.getMatrices().pop();
        }

        boolean isHovered(double mouseX, double mouseY) {
            return mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
        }
    }

    private class CombinedButton {
        int x, y, width, height;
        final String leftName, rightName;

        private float leftHoverAnim = 0f;
        private float rightHoverAnim = 0f;
        private float leftScale = 1f;
        private float rightScale = 1f;

        CombinedButton(int x, int y, int width, int height, String leftName, String rightName) {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
            this.leftName = leftName;
            this.rightName = rightName;
        }

        void render(DrawContext context, int mouseX, int mouseY, float delta) {
            int buttonGap = 2;
            int halfWidth = width / 2;
            int shrink = 3;

            boolean leftHovered = isOptionHovered(mouseX, mouseY);
            boolean rightHovered = isQuitHovered(mouseX, mouseY);

            float animSpeed = 0.04f;

            if (leftHovered) {
                leftHoverAnim = Math.min(1f, leftHoverAnim + animSpeed);
                leftScale = Math.min(1.02f, leftScale + animSpeed * 0.5f);
            } else {
                leftHoverAnim = Math.max(0f, leftHoverAnim - animSpeed);
                leftScale = Math.max(1f, leftScale - animSpeed * 0.5f);
            }

            if (rightHovered) {
                rightHoverAnim = Math.min(1f, rightHoverAnim + animSpeed);
                rightScale = Math.min(1.02f, rightScale + animSpeed * 0.5f);
            } else {
                rightHoverAnim = Math.max(0f, rightHoverAnim - animSpeed);
                rightScale = Math.max(1f, rightScale - animSpeed * 0.5f);
            }

            int baseBgColor = new Color(20, 20, 30, 180).getRGB();
            int hoverBgColor = new Color(40, 40, 60, 220).getRGB();
            int baseOutlineColor = new Color(PRIMARY_COLOR.getRed(), PRIMARY_COLOR.getGreen(), PRIMARY_COLOR.getBlue(), 100).getRGB();
            int hoverOutlineColor = new Color(ACCENT_COLOR.getRed(), ACCENT_COLOR.getGreen(), ACCENT_COLOR.getBlue(), 200).getRGB();

            int buttonWidth = halfWidth - shrink;

            int leftX = x + shrink / 2;
            int leftBg = ColorUtil.blendColorsInt(baseBgColor, hoverBgColor, leftHoverAnim);
            int leftOutline = ColorUtil.blendColorsInt(baseOutlineColor, hoverOutlineColor, leftHoverAnim);

            if (leftHovered) {
                RenderUtil.drawBlur(context.getMatrices(), leftX - 3, y - 3, buttonWidth + 6, height + 6, 6, 1.5f,
                    ColorUtil.applyAlpha(leftOutline, leftHoverAnim * 0.4f));
            }

            context.getMatrices().push();
            context.getMatrices().translate(leftX + buttonWidth / 2f, y + height / 2f, 0);
            context.getMatrices().scale(leftScale, leftScale, 1);
            context.getMatrices().translate(-(leftX + buttonWidth / 2f), -(y + height / 2f), 0);
            RenderUtil.drawRoundedRect(context.getMatrices(), leftX, y, buttonWidth, height, 6, leftBg);
            RenderUtil.drawRoundedBorder(context.getMatrices(), leftX, y, buttonWidth, height, 6, 2f, leftOutline);
            FontUtils.gilroy[18].centeredDraw(context.getMatrices(), leftName, leftX + buttonWidth / 2f, y + (height - 9) / 2.2f,
                ColorUtil.blendColorsInt(Color.WHITE.getRGB(),
                    ColorUtil.blendColorsInt(PRIMARY_COLOR.getRGB(), ACCENT_COLOR.getRGB(), leftHoverAnim), leftHoverAnim * 0.3f));
            context.getMatrices().pop();

            int rightX = x + halfWidth + shrink / 2;
            int rightBg = ColorUtil.blendColorsInt(baseBgColor, hoverBgColor, rightHoverAnim);
            int rightOutline = ColorUtil.blendColorsInt(baseOutlineColor, hoverOutlineColor, rightHoverAnim);

            if (rightHovered) {
                RenderUtil.drawBlur(context.getMatrices(), rightX - 3, y - 3, buttonWidth + 6, height + 6, 6, 1.5f,
                    ColorUtil.applyAlpha(rightOutline, rightHoverAnim * 0.4f));
            }

            context.getMatrices().push();
            context.getMatrices().translate(rightX + buttonWidth / 2f, y + height / 2f, 0);
            context.getMatrices().scale(rightScale, rightScale, 1);
            context.getMatrices().translate(-(rightX + buttonWidth / 2f), -(y + height / 2f), 0);
            RenderUtil.drawRoundedRect(context.getMatrices(), rightX, y, buttonWidth, height, 6, rightBg);
            RenderUtil.drawRoundedBorder(context.getMatrices(), rightX, y, buttonWidth, height, 6, 2f, rightOutline);
            FontUtils.gilroy[18].centeredDraw(context.getMatrices(), rightName, rightX + buttonWidth / 2f, y + (height - 9) / 2.2f,
                ColorUtil.blendColorsInt(Color.WHITE.getRGB(),
                    ColorUtil.blendColorsInt(PRIMARY_COLOR.getRGB(), ACCENT_COLOR.getRGB(), rightHoverAnim), rightHoverAnim * 0.3f));
            context.getMatrices().pop();
        }

        boolean isOptionHovered(double mouseX, double mouseY) {
            return mouseX >= x && mouseX < x + width / 2 && mouseY >= y && mouseY <= y + height;
        }

        boolean isQuitHovered(double mouseX, double mouseY) {
            return mouseX >= x + width / 2 && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
        }
    }

    @Override
    public boolean shouldCloseOnEsc() {
        return false;
    }
}
не самый лучший и не самый худший если сделать норм тени то будет норм
 
зачем брать картинку с рокстара :coldsideRage:
в ассестах лежит
Первая тема
класс MainMenu
Код:
Expand Collapse Copy
package ru.levin.screens.mainmenu;

import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.option.OptionsScreen;
import net.minecraft.client.gui.screen.world.SelectWorldScreen;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import ru.levin.screens.altmanager.AltManager;
import ru.levin.util.color.ColorUtil;
import ru.levin.manager.fontManager.FontUtils;
import ru.levin.util.render.RenderUtil;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

@SuppressWarnings("All")
public class MainMenu extends Screen {

    private Button singleplayerButton;
    private Button multiplayerButton;
    private Button altmanagerButton;
    private CombinedButton optionsQuitButton;

    private final String title = "ExosWare";

    private final Color PRIMARY_COLOR = new Color(138, 43, 226);
    private final Color SECONDARY_COLOR = new Color(75, 0, 130);
    private final Color ACCENT_COLOR = new Color(255, 20, 147);
    private final Color BACKGROUND_COLOR = new Color(25, 25, 35, 240);

    private int shakeTime = 0;
    private float shakeOffsetY = 0f;
    private float backgroundOffset = 0f;
    private float cameraRotation = 0f;

    private List<Particle> particles = new ArrayList<>();
    private Random random = new Random();
    private long lastParticleTime = 0;

    private final Identifier BACKGROUND_TEXTURE = Identifier.of("exosware", "images/gui/background360.png");

    public MainMenu() {
        super(Text.literal("Custom Main Menu"));
    }

    @Override
    protected void init() {
        int buttonWidth = 160;
        int buttonHeight = 24;

        singleplayerButton = new Button("Singleplayer", 0, 0, buttonWidth, buttonHeight);
        multiplayerButton = new Button("Multiplayer", 0, 0, buttonWidth, buttonHeight);
        altmanagerButton = new Button("AltManager", 0, 0, buttonWidth, buttonHeight);
        optionsQuitButton = new CombinedButton(0, 0, buttonWidth, buttonHeight, "Options", "Quit");

        initializeParticles();
    }

    private void initializeParticles() {
        particles.clear();
        for (int i = 0; i < 25; i++) {
            particles.add(new Particle(
                random.nextFloat() * this.width,
                random.nextFloat() * this.height,
                random.nextFloat() * 2 - 1,
                random.nextFloat() * 2 - 1,
                random.nextInt(3)
            ));
        }
    }

    @Override
    public void render(DrawContext context, int mouseX, int mouseY, float delta) {
        renderBackground(context, delta);
        updateAndRenderParticles(context, delta);
        if (shakeTime > 0) {
            shakeTime--;
            shakeOffsetY = (float)(Math.sin(shakeTime * 0.5) * 3);
        } else {
            shakeOffsetY = 0f;
        }

        int titleSize = 48;
        int titleWidth = (int) FontUtils.gilroy[titleSize].getWidth(title);
        float titleX = (this.width - titleWidth) / 2f;
        float titleBaseY = this.height / 4f;
        float titleY = titleBaseY + shakeOffsetY;

        float time = (System.currentTimeMillis() % 4000L) / 1500f;
        int startColor = PRIMARY_COLOR.getRGB();
        int endColor = ACCENT_COLOR.getRGB();
        FontUtils.gilroy[titleSize].renderAnimatedGradientText(context.getMatrices(), title, titleX, titleY, startColor, endColor, time);

        float titleHeight = titleSize;

        int spacing = 6;
        int buttonWidth = 160;
        int buttonHeight = 24;

        float buttonsStartY = titleBaseY + titleHeight + spacing * 4;

        int centerX = this.width / 2 - buttonWidth / 2;

        singleplayerButton.x = centerX;
        singleplayerButton.y = (int)buttonsStartY;

        multiplayerButton.x = centerX;
        multiplayerButton.y = (int)(buttonsStartY + buttonHeight + spacing);

        altmanagerButton.x = centerX;
        altmanagerButton.y = (int)(buttonsStartY + 2 * (buttonHeight + spacing));

        optionsQuitButton.x = centerX;
        optionsQuitButton.y = (int)(buttonsStartY + 3 * (buttonHeight + spacing));
        optionsQuitButton.width = buttonWidth;

        singleplayerButton.render(context, mouseX, mouseY, delta);
        multiplayerButton.render(context, mouseX, mouseY, delta);
        altmanagerButton.render(context, mouseX, mouseY, delta);
        optionsQuitButton.render(context, mouseX, mouseY, delta);

        renderVersion(context);
    }

    private void renderBackground(DrawContext context, float delta) {
        backgroundOffset += delta * 0.01f;
        cameraRotation += delta * 0.005f;
        RenderUtil.drawRoundedRect(context.getMatrices(), 0, 0, this.width, this.height, 0, BACKGROUND_COLOR.getRGB());
        try {
            context.getMatrices().push();
            context.getMatrices().translate(this.width / 2f, this.height / 2f, 0);
            context.getMatrices().multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotation(cameraRotation));
            context.getMatrices().translate(-this.width / 2f, -this.height / 2f, 0);

            RenderUtil.drawTexture(context.getMatrices(), BACKGROUND_TEXTURE,
                0, 0, this.width, this.height, 0,
                ColorUtil.applyAlpha(Color.WHITE.getRGB(), 0.3f));

            context.getMatrices().pop();
        } catch (Exception e) {
        }
    }

    private void updateAndRenderParticles(DrawContext context, float delta) {
        long currentTime = System.currentTimeMillis();

        if (currentTime - lastParticleTime > 2000 && particles.size() < 30) {
            particles.add(new Particle(
                random.nextBoolean() ? -10 : this.width + 10,
                random.nextFloat() * this.height,
                random.nextFloat() * 2 - 1,
                random.nextFloat() * 2 - 1,
                random.nextInt(3)
            ));
            lastParticleTime = currentTime;
        }

        particles.removeIf(particle -> particle.update(delta) && particle.isOffScreen(this.width, this.height));

        for (Particle particle : particles) {
            particle.render(context);
        }
    }

    private void renderVersion(DrawContext context) {
        String version = "1.21.4";
        int fontSize = 14;
        int versionWidth = (int) FontUtils.gilroy[fontSize].getWidth(version);
        float versionX = this.width - versionWidth - 10;
        float versionY = this.height - 20;

        FontUtils.gilroy[fontSize].drawLeftAligned(context.getMatrices(), version, versionX, versionY,
            new Color(200, 200, 200, 150).getRGB());
    }

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {
        int titleSize = 40;
        int titleWidth = (int) FontUtils.sf_bold[titleSize].getWidth(title);
        float titleX = (this.width - titleWidth) / 2f;
        float titleY = this.height / 5f;

        if (mouseX >= titleX && mouseX <= titleX + titleWidth && mouseY >= titleY && mouseY <= titleY + titleSize) {
            shakeTime = 20;
            return true;
        }

        if (singleplayerButton.isHovered(mouseX, mouseY)) {
            this.client.setScreen(new SelectWorldScreen(this));
            return true;
        }
        if (multiplayerButton.isHovered(mouseX, mouseY)) {
            this.client.setScreen(new MultiplayerScreen(this));
            return true;
        }
        if (altmanagerButton.isHovered(mouseX, mouseY)) {
            this.client.setScreen(new AltManager(this));
            return true;
        }
        if (optionsQuitButton.isOptionHovered(mouseX, mouseY)) {
            this.client.setScreen(new OptionsScreen(this, client.options));
            return true;
        }
        if (optionsQuitButton.isQuitHovered(mouseX, mouseY)) {
            this.client.scheduleStop();
            return true;
        }

        return super.mouseClicked(mouseX, mouseY, button);
    }

    private class Particle {
        float x, y, vx, vy;
        int type;
        float life = 1.0f;
        float rotation = 0f;
        float scale = 1f;

        Particle(float x, float y, float vx, float vy, int type) {
            this.x = x;
            this.y = y;
            this.vx = vx;
            this.vy = vy;
            this.type = type;
        }

        boolean update(float delta) {
            x += vx * delta * 30;
            y += vy * delta * 30;
            rotation += delta * 0.5f;
            life -= delta * 0.001f;

            vy += Math.sin(System.currentTimeMillis() * 0.001f + x * 0.01f) * 0.01f;

            return life <= 0;
        }

        boolean isOffScreen(int screenWidth, int screenHeight) {
            return x < -20 || x > screenWidth + 20 || y < -20 || y > screenHeight + 20;
        }

        void render(DrawContext context) {
            String texturePath = switch (type) {
                case 0 -> "images/particles/snowflake.png";
                case 1 -> "images/particles/firefly.png";
                case 2 -> "images/particles/spark.png";
                default -> "images/particles/star.png";
            };

            try {
                context.getMatrices().push();
                context.getMatrices().translate(x, y, 0);
                context.getMatrices().multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotation(rotation));
                context.getMatrices().scale(scale, scale, 1);

                int alpha = (int)(life * 255);
                int color = (alpha << 24) | 0xFFFFFF;

                RenderUtil.drawTexture(context.getMatrices(),
                    Identifier.of("exosware", texturePath),
                    -8, -8, 16, 16, 4, color);

                context.getMatrices().pop();
            } catch (Exception e) {
                RenderUtil.drawCircle(context.getMatrices(), x, y, 3, ColorUtil.applyAlpha(Color.WHITE.getRGB(), life));
            }
        }
    }

    private class Button {
        final String name;
        int x, y, width, height;

        private float hoverAnim = 0f;
        private float scale = 1f;

        Button(String name, int x, int y, int width, int height) {
            this.name = name;
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }

        void render(DrawContext context, int mouseX, int mouseY, float delta) {
            boolean hovered = isHovered(mouseX, mouseY);

            float animSpeed = 0.06f;

            if (hovered) {
                hoverAnim = Math.min(1f, hoverAnim + animSpeed);
                scale = Math.min(1.05f, scale + animSpeed * 0.3f);
            } else {
                hoverAnim = Math.max(0f, hoverAnim - animSpeed);
                scale = Math.max(1f, scale - animSpeed * 0.3f);
            }

            int baseBgColor = new Color(20, 20, 30, 180).getRGB();
            int hoverBgColor = new Color(40, 40, 60, 220).getRGB();
            int bgColor = ColorUtil.blendColorsInt(baseBgColor, hoverBgColor, hoverAnim);

            int baseOutlineColor = new Color(PRIMARY_COLOR.getRed(), PRIMARY_COLOR.getGreen(), PRIMARY_COLOR.getBlue(), 100).getRGB();
            int hoverOutlineColor = new Color(ACCENT_COLOR.getRed(), ACCENT_COLOR.getGreen(), ACCENT_COLOR.getBlue(), 200).getRGB();
            int outlineColor = ColorUtil.blendColorsInt(baseOutlineColor, hoverOutlineColor, hoverAnim);

            if (hovered) {
                RenderUtil.drawBlur(context.getMatrices(), x - 5, y - 5, width + 10, height + 10, 8, 2f,
                    ColorUtil.applyAlpha(outlineColor, hoverAnim * 0.5f));
            }

            float textHeight = 18;
            float textY = y + (height - textHeight) / 2f + 3.5f;

            context.getMatrices().push();
            context.getMatrices().translate(x + width / 2f, y + height / 2f, 0);
            context.getMatrices().scale(scale, scale, 1);
            context.getMatrices().translate(-(x + width / 2f), -(y + height / 2f), 0);

            RenderUtil.drawRoundedRect(context.getMatrices(), x, y, width, height, 6, bgColor);
            RenderUtil.drawRoundedBorder(context.getMatrices(), x, y, width, height, 6, 2f, outlineColor);

            FontUtils.gilroy[18].centeredDraw(context.getMatrices(), name, x + width / 2f, textY,
                ColorUtil.blendColorsInt(Color.WHITE.getRGB(),
                    ColorUtil.blendColorsInt(PRIMARY_COLOR.getRGB(), ACCENT_COLOR.getRGB(), hoverAnim), hoverAnim * 0.3f));

            context.getMatrices().pop();
        }

        boolean isHovered(double mouseX, double mouseY) {
            return mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
        }
    }

    private class CombinedButton {
        int x, y, width, height;
        final String leftName, rightName;

        private float leftHoverAnim = 0f;
        private float rightHoverAnim = 0f;
        private float leftScale = 1f;
        private float rightScale = 1f;

        CombinedButton(int x, int y, int width, int height, String leftName, String rightName) {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
            this.leftName = leftName;
            this.rightName = rightName;
        }

        void render(DrawContext context, int mouseX, int mouseY, float delta) {
            int buttonGap = 2;
            int halfWidth = width / 2;
            int shrink = 3;

            boolean leftHovered = isOptionHovered(mouseX, mouseY);
            boolean rightHovered = isQuitHovered(mouseX, mouseY);

            float animSpeed = 0.04f;

            if (leftHovered) {
                leftHoverAnim = Math.min(1f, leftHoverAnim + animSpeed);
                leftScale = Math.min(1.02f, leftScale + animSpeed * 0.5f);
            } else {
                leftHoverAnim = Math.max(0f, leftHoverAnim - animSpeed);
                leftScale = Math.max(1f, leftScale - animSpeed * 0.5f);
            }

            if (rightHovered) {
                rightHoverAnim = Math.min(1f, rightHoverAnim + animSpeed);
                rightScale = Math.min(1.02f, rightScale + animSpeed * 0.5f);
            } else {
                rightHoverAnim = Math.max(0f, rightHoverAnim - animSpeed);
                rightScale = Math.max(1f, rightScale - animSpeed * 0.5f);
            }

            int baseBgColor = new Color(20, 20, 30, 180).getRGB();
            int hoverBgColor = new Color(40, 40, 60, 220).getRGB();
            int baseOutlineColor = new Color(PRIMARY_COLOR.getRed(), PRIMARY_COLOR.getGreen(), PRIMARY_COLOR.getBlue(), 100).getRGB();
            int hoverOutlineColor = new Color(ACCENT_COLOR.getRed(), ACCENT_COLOR.getGreen(), ACCENT_COLOR.getBlue(), 200).getRGB();

            int buttonWidth = halfWidth - shrink;

            int leftX = x + shrink / 2;
            int leftBg = ColorUtil.blendColorsInt(baseBgColor, hoverBgColor, leftHoverAnim);
            int leftOutline = ColorUtil.blendColorsInt(baseOutlineColor, hoverOutlineColor, leftHoverAnim);

            if (leftHovered) {
                RenderUtil.drawBlur(context.getMatrices(), leftX - 3, y - 3, buttonWidth + 6, height + 6, 6, 1.5f,
                    ColorUtil.applyAlpha(leftOutline, leftHoverAnim * 0.4f));
            }

            context.getMatrices().push();
            context.getMatrices().translate(leftX + buttonWidth / 2f, y + height / 2f, 0);
            context.getMatrices().scale(leftScale, leftScale, 1);
            context.getMatrices().translate(-(leftX + buttonWidth / 2f), -(y + height / 2f), 0);
            RenderUtil.drawRoundedRect(context.getMatrices(), leftX, y, buttonWidth, height, 6, leftBg);
            RenderUtil.drawRoundedBorder(context.getMatrices(), leftX, y, buttonWidth, height, 6, 2f, leftOutline);
            FontUtils.gilroy[18].centeredDraw(context.getMatrices(), leftName, leftX + buttonWidth / 2f, y + (height - 9) / 2.2f,
                ColorUtil.blendColorsInt(Color.WHITE.getRGB(),
                    ColorUtil.blendColorsInt(PRIMARY_COLOR.getRGB(), ACCENT_COLOR.getRGB(), leftHoverAnim), leftHoverAnim * 0.3f));
            context.getMatrices().pop();

            int rightX = x + halfWidth + shrink / 2;
            int rightBg = ColorUtil.blendColorsInt(baseBgColor, hoverBgColor, rightHoverAnim);
            int rightOutline = ColorUtil.blendColorsInt(baseOutlineColor, hoverOutlineColor, rightHoverAnim);

            if (rightHovered) {
                RenderUtil.drawBlur(context.getMatrices(), rightX - 3, y - 3, buttonWidth + 6, height + 6, 6, 1.5f,
                    ColorUtil.applyAlpha(rightOutline, rightHoverAnim * 0.4f));
            }

            context.getMatrices().push();
            context.getMatrices().translate(rightX + buttonWidth / 2f, y + height / 2f, 0);
            context.getMatrices().scale(rightScale, rightScale, 1);
            context.getMatrices().translate(-(rightX + buttonWidth / 2f), -(y + height / 2f), 0);
            RenderUtil.drawRoundedRect(context.getMatrices(), rightX, y, buttonWidth, height, 6, rightBg);
            RenderUtil.drawRoundedBorder(context.getMatrices(), rightX, y, buttonWidth, height, 6, 2f, rightOutline);
            FontUtils.gilroy[18].centeredDraw(context.getMatrices(), rightName, rightX + buttonWidth / 2f, y + (height - 9) / 2.2f,
                ColorUtil.blendColorsInt(Color.WHITE.getRGB(),
                    ColorUtil.blendColorsInt(PRIMARY_COLOR.getRGB(), ACCENT_COLOR.getRGB(), rightHoverAnim), rightHoverAnim * 0.3f));
            context.getMatrices().pop();
        }

        boolean isOptionHovered(double mouseX, double mouseY) {
            return mouseX >= x && mouseX < x + width / 2 && mouseY >= y && mouseY <= y + height;
        }

        boolean isQuitHovered(double mouseX, double mouseY) {
            return mouseX >= x + width / 2 && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
        }
    }

    @Override
    public boolean shouldCloseOnEsc() {
        return false;
    }
}
норм, но можно было лучше
 
Первая тема
класс MainMenu
Код:
Expand Collapse Copy
package ru.levin.screens.mainmenu;

import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.option.OptionsScreen;
import net.minecraft.client.gui.screen.world.SelectWorldScreen;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import ru.levin.screens.altmanager.AltManager;
import ru.levin.util.color.ColorUtil;
import ru.levin.manager.fontManager.FontUtils;
import ru.levin.util.render.RenderUtil;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

@SuppressWarnings("All")
public class MainMenu extends Screen {

    private Button singleplayerButton;
    private Button multiplayerButton;
    private Button altmanagerButton;
    private CombinedButton optionsQuitButton;

    private final String title = "ExosWare";

    private final Color PRIMARY_COLOR = new Color(138, 43, 226);
    private final Color SECONDARY_COLOR = new Color(75, 0, 130);
    private final Color ACCENT_COLOR = new Color(255, 20, 147);
    private final Color BACKGROUND_COLOR = new Color(25, 25, 35, 240);

    private int shakeTime = 0;
    private float shakeOffsetY = 0f;
    private float backgroundOffset = 0f;
    private float cameraRotation = 0f;

    private List<Particle> particles = new ArrayList<>();
    private Random random = new Random();
    private long lastParticleTime = 0;

    private final Identifier BACKGROUND_TEXTURE = Identifier.of("exosware", "images/gui/background360.png");

    public MainMenu() {
        super(Text.literal("Custom Main Menu"));
    }

    @Override
    protected void init() {
        int buttonWidth = 160;
        int buttonHeight = 24;

        singleplayerButton = new Button("Singleplayer", 0, 0, buttonWidth, buttonHeight);
        multiplayerButton = new Button("Multiplayer", 0, 0, buttonWidth, buttonHeight);
        altmanagerButton = new Button("AltManager", 0, 0, buttonWidth, buttonHeight);
        optionsQuitButton = new CombinedButton(0, 0, buttonWidth, buttonHeight, "Options", "Quit");

        initializeParticles();
    }

    private void initializeParticles() {
        particles.clear();
        for (int i = 0; i < 25; i++) {
            particles.add(new Particle(
                random.nextFloat() * this.width,
                random.nextFloat() * this.height,
                random.nextFloat() * 2 - 1,
                random.nextFloat() * 2 - 1,
                random.nextInt(3)
            ));
        }
    }

    @Override
    public void render(DrawContext context, int mouseX, int mouseY, float delta) {
        renderBackground(context, delta);
        updateAndRenderParticles(context, delta);
        if (shakeTime > 0) {
            shakeTime--;
            shakeOffsetY = (float)(Math.sin(shakeTime * 0.5) * 3);
        } else {
            shakeOffsetY = 0f;
        }

        int titleSize = 48;
        int titleWidth = (int) FontUtils.gilroy[titleSize].getWidth(title);
        float titleX = (this.width - titleWidth) / 2f;
        float titleBaseY = this.height / 4f;
        float titleY = titleBaseY + shakeOffsetY;

        float time = (System.currentTimeMillis() % 4000L) / 1500f;
        int startColor = PRIMARY_COLOR.getRGB();
        int endColor = ACCENT_COLOR.getRGB();
        FontUtils.gilroy[titleSize].renderAnimatedGradientText(context.getMatrices(), title, titleX, titleY, startColor, endColor, time);

        float titleHeight = titleSize;

        int spacing = 6;
        int buttonWidth = 160;
        int buttonHeight = 24;

        float buttonsStartY = titleBaseY + titleHeight + spacing * 4;

        int centerX = this.width / 2 - buttonWidth / 2;

        singleplayerButton.x = centerX;
        singleplayerButton.y = (int)buttonsStartY;

        multiplayerButton.x = centerX;
        multiplayerButton.y = (int)(buttonsStartY + buttonHeight + spacing);

        altmanagerButton.x = centerX;
        altmanagerButton.y = (int)(buttonsStartY + 2 * (buttonHeight + spacing));

        optionsQuitButton.x = centerX;
        optionsQuitButton.y = (int)(buttonsStartY + 3 * (buttonHeight + spacing));
        optionsQuitButton.width = buttonWidth;

        singleplayerButton.render(context, mouseX, mouseY, delta);
        multiplayerButton.render(context, mouseX, mouseY, delta);
        altmanagerButton.render(context, mouseX, mouseY, delta);
        optionsQuitButton.render(context, mouseX, mouseY, delta);

        renderVersion(context);
    }

    private void renderBackground(DrawContext context, float delta) {
        backgroundOffset += delta * 0.01f;
        cameraRotation += delta * 0.005f;
        RenderUtil.drawRoundedRect(context.getMatrices(), 0, 0, this.width, this.height, 0, BACKGROUND_COLOR.getRGB());
        try {
            context.getMatrices().push();
            context.getMatrices().translate(this.width / 2f, this.height / 2f, 0);
            context.getMatrices().multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotation(cameraRotation));
            context.getMatrices().translate(-this.width / 2f, -this.height / 2f, 0);

            RenderUtil.drawTexture(context.getMatrices(), BACKGROUND_TEXTURE,
                0, 0, this.width, this.height, 0,
                ColorUtil.applyAlpha(Color.WHITE.getRGB(), 0.3f));

            context.getMatrices().pop();
        } catch (Exception e) {
        }
    }

    private void updateAndRenderParticles(DrawContext context, float delta) {
        long currentTime = System.currentTimeMillis();

        if (currentTime - lastParticleTime > 2000 && particles.size() < 30) {
            particles.add(new Particle(
                random.nextBoolean() ? -10 : this.width + 10,
                random.nextFloat() * this.height,
                random.nextFloat() * 2 - 1,
                random.nextFloat() * 2 - 1,
                random.nextInt(3)
            ));
            lastParticleTime = currentTime;
        }

        particles.removeIf(particle -> particle.update(delta) && particle.isOffScreen(this.width, this.height));

        for (Particle particle : particles) {
            particle.render(context);
        }
    }

    private void renderVersion(DrawContext context) {
        String version = "1.21.4";
        int fontSize = 14;
        int versionWidth = (int) FontUtils.gilroy[fontSize].getWidth(version);
        float versionX = this.width - versionWidth - 10;
        float versionY = this.height - 20;

        FontUtils.gilroy[fontSize].drawLeftAligned(context.getMatrices(), version, versionX, versionY,
            new Color(200, 200, 200, 150).getRGB());
    }

    @Override
    public boolean mouseClicked(double mouseX, double mouseY, int button) {
        int titleSize = 40;
        int titleWidth = (int) FontUtils.sf_bold[titleSize].getWidth(title);
        float titleX = (this.width - titleWidth) / 2f;
        float titleY = this.height / 5f;

        if (mouseX >= titleX && mouseX <= titleX + titleWidth && mouseY >= titleY && mouseY <= titleY + titleSize) {
            shakeTime = 20;
            return true;
        }

        if (singleplayerButton.isHovered(mouseX, mouseY)) {
            this.client.setScreen(new SelectWorldScreen(this));
            return true;
        }
        if (multiplayerButton.isHovered(mouseX, mouseY)) {
            this.client.setScreen(new MultiplayerScreen(this));
            return true;
        }
        if (altmanagerButton.isHovered(mouseX, mouseY)) {
            this.client.setScreen(new AltManager(this));
            return true;
        }
        if (optionsQuitButton.isOptionHovered(mouseX, mouseY)) {
            this.client.setScreen(new OptionsScreen(this, client.options));
            return true;
        }
        if (optionsQuitButton.isQuitHovered(mouseX, mouseY)) {
            this.client.scheduleStop();
            return true;
        }

        return super.mouseClicked(mouseX, mouseY, button);
    }

    private class Particle {
        float x, y, vx, vy;
        int type;
        float life = 1.0f;
        float rotation = 0f;
        float scale = 1f;

        Particle(float x, float y, float vx, float vy, int type) {
            this.x = x;
            this.y = y;
            this.vx = vx;
            this.vy = vy;
            this.type = type;
        }

        boolean update(float delta) {
            x += vx * delta * 30;
            y += vy * delta * 30;
            rotation += delta * 0.5f;
            life -= delta * 0.001f;

            vy += Math.sin(System.currentTimeMillis() * 0.001f + x * 0.01f) * 0.01f;

            return life <= 0;
        }

        boolean isOffScreen(int screenWidth, int screenHeight) {
            return x < -20 || x > screenWidth + 20 || y < -20 || y > screenHeight + 20;
        }

        void render(DrawContext context) {
            String texturePath = switch (type) {
                case 0 -> "images/particles/snowflake.png";
                case 1 -> "images/particles/firefly.png";
                case 2 -> "images/particles/spark.png";
                default -> "images/particles/star.png";
            };

            try {
                context.getMatrices().push();
                context.getMatrices().translate(x, y, 0);
                context.getMatrices().multiply(net.minecraft.util.math.RotationAxis.POSITIVE_Z.rotation(rotation));
                context.getMatrices().scale(scale, scale, 1);

                int alpha = (int)(life * 255);
                int color = (alpha << 24) | 0xFFFFFF;

                RenderUtil.drawTexture(context.getMatrices(),
                    Identifier.of("exosware", texturePath),
                    -8, -8, 16, 16, 4, color);

                context.getMatrices().pop();
            } catch (Exception e) {
                RenderUtil.drawCircle(context.getMatrices(), x, y, 3, ColorUtil.applyAlpha(Color.WHITE.getRGB(), life));
            }
        }
    }

    private class Button {
        final String name;
        int x, y, width, height;

        private float hoverAnim = 0f;
        private float scale = 1f;

        Button(String name, int x, int y, int width, int height) {
            this.name = name;
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }

        void render(DrawContext context, int mouseX, int mouseY, float delta) {
            boolean hovered = isHovered(mouseX, mouseY);

            float animSpeed = 0.06f;

            if (hovered) {
                hoverAnim = Math.min(1f, hoverAnim + animSpeed);
                scale = Math.min(1.05f, scale + animSpeed * 0.3f);
            } else {
                hoverAnim = Math.max(0f, hoverAnim - animSpeed);
                scale = Math.max(1f, scale - animSpeed * 0.3f);
            }

            int baseBgColor = new Color(20, 20, 30, 180).getRGB();
            int hoverBgColor = new Color(40, 40, 60, 220).getRGB();
            int bgColor = ColorUtil.blendColorsInt(baseBgColor, hoverBgColor, hoverAnim);

            int baseOutlineColor = new Color(PRIMARY_COLOR.getRed(), PRIMARY_COLOR.getGreen(), PRIMARY_COLOR.getBlue(), 100).getRGB();
            int hoverOutlineColor = new Color(ACCENT_COLOR.getRed(), ACCENT_COLOR.getGreen(), ACCENT_COLOR.getBlue(), 200).getRGB();
            int outlineColor = ColorUtil.blendColorsInt(baseOutlineColor, hoverOutlineColor, hoverAnim);

            if (hovered) {
                RenderUtil.drawBlur(context.getMatrices(), x - 5, y - 5, width + 10, height + 10, 8, 2f,
                    ColorUtil.applyAlpha(outlineColor, hoverAnim * 0.5f));
            }

            float textHeight = 18;
            float textY = y + (height - textHeight) / 2f + 3.5f;

            context.getMatrices().push();
            context.getMatrices().translate(x + width / 2f, y + height / 2f, 0);
            context.getMatrices().scale(scale, scale, 1);
            context.getMatrices().translate(-(x + width / 2f), -(y + height / 2f), 0);

            RenderUtil.drawRoundedRect(context.getMatrices(), x, y, width, height, 6, bgColor);
            RenderUtil.drawRoundedBorder(context.getMatrices(), x, y, width, height, 6, 2f, outlineColor);

            FontUtils.gilroy[18].centeredDraw(context.getMatrices(), name, x + width / 2f, textY,
                ColorUtil.blendColorsInt(Color.WHITE.getRGB(),
                    ColorUtil.blendColorsInt(PRIMARY_COLOR.getRGB(), ACCENT_COLOR.getRGB(), hoverAnim), hoverAnim * 0.3f));

            context.getMatrices().pop();
        }

        boolean isHovered(double mouseX, double mouseY) {
            return mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
        }
    }

    private class CombinedButton {
        int x, y, width, height;
        final String leftName, rightName;

        private float leftHoverAnim = 0f;
        private float rightHoverAnim = 0f;
        private float leftScale = 1f;
        private float rightScale = 1f;

        CombinedButton(int x, int y, int width, int height, String leftName, String rightName) {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
            this.leftName = leftName;
            this.rightName = rightName;
        }

        void render(DrawContext context, int mouseX, int mouseY, float delta) {
            int buttonGap = 2;
            int halfWidth = width / 2;
            int shrink = 3;

            boolean leftHovered = isOptionHovered(mouseX, mouseY);
            boolean rightHovered = isQuitHovered(mouseX, mouseY);

            float animSpeed = 0.04f;

            if (leftHovered) {
                leftHoverAnim = Math.min(1f, leftHoverAnim + animSpeed);
                leftScale = Math.min(1.02f, leftScale + animSpeed * 0.5f);
            } else {
                leftHoverAnim = Math.max(0f, leftHoverAnim - animSpeed);
                leftScale = Math.max(1f, leftScale - animSpeed * 0.5f);
            }

            if (rightHovered) {
                rightHoverAnim = Math.min(1f, rightHoverAnim + animSpeed);
                rightScale = Math.min(1.02f, rightScale + animSpeed * 0.5f);
            } else {
                rightHoverAnim = Math.max(0f, rightHoverAnim - animSpeed);
                rightScale = Math.max(1f, rightScale - animSpeed * 0.5f);
            }

            int baseBgColor = new Color(20, 20, 30, 180).getRGB();
            int hoverBgColor = new Color(40, 40, 60, 220).getRGB();
            int baseOutlineColor = new Color(PRIMARY_COLOR.getRed(), PRIMARY_COLOR.getGreen(), PRIMARY_COLOR.getBlue(), 100).getRGB();
            int hoverOutlineColor = new Color(ACCENT_COLOR.getRed(), ACCENT_COLOR.getGreen(), ACCENT_COLOR.getBlue(), 200).getRGB();

            int buttonWidth = halfWidth - shrink;

            int leftX = x + shrink / 2;
            int leftBg = ColorUtil.blendColorsInt(baseBgColor, hoverBgColor, leftHoverAnim);
            int leftOutline = ColorUtil.blendColorsInt(baseOutlineColor, hoverOutlineColor, leftHoverAnim);

            if (leftHovered) {
                RenderUtil.drawBlur(context.getMatrices(), leftX - 3, y - 3, buttonWidth + 6, height + 6, 6, 1.5f,
                    ColorUtil.applyAlpha(leftOutline, leftHoverAnim * 0.4f));
            }

            context.getMatrices().push();
            context.getMatrices().translate(leftX + buttonWidth / 2f, y + height / 2f, 0);
            context.getMatrices().scale(leftScale, leftScale, 1);
            context.getMatrices().translate(-(leftX + buttonWidth / 2f), -(y + height / 2f), 0);
            RenderUtil.drawRoundedRect(context.getMatrices(), leftX, y, buttonWidth, height, 6, leftBg);
            RenderUtil.drawRoundedBorder(context.getMatrices(), leftX, y, buttonWidth, height, 6, 2f, leftOutline);
            FontUtils.gilroy[18].centeredDraw(context.getMatrices(), leftName, leftX + buttonWidth / 2f, y + (height - 9) / 2.2f,
                ColorUtil.blendColorsInt(Color.WHITE.getRGB(),
                    ColorUtil.blendColorsInt(PRIMARY_COLOR.getRGB(), ACCENT_COLOR.getRGB(), leftHoverAnim), leftHoverAnim * 0.3f));
            context.getMatrices().pop();

            int rightX = x + halfWidth + shrink / 2;
            int rightBg = ColorUtil.blendColorsInt(baseBgColor, hoverBgColor, rightHoverAnim);
            int rightOutline = ColorUtil.blendColorsInt(baseOutlineColor, hoverOutlineColor, rightHoverAnim);

            if (rightHovered) {
                RenderUtil.drawBlur(context.getMatrices(), rightX - 3, y - 3, buttonWidth + 6, height + 6, 6, 1.5f,
                    ColorUtil.applyAlpha(rightOutline, rightHoverAnim * 0.4f));
            }

            context.getMatrices().push();
            context.getMatrices().translate(rightX + buttonWidth / 2f, y + height / 2f, 0);
            context.getMatrices().scale(rightScale, rightScale, 1);
            context.getMatrices().translate(-(rightX + buttonWidth / 2f), -(y + height / 2f), 0);
            RenderUtil.drawRoundedRect(context.getMatrices(), rightX, y, buttonWidth, height, 6, rightBg);
            RenderUtil.drawRoundedBorder(context.getMatrices(), rightX, y, buttonWidth, height, 6, 2f, rightOutline);
            FontUtils.gilroy[18].centeredDraw(context.getMatrices(), rightName, rightX + buttonWidth / 2f, y + (height - 9) / 2.2f,
                ColorUtil.blendColorsInt(Color.WHITE.getRGB(),
                    ColorUtil.blendColorsInt(PRIMARY_COLOR.getRGB(), ACCENT_COLOR.getRGB(), rightHoverAnim), rightHoverAnim * 0.3f));
            context.getMatrices().pop();
        }

        boolean isOptionHovered(double mouseX, double mouseY) {
            return mouseX >= x && mouseX < x + width / 2 && mouseY >= y && mouseY <= y + height;
        }

        boolean isQuitHovered(double mouseX, double mouseY) {
            return mouseX >= x + width / 2 && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
        }
    }

    @Override
    public boolean shouldCloseOnEsc() {
        return false;
    }
}
почему никто кнопки не меняет что поляк что ты кнопки плохо смотрятся
 
кто то не дадумался кнопки сменить скажу по секрету

SinglePlayer
MultiPlayer
AltManager
на ходяться в классе Button просто вроде

а Quit и option
в CombineButtons
 
Назад
Сверху Снизу