блять там 3 строки поменятьну слушай получилось довольно не плохой скид но внизу где серый текст у векса текст белым ссылкой у тебя нету и фон чуть темнее чем у векса а так годно
Смотрите видео ниже, чтобы узнать, как установить наш сайт в качестве веб-приложения на домашнем экране.
Примечание: Эта возможность может быть недоступна в некоторых браузерах.
блять там 3 строки поменятьну слушай получилось довольно не плохой скид но внизу где серый текст у векса текст белым ссылкой у тебя нету и фон чуть темнее чем у векса а так годно
бля очень ахуенноврод похоже хз
фонты думаю сами найдете
векса:код:package rich.screens.menu; import net.minecraft.client.gui.Click; 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.multiplayer.MultiplayerWarningScreen; import net.minecraft.client.gui.screen.option.OptionsScreen; import net.minecraft.client.gui.screen.world.SelectWorldScreen; import net.minecraft.client.input.KeyInput; import net.minecraft.client.input.CharInput; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.Util; import net.minecraft.util.math.MathHelper; import rich.Initialization; import rich.screens.account.AccountEntry; import rich.screens.account.AccountRenderer; import rich.util.config.impl.account.AccountConfig; import rich.util.render.Render2D; import rich.util.render.font.Fonts; import rich.util.session.SessionChanger; import rich.util.sounds.SoundManager; import antidaunleak.api.UserProfile; import java.awt.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Random; public class MainMenuScreen extends Screen { private static final Identifier BACKGROUND_TEXTURE = Identifier.of("rich", "textures/menu/backmenu.png"); private static final float FIXED_GUI_SCALE = 2.0f; private static final int PARTICLE_COUNT = 50; private static final float PARTICLE_FADE_THRESHOLD = 0.8f; private static class Particle { float x, y; float vx, vy; float size; float alpha; float lifetime; float maxLifetime; boolean isDead = false; Particle(float x, float y) { this.x = x; this.y = y; Random rand = new Random(); this.vx = (rand.nextFloat() - 0.5f) * 0.2f; this.vy = (rand.nextFloat() - 0.5f) * 0.2f; this.size = 0.5f + rand.nextFloat() * 1f; this.alpha = 0.2f + rand.nextFloat() * 0.3f; this.maxLifetime = 10f + rand.nextFloat() * 10f; this.lifetime = 0f; } void update(float delta, int width, int height) { lifetime += delta / 60f; if (lifetime > maxLifetime * PARTICLE_FADE_THRESHOLD) { float fadeProgress = (lifetime - maxLifetime * PARTICLE_FADE_THRESHOLD) / (maxLifetime * (1f - PARTICLE_FADE_THRESHOLD)); alpha = Math.max(0, alpha * (1f - fadeProgress)); } if (lifetime >= maxLifetime) { isDead = true; return; } x += vx * delta; y += vy * delta; if (x < -10 || x > width + 10 || y < -10 || y > height + 10) { isDead = true; } } } private final List<Particle> particles = new java.util.ArrayList<>(); private boolean particlesInitialized = false; private int lastWindowWidth = 0; private int lastWindowHeight = 0; private enum View { MAIN_MENU, ALT_SCREEN } private View currentView = View.MAIN_MENU; private long screenStartTime = 0L; private boolean initialized = false; private long lastRenderTime = 0L; private int hoveredButton = -1; private float[] buttonHoverProgress = new float[6]; private final AccountRenderer accountRenderer; private final AccountConfig accountConfig; private String nicknameText = ""; private boolean nicknameFieldFocused = false; private float scrollOffset = 0f; private float targetScrollOffset = 0f; public MainMenuScreen() { super(Text.literal("Main Menu")); for (int i = 0; i < 6; i++) { buttonHoverProgress[i] = 0f; } this.accountRenderer = new AccountRenderer(); this.accountConfig = AccountConfig.getInstance(); this.accountConfig.load(); } @Override protected void init() { initialized = false; particlesInitialized = false; } private int getFixedScaledWidth() { return (int) Math.ceil((double) client.getWindow().getFramebufferWidth() / FIXED_GUI_SCALE); } private int getFixedScaledHeight() { return (int) Math.ceil((double) client.getWindow().getFramebufferHeight() / FIXED_GUI_SCALE); } private float toFixedCoord(double coord) { float currentScale = (float) client.getWindow().getScaleFactor(); return (float) (coord * currentScale / FIXED_GUI_SCALE); } private void initParticles(int width, int height) { if (particlesInitialized) return; Random rand = new Random(); for (int i = 0; i < PARTICLE_COUNT; i++) { particles.add(new Particle(rand.nextFloat() * width, rand.nextFloat() * height)); } particlesInitialized = true; } private void drawBackground() { int screenWidth = getFixedScaledWidth(); int screenHeight = getFixedScaledHeight(); Render2D.rect(0, 0, screenWidth, screenHeight, new Color(12, 15, 18).getRGB()); initParticles(screenWidth, screenHeight); for (Particle p : particles) { if (!p.isDead && p.alpha > 0.01f) { int alpha = (int) (p.alpha * 255); Render2D.rect(p.x, p.y, p.size, p.size, new Color(255, 255, 255, alpha).getRGB()); } } } @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { long currentTime = Util.getMeasuringTimeMs(); if (!initialized) { screenStartTime = currentTime; lastRenderTime = currentTime; initialized = true; } float deltaTime = Math.min(delta, 0.05f); lastRenderTime = currentTime; int fixedWidth = getFixedScaledWidth(); int fixedHeight = getFixedScaledHeight(); if (lastWindowWidth != fixedWidth || lastWindowHeight != fixedHeight) { particles.clear(); particlesInitialized = false; lastWindowWidth = fixedWidth; lastWindowHeight = fixedHeight; } for (Particle p : particles) { p.update(deltaTime * 60f, fixedWidth, fixedHeight); } particles.removeIf(p -> p.isDead); Random rand = new Random(); while (particles.size() < PARTICLE_COUNT) { particles.add(new Particle(rand.nextFloat() * fixedWidth, rand.nextFloat() * fixedHeight)); } float scaledMouseX = toFixedCoord(mouseX); float scaledMouseY = toFixedCoord(mouseY); updateButtonAnimations(deltaTime, scaledMouseX, scaledMouseY, fixedWidth, fixedHeight); Render2D.beginOverlay(); drawBackground(); if (currentView == View.MAIN_MENU) { renderMainMenu(fixedWidth, fixedHeight, scaledMouseX, scaledMouseY); } else { renderAltScreen(fixedWidth, fixedHeight, scaledMouseX, scaledMouseY, currentTime); } Render2D.endOverlay(); } private void renderMainMenu(int screenWidth, int screenHeight, float mouseX, float mouseY) { float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; String username = "user"; float avatarSize = 20; float avatarX = 8; float avatarY = 10; Fonts.INTER_MEDIUM.draw("Logged in as", avatarX + avatarSize + 5, avatarY, 7f, new Color(150, 150, 150).getRGB()); Fonts.INTER_MEDIUM.draw(username, avatarX + avatarSize + 5, avatarY + 9, 8f, new Color(255, 255, 255).getRGB()); Render2D.rect(avatarX, avatarY, avatarSize, avatarSize, new Color(40, 45, 55).getRGB(), avatarSize / 2f); Identifier userAvatar = Identifier.of("rich", "user.png"); int[] avatarColors = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; float[] avatarRadii = {avatarSize / 2f, avatarSize / 2f, avatarSize / 2f, avatarSize / 2f}; Initialization.getInstance().getManager().getRenderCore().getTexturePipeline() .drawTexture(userAvatar, avatarX, avatarY, avatarSize, avatarSize, 0, 0, 1, 1, avatarColors, avatarRadii, 1f); float logoSize = 35; float logoY = centerY - 90; Identifier logoTexture = Identifier.of("rich", "images/logo.png"); int[] logoColors = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; float[] logoRadii = {0, 0, 0, 0}; Initialization.getInstance().getManager().getRenderCore().getTexturePipeline() .drawTexture(logoTexture, centerX - logoSize / 2f, logoY, logoSize, logoSize, 0, 0, 1, 1, logoColors, logoRadii, 1f); String timeOfDay = getTimeOfDay(); String greeting = "Good " + timeOfDay + ", "; String usernameColored = username; float greetingWidth = Fonts.INTER_SEMIBOLD.getWidth(greeting, 14f); float usernameWidth = Fonts.INTER_SEMIBOLD.getWidth(usernameColored, 14f); float totalGreetingWidth = greetingWidth + usernameWidth; float greetingStartX = centerX - totalGreetingWidth / 2f; float greetingY = centerY - 38; Fonts.INTER_SEMIBOLD.draw(greeting, greetingStartX, greetingY, 14f, new Color(255, 255, 255).getRGB()); Fonts.INTER_SEMIBOLD.draw(usernameColored, greetingStartX + greetingWidth, greetingY, 14f, new Color(100, 180, 255).getRGB()); String welcomeText = "Welcome to "; String clientName = "WexSide. The best client."; String restText = ""; float welcomeWidth = Fonts.INTER_MEDIUM.getWidth(welcomeText, 9f); float clientWidth = Fonts.INTER_MEDIUM.getWidth(clientName, 9f); float restWidth = Fonts.INTER_MEDIUM.getWidth(restText, 9f); float totalWidth = welcomeWidth + clientWidth + restWidth; float startX = centerX - totalWidth / 2f; float textY = centerY - 20; Fonts.INTER_MEDIUM.draw(welcomeText, startX, textY, 9f, new Color(180, 180, 180).getRGB()); Fonts.INTER_SEMIBOLD.draw(clientName, startX + welcomeWidth, textY, 9f, new Color(90, 22, 134).getRGB()); Fonts.INTER_MEDIUM.draw(restText, startX + welcomeWidth + clientWidth, textY, 9f, new Color(180, 180, 180).getRGB()); float buttonWidth = 220; float buttonHeight = 30; float buttonSpacing = 7; float buttonStartY = centerY + 3; drawButton(centerX - buttonWidth / 2f, buttonStartY, buttonWidth, buttonHeight, "Singleplayer", 0, mouseX, mouseY, new Color(30, 35, 45), false); drawButton(centerX - buttonWidth / 2f, buttonStartY + buttonHeight + buttonSpacing, buttonWidth, buttonHeight, "Multiplayer", 1, mouseX, mouseY, new Color(30, 35, 45), false); float swapAccountsY = buttonStartY + (buttonHeight + buttonSpacing) * 2 + 5; drawButton(centerX - buttonWidth / 2f, swapAccountsY, buttonWidth, buttonHeight, "Swap Accounts", 2, mouseX, mouseY, new Color(90, 22, 134), true); float bottomY = swapAccountsY + buttonHeight + 5; float bottomButtonWidth = 65; float bottomButtonHeight = 20; float bottomSpacing = 10; float totalBottomWidth = bottomButtonWidth * 3 + bottomSpacing * 2; float bottomStartX = centerX - totalBottomWidth / 2f; drawSmallButton(bottomStartX, bottomY, bottomButtonWidth, bottomButtonHeight, "Options", 3, mouseX, mouseY); drawSmallButton(bottomStartX + bottomButtonWidth + bottomSpacing, bottomY, bottomButtonWidth, bottomButtonHeight, "Proxies", 4, mouseX, mouseY); drawSmallButton(bottomStartX + (bottomButtonWidth + bottomSpacing) * 2, bottomY, bottomButtonWidth, bottomButtonHeight, "Exit", 5, mouseX, mouseY); String footerText = "By logging into your account, you agree to all of our policies,"; String policyLinks = "including our Privacy Policy and Terms of Service"; Fonts.INTER_MEDIUM.drawCentered(footerText, centerX, screenHeight - 17, 6.5f, new Color(100, 100, 100).getRGB()); Fonts.INTER_MEDIUM.drawCentered(policyLinks, centerX, screenHeight - 8, 6.5f, new Color(100, 100, 100).getRGB()); } private String getTimeOfDay() { int hour = java.time.LocalTime.now().getHour(); if (hour >= 5 && hour < 12) return "morning"; if (hour >= 12 && hour < 17) return "afternoon"; if (hour >= 17 && hour < 21) return "evening"; return "night"; } private void drawButton(float x, float y, float width, float height, String text, int index, float mouseX, float mouseY, Color baseColor, boolean isPurple) { boolean hovered = isMouseOver(mouseX, mouseY, x, y, width, height); float hoverProgress = buttonHoverProgress[index]; Color bgColor = baseColor; if (isPurple) { int brightness = (int) (hoverProgress * 20); bgColor = new Color( Math.min(255, baseColor.getRed() + brightness), Math.min(255, baseColor.getGreen() + brightness), Math.min(255, baseColor.getBlue() + brightness) ); } else { int brightness = (int) (hoverProgress * 15); bgColor = new Color( Math.min(255, baseColor.getRed() + brightness), Math.min(255, baseColor.getGreen() + brightness), Math.min(255, baseColor.getBlue() + brightness) ); } Render2D.rect(x, y, width, height, bgColor.getRGB(), 8); if (!isPurple) { Render2D.outline(x, y, width, height, 1f, new Color(50, 55, 65, 80).getRGB(), 8); } if (hoverProgress > 0.01f) { int borderAlpha = (int) (hoverProgress * 100); Color borderColor = isPurple ? new Color(138, 43, 226, borderAlpha) : new Color(100, 110, 130, borderAlpha); Render2D.outline(x, y, width, height, 1f, borderColor.getRGB(), 8); } float fontSize = 9f; float textHeight = Fonts.INTER_MEDIUM.getHeight(fontSize); Color textColor = isPurple ? new Color(255, 255, 255) : new Color(160, 160, 160); Fonts.INTER_MEDIUM.drawCentered(text, x + width / 2f, y + (height - textHeight) / 2f, fontSize, textColor.getRGB()); } private void drawSmallButton(float x, float y, float width, float height, String text, int index, float mouseX, float mouseY) { float hoverProgress = buttonHoverProgress[index]; int baseAlpha = 150; int hoverAlpha = (int) (baseAlpha + hoverProgress * 50); float fontSize = 8f; float textHeight = Fonts.INTER_MEDIUM.getHeight(fontSize); Fonts.INTER_MEDIUM.drawCentered(text, x + width / 2f, y + (height - textHeight) / 2f, fontSize, new Color(180, 180, 180, hoverAlpha).getRGB()); } private boolean isMouseOver(float mouseX, float mouseY, float x, float y, float width, float height) { return mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height; } private void updateButtonAnimations(float deltaTime, float mouseX, float mouseY, int screenWidth, int screenHeight) { float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float lerpSpeed = 1f - (float) Math.pow(0.001f, deltaTime); if (currentView == View.MAIN_MENU) { float buttonWidth = 220; float buttonHeight = 30; float buttonSpacing = 7; float buttonStartY = centerY + 3; for (int i = 0; i < 2; i++) { float y = buttonStartY + i * (buttonHeight + buttonSpacing); boolean hovered = isMouseOver(mouseX, mouseY, centerX - buttonWidth / 2f, y, buttonWidth, buttonHeight); float target = hovered ? 1f : 0f; buttonHoverProgress[i] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[i], target); } float swapAccountsY = buttonStartY + (buttonHeight + buttonSpacing) * 2 + 5; boolean swapHovered = isMouseOver(mouseX, mouseY, centerX - buttonWidth / 2f, swapAccountsY, buttonWidth, buttonHeight); buttonHoverProgress[2] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[2], swapHovered ? 1f : 0f); float bottomY = swapAccountsY + buttonHeight + 5; float bottomButtonWidth = 65; float bottomButtonHeight = 20; float bottomSpacing = 10; float totalBottomWidth = bottomButtonWidth * 3 + bottomSpacing * 2; float bottomStartX = centerX - totalBottomWidth / 2f; for (int i = 0; i < 3; i++) { float x = bottomStartX + i * (bottomButtonWidth + bottomSpacing); boolean hovered = isMouseOver(mouseX, mouseY, x, bottomY, bottomButtonWidth, bottomButtonHeight); float target = hovered ? 1f : 0f; buttonHoverProgress[i + 3] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[i + 3], target); } } else { for (int i = 0; i < 6; i++) { buttonHoverProgress[i] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[i], 0f); } } } private void renderAltScreen(int screenWidth, int screenHeight, float mouseX, float mouseY, long currentTime) { float totalWidth = 405; float totalHeight = 163; float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float startX = centerX - totalWidth / 2f; float startY = centerY - totalHeight / 2f; float leftPanelX = startX; float leftPanelTopY = startY; accountRenderer.renderLeftPanelTop(leftPanelX, leftPanelTopY, 100, 100, 1f, nicknameText, nicknameFieldFocused, mouseX, mouseY, currentTime); float leftPanelBottomY = startY + 100 + 5; accountRenderer.renderLeftPanelBottom(leftPanelX, leftPanelBottomY, 100, 58, 1f, accountConfig.getActiveAccountName(), accountConfig.getActiveAccountDate(), accountConfig.getActiveAccountSkin()); float rightPanelX = startX + 100 + 5; float rightPanelY = startY; List<AccountEntry> sortedAccounts = accountConfig.getSortedAccounts(); accountRenderer.renderRightPanel(rightPanelX, rightPanelY, 300, 165, 1f, sortedAccounts, scrollOffset, mouseX, mouseY, 1f, (int) FIXED_GUI_SCALE); } @Override public boolean mouseClicked(Click click, boolean doubled) { float scaledMouseX = toFixedCoord(click.x()); float scaledMouseY = toFixedCoord(click.y()); if (currentView == View.MAIN_MENU) { if (click.button() == 0) { int fixedWidth = getFixedScaledWidth(); int fixedHeight = getFixedScaledHeight(); float centerX = fixedWidth / 2f; float centerY = fixedHeight / 2f; float buttonWidth = 220; float buttonHeight = 30; float buttonSpacing = 7; float buttonStartY = centerY + 3; for (int i = 0; i < 2; i++) { float y = buttonStartY + i * (buttonHeight + buttonSpacing); if (isMouseOver(scaledMouseX, scaledMouseY, centerX - buttonWidth / 2f, y, buttonWidth, buttonHeight)) { handleMainMenuButtonClick(i); return true; } } float swapAccountsY = buttonStartY + (buttonHeight + buttonSpacing) * 2 + 5; if (isMouseOver(scaledMouseX, scaledMouseY, centerX - buttonWidth / 2f, swapAccountsY, buttonWidth, buttonHeight)) { handleMainMenuButtonClick(2); return true; } float bottomY = swapAccountsY + buttonHeight + 5; float bottomButtonWidth = 65; float bottomButtonHeight = 20; float bottomSpacing = 10; float totalBottomWidth = bottomButtonWidth * 3 + bottomSpacing * 2; float bottomStartX = centerX - totalBottomWidth / 2f; for (int i = 0; i < 3; i++) { float x = bottomStartX + i * (bottomButtonWidth + bottomSpacing); if (isMouseOver(scaledMouseX, scaledMouseY, x, bottomY, bottomButtonWidth, bottomButtonHeight)) { handleMainMenuButtonClick(i + 3); return true; } } } } else if (currentView == View.ALT_SCREEN) { return handleAltScreenClick(scaledMouseX, scaledMouseY, click); } return super.mouseClicked(click, doubled); } private void handleMainMenuButtonClick(int index) { switch (index) { case 0 -> this.client.setScreen(new SelectWorldScreen(this)); case 1 -> { Screen screen = this.client.options.skipMultiplayerWarning ? new MultiplayerScreen(this) : new MultiplayerWarningScreen(this); this.client.setScreen(screen); } case 2 -> currentView = View.ALT_SCREEN; case 3 -> this.client.setScreen(new OptionsScreen(this, this.client.options)); case 4 -> {} case 5 -> this.client.scheduleStop(); } } private boolean handleAltScreenClick(float mouseX, float mouseY, Click click) { int screenWidth = getFixedScaledWidth(); int screenHeight = getFixedScaledHeight(); float totalWidth = 100 + 5 + 300; float totalHeight = 100 + 5 + 58; float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float startX = centerX - totalWidth / 2f; float startY = centerY - totalHeight / 2f; float leftPanelX = startX; float leftPanelTopY = startY; float fieldX = leftPanelX + 5; float fieldY = leftPanelTopY + 38; float fieldHeight = 14; float addButtonSize = 14; float buttonGap = 3; float fieldWidth = 100 - 10 - addButtonSize - buttonGap; if (accountRenderer.isMouseOver(mouseX, mouseY, fieldX, fieldY, fieldWidth, fieldHeight)) { nicknameFieldFocused = true; return true; } else { nicknameFieldFocused = false; } float addButtonX = fieldX + fieldWidth + buttonGap; float addButtonY = fieldY; if (accountRenderer.isMouseOver(mouseX, mouseY, addButtonX, addButtonY, addButtonSize, addButtonSize)) { if (!nicknameText.isEmpty()) { addAccount(nicknameText); nicknameText = ""; } return true; } float buttonWidth = 100 - 10; float buttonHeight = 16; float randomButtonX = leftPanelX + 5; float randomButtonY = fieldY + fieldHeight + 6; if (accountRenderer.isMouseOver(mouseX, mouseY, randomButtonX, randomButtonY, buttonWidth, buttonHeight)) { String randomNick = generateRandomNickname(); addAccount(randomNick); nicknameText = ""; return true; } float clearButtonX = leftPanelX + 5; float clearButtonY = randomButtonY + buttonHeight + 5; if (accountRenderer.isMouseOver(mouseX, mouseY, clearButtonX, clearButtonY, buttonWidth, buttonHeight)) { accountConfig.clearAllAccounts(); targetScrollOffset = 0f; scrollOffset = 0f; return true; } float rightPanelX = startX + 100 + 5; float rightPanelY = startY; float accountListX = rightPanelX + 5; float accountListY = rightPanelY + 26; float accountListWidth = 300 - 10; float accountListHeight = 165 - 31; if (!accountRenderer.isMouseOver(mouseX, mouseY, accountListX, accountListY, accountListWidth, accountListHeight)) { return false; } float cardWidth = (accountListWidth - 5) / 2f; float cardHeight = 40; float cardGap = 5; List<AccountEntry> sortedAccounts = accountConfig.getSortedAccounts(); for (int i = 0; i < sortedAccounts.size(); i++) { int col = i % 2; int row = i / 2; float cardX = accountListX + col * (cardWidth + cardGap); float cardY = accountListY + row * (cardHeight + cardGap) - scrollOffset; if (cardY + cardHeight < accountListY || cardY > accountListY + accountListHeight) { continue; } float btnSize = 12; float buttonYPos = cardY + cardHeight - btnSize - 5; float pinButtonX = cardX + cardWidth - btnSize * 2 - 8; float deleteButtonX = cardX + cardWidth - btnSize - 5; if (accountRenderer.isMouseOver(mouseX, mouseY, pinButtonX, buttonYPos, btnSize, btnSize)) { AccountEntry entry = sortedAccounts.get(i); entry.togglePinned(); if (entry.isPinned()) { setActiveAccount(entry); } accountConfig.save(); return true; } if (accountRenderer.isMouseOver(mouseX, mouseY, deleteButtonX, buttonYPos, btnSize, btnSize)) { accountConfig.removeAccountByIndex(i); return true; } if (accountRenderer.isMouseOver(mouseX, mouseY, cardX, cardY, cardWidth, cardHeight)) { setActiveAccount(sortedAccounts.get(i)); return true; } } return false; } @Override public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { if (currentView != View.ALT_SCREEN) return false; float scaledMouseX = toFixedCoord(mouseX); float scaledMouseY = toFixedCoord(mouseY); int screenWidth = getFixedScaledWidth(); int screenHeight = getFixedScaledHeight(); float totalWidth = 100 + 5 + 300; float totalHeight = 100 + 5 + 58; float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float startX = centerX - totalWidth / 2f; float startY = centerY - totalHeight / 2f; float rightPanelX = startX + 100 + 5; float rightPanelY = startY; if (accountRenderer.isMouseOver(scaledMouseX, scaledMouseY, rightPanelX, rightPanelY, 300, 165)) { float cardHeight = 40; float cardGap = 5; float accountListHeight = 165 - 31; int rows = (int) Math.ceil(accountConfig.getSortedAccounts().size() / 2.0); float maxScroll = Math.max(0, rows * (cardHeight + cardGap) - accountListHeight); targetScrollOffset -= (float) verticalAmount * 25; targetScrollOffset = MathHelper.clamp(targetScrollOffset, 0, maxScroll); float scrollSpeed = 12f; float deltaTime = 0.016f; float scrollDiff = targetScrollOffset - scrollOffset; scrollOffset += scrollDiff * Math.min(1f, deltaTime * scrollSpeed); return true; } return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); } @Override public boolean keyPressed(KeyInput input) { if (currentView == View.ALT_SCREEN) { if (nicknameFieldFocused) { int keyCode = input.key(); if (keyCode == 259) { if (!nicknameText.isEmpty()) { nicknameText = nicknameText.substring(0, nicknameText.length() - 1); } return true; } if (keyCode == 256) { nicknameFieldFocused = false; return true; } if (keyCode == 257 || keyCode == 335) { if (!nicknameText.isEmpty()) { addAccount(nicknameText); nicknameText = ""; } nicknameFieldFocused = false; return true; } } if (input.key() == 256) { currentView = View.MAIN_MENU; accountConfig.save(); return true; } } return super.keyPressed(input); } @Override public boolean charTyped(CharInput input) { if (currentView == View.ALT_SCREEN && nicknameFieldFocused) { int codepoint = input.codepoint(); if (Character.isLetterOrDigit(codepoint) || codepoint == '_') { if (nicknameText.length() < 16) { nicknameText += Character.toString(codepoint); } return true; } } return super.charTyped(input); } private void setActiveAccount(AccountEntry account) { accountConfig.setActiveAccount(account.getName(), account.getDate(), account.getSkin()); SessionChanger.changeUsername(account.getName()); } private void addAccount(String nickname) { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); String date = now.format(formatter); AccountEntry entry = new AccountEntry(nickname, date, null); accountConfig.addAccount(entry); setActiveAccount(entry); SessionChanger.changeUsername(nickname); } private String generateRandomNickname() { Random random = new Random(); StringBuilder username = new StringBuilder(); char[] vowels = {'a', 'e', 'i', 'o', 'u'}; char[] consonants = {'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'}; String finalUsername = null; int attempts = 0; final int MAX_ATTEMPTS = 10; List<AccountEntry> existingAccounts = accountConfig.getAccounts(); do { username.setLength(0); int length = 6 + random.nextInt(5); boolean startWithVowel = random.nextBoolean(); for (int i = 0; i < length; i++) { if (i % 2 == 0) { username.append(startWithVowel ? vowels[random.nextInt(vowels.length)] : consonants[random.nextInt(consonants.length)]); } else { username.append(startWithVowel ? consonants[random.nextInt(consonants.length)] : vowels[random.nextInt(vowels.length)]); } } if (random.nextInt(100) < 30) { username.append(random.nextInt(100)); } String tempUsername = username.substring(0, 1).toUpperCase() + username.substring(1); attempts++; boolean exists = false; for (AccountEntry account : existingAccounts) { if (account.getName().equalsIgnoreCase(tempUsername)) { exists = true; break; } } if (!exists) { finalUsername = tempUsername; break; } } while (attempts < MAX_ATTEMPTS); if (finalUsername == null) { finalUsername = username.substring(0, 1).toUpperCase() + username.substring(1) + (System.currentTimeMillis() % 1000); } return finalUsername; } @Override public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { drawBackground(); } @Override public boolean shouldCloseOnEsc() { return false; } @Override public boolean shouldPause() { return false; } private int withAlpha(int color, int alpha) { return (color & 0x00FFFFFF) | (MathHelper.clamp(alpha, 0, 255) << 24); } } }
Посмотреть вложение 327281
мое:Посмотреть вложение 327344
upd: добавил обводку
охуенноврод похоже хз
фонты думаю сами найдете
векса:код:package rich.screens.menu; import net.minecraft.client.gui.Click; 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.multiplayer.MultiplayerWarningScreen; import net.minecraft.client.gui.screen.option.OptionsScreen; import net.minecraft.client.gui.screen.world.SelectWorldScreen; import net.minecraft.client.input.KeyInput; import net.minecraft.client.input.CharInput; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.Util; import net.minecraft.util.math.MathHelper; import rich.Initialization; import rich.screens.account.AccountEntry; import rich.screens.account.AccountRenderer; import rich.util.config.impl.account.AccountConfig; import rich.util.render.Render2D; import rich.util.render.font.Fonts; import rich.util.session.SessionChanger; import rich.util.sounds.SoundManager; import antidaunleak.api.UserProfile; import java.awt.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Random; public class MainMenuScreen extends Screen { private static final Identifier BACKGROUND_TEXTURE = Identifier.of("rich", "textures/menu/backmenu.png"); private static final float FIXED_GUI_SCALE = 2.0f; private static final int PARTICLE_COUNT = 50; private static final float PARTICLE_FADE_THRESHOLD = 0.8f; private static class Particle { float x, y; float vx, vy; float size; float alpha; float lifetime; float maxLifetime; boolean isDead = false; Particle(float x, float y) { this.x = x; this.y = y; Random rand = new Random(); this.vx = (rand.nextFloat() - 0.5f) * 0.2f; this.vy = (rand.nextFloat() - 0.5f) * 0.2f; this.size = 0.5f + rand.nextFloat() * 1f; this.alpha = 0.2f + rand.nextFloat() * 0.3f; this.maxLifetime = 10f + rand.nextFloat() * 10f; this.lifetime = 0f; } void update(float delta, int width, int height) { lifetime += delta / 60f; if (lifetime > maxLifetime * PARTICLE_FADE_THRESHOLD) { float fadeProgress = (lifetime - maxLifetime * PARTICLE_FADE_THRESHOLD) / (maxLifetime * (1f - PARTICLE_FADE_THRESHOLD)); alpha = Math.max(0, alpha * (1f - fadeProgress)); } if (lifetime >= maxLifetime) { isDead = true; return; } x += vx * delta; y += vy * delta; if (x < -10 || x > width + 10 || y < -10 || y > height + 10) { isDead = true; } } } private final List<Particle> particles = new java.util.ArrayList<>(); private boolean particlesInitialized = false; private int lastWindowWidth = 0; private int lastWindowHeight = 0; private enum View { MAIN_MENU, ALT_SCREEN } private View currentView = View.MAIN_MENU; private long screenStartTime = 0L; private boolean initialized = false; private long lastRenderTime = 0L; private int hoveredButton = -1; private float[] buttonHoverProgress = new float[6]; private final AccountRenderer accountRenderer; private final AccountConfig accountConfig; private String nicknameText = ""; private boolean nicknameFieldFocused = false; private float scrollOffset = 0f; private float targetScrollOffset = 0f; public MainMenuScreen() { super(Text.literal("Main Menu")); for (int i = 0; i < 6; i++) { buttonHoverProgress[i] = 0f; } this.accountRenderer = new AccountRenderer(); this.accountConfig = AccountConfig.getInstance(); this.accountConfig.load(); } @Override protected void init() { initialized = false; particlesInitialized = false; } private int getFixedScaledWidth() { return (int) Math.ceil((double) client.getWindow().getFramebufferWidth() / FIXED_GUI_SCALE); } private int getFixedScaledHeight() { return (int) Math.ceil((double) client.getWindow().getFramebufferHeight() / FIXED_GUI_SCALE); } private float toFixedCoord(double coord) { float currentScale = (float) client.getWindow().getScaleFactor(); return (float) (coord * currentScale / FIXED_GUI_SCALE); } private void initParticles(int width, int height) { if (particlesInitialized) return; Random rand = new Random(); for (int i = 0; i < PARTICLE_COUNT; i++) { particles.add(new Particle(rand.nextFloat() * width, rand.nextFloat() * height)); } particlesInitialized = true; } private void drawBackground() { int screenWidth = getFixedScaledWidth(); int screenHeight = getFixedScaledHeight(); Render2D.rect(0, 0, screenWidth, screenHeight, new Color(12, 15, 18).getRGB()); initParticles(screenWidth, screenHeight); for (Particle p : particles) { if (!p.isDead && p.alpha > 0.01f) { int alpha = (int) (p.alpha * 255); Render2D.rect(p.x, p.y, p.size, p.size, new Color(255, 255, 255, alpha).getRGB()); } } } @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { long currentTime = Util.getMeasuringTimeMs(); if (!initialized) { screenStartTime = currentTime; lastRenderTime = currentTime; initialized = true; } float deltaTime = Math.min(delta, 0.05f); lastRenderTime = currentTime; int fixedWidth = getFixedScaledWidth(); int fixedHeight = getFixedScaledHeight(); if (lastWindowWidth != fixedWidth || lastWindowHeight != fixedHeight) { particles.clear(); particlesInitialized = false; lastWindowWidth = fixedWidth; lastWindowHeight = fixedHeight; } for (Particle p : particles) { p.update(deltaTime * 60f, fixedWidth, fixedHeight); } particles.removeIf(p -> p.isDead); Random rand = new Random(); while (particles.size() < PARTICLE_COUNT) { particles.add(new Particle(rand.nextFloat() * fixedWidth, rand.nextFloat() * fixedHeight)); } float scaledMouseX = toFixedCoord(mouseX); float scaledMouseY = toFixedCoord(mouseY); updateButtonAnimations(deltaTime, scaledMouseX, scaledMouseY, fixedWidth, fixedHeight); Render2D.beginOverlay(); drawBackground(); if (currentView == View.MAIN_MENU) { renderMainMenu(fixedWidth, fixedHeight, scaledMouseX, scaledMouseY); } else { renderAltScreen(fixedWidth, fixedHeight, scaledMouseX, scaledMouseY, currentTime); } Render2D.endOverlay(); } private void renderMainMenu(int screenWidth, int screenHeight, float mouseX, float mouseY) { float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; String username = "user"; float avatarSize = 20; float avatarX = 8; float avatarY = 10; Fonts.INTER_MEDIUM.draw("Logged in as", avatarX + avatarSize + 5, avatarY, 7f, new Color(150, 150, 150).getRGB()); Fonts.INTER_MEDIUM.draw(username, avatarX + avatarSize + 5, avatarY + 9, 8f, new Color(255, 255, 255).getRGB()); Render2D.rect(avatarX, avatarY, avatarSize, avatarSize, new Color(40, 45, 55).getRGB(), avatarSize / 2f); Identifier userAvatar = Identifier.of("rich", "user.png"); int[] avatarColors = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; float[] avatarRadii = {avatarSize / 2f, avatarSize / 2f, avatarSize / 2f, avatarSize / 2f}; Initialization.getInstance().getManager().getRenderCore().getTexturePipeline() .drawTexture(userAvatar, avatarX, avatarY, avatarSize, avatarSize, 0, 0, 1, 1, avatarColors, avatarRadii, 1f); float logoSize = 35; float logoY = centerY - 90; Identifier logoTexture = Identifier.of("rich", "images/logo.png"); int[] logoColors = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; float[] logoRadii = {0, 0, 0, 0}; Initialization.getInstance().getManager().getRenderCore().getTexturePipeline() .drawTexture(logoTexture, centerX - logoSize / 2f, logoY, logoSize, logoSize, 0, 0, 1, 1, logoColors, logoRadii, 1f); String timeOfDay = getTimeOfDay(); String greeting = "Good " + timeOfDay + ", "; String usernameColored = username; float greetingWidth = Fonts.INTER_SEMIBOLD.getWidth(greeting, 14f); float usernameWidth = Fonts.INTER_SEMIBOLD.getWidth(usernameColored, 14f); float totalGreetingWidth = greetingWidth + usernameWidth; float greetingStartX = centerX - totalGreetingWidth / 2f; float greetingY = centerY - 38; Fonts.INTER_SEMIBOLD.draw(greeting, greetingStartX, greetingY, 14f, new Color(255, 255, 255).getRGB()); Fonts.INTER_SEMIBOLD.draw(usernameColored, greetingStartX + greetingWidth, greetingY, 14f, new Color(100, 180, 255).getRGB()); String welcomeText = "Welcome to "; String clientName = "WexSide. The best client."; String restText = ""; float welcomeWidth = Fonts.INTER_MEDIUM.getWidth(welcomeText, 9f); float clientWidth = Fonts.INTER_MEDIUM.getWidth(clientName, 9f); float restWidth = Fonts.INTER_MEDIUM.getWidth(restText, 9f); float totalWidth = welcomeWidth + clientWidth + restWidth; float startX = centerX - totalWidth / 2f; float textY = centerY - 20; Fonts.INTER_MEDIUM.draw(welcomeText, startX, textY, 9f, new Color(180, 180, 180).getRGB()); Fonts.INTER_SEMIBOLD.draw(clientName, startX + welcomeWidth, textY, 9f, new Color(90, 22, 134).getRGB()); Fonts.INTER_MEDIUM.draw(restText, startX + welcomeWidth + clientWidth, textY, 9f, new Color(180, 180, 180).getRGB()); float buttonWidth = 220; float buttonHeight = 30; float buttonSpacing = 7; float buttonStartY = centerY + 3; drawButton(centerX - buttonWidth / 2f, buttonStartY, buttonWidth, buttonHeight, "Singleplayer", 0, mouseX, mouseY, new Color(30, 35, 45), false); drawButton(centerX - buttonWidth / 2f, buttonStartY + buttonHeight + buttonSpacing, buttonWidth, buttonHeight, "Multiplayer", 1, mouseX, mouseY, new Color(30, 35, 45), false); float swapAccountsY = buttonStartY + (buttonHeight + buttonSpacing) * 2 + 5; drawButton(centerX - buttonWidth / 2f, swapAccountsY, buttonWidth, buttonHeight, "Swap Accounts", 2, mouseX, mouseY, new Color(90, 22, 134), true); float bottomY = swapAccountsY + buttonHeight + 5; float bottomButtonWidth = 65; float bottomButtonHeight = 20; float bottomSpacing = 10; float totalBottomWidth = bottomButtonWidth * 3 + bottomSpacing * 2; float bottomStartX = centerX - totalBottomWidth / 2f; drawSmallButton(bottomStartX, bottomY, bottomButtonWidth, bottomButtonHeight, "Options", 3, mouseX, mouseY); drawSmallButton(bottomStartX + bottomButtonWidth + bottomSpacing, bottomY, bottomButtonWidth, bottomButtonHeight, "Proxies", 4, mouseX, mouseY); drawSmallButton(bottomStartX + (bottomButtonWidth + bottomSpacing) * 2, bottomY, bottomButtonWidth, bottomButtonHeight, "Exit", 5, mouseX, mouseY); String footerText = "By logging into your account, you agree to all of our policies,"; String policyLinks = "including our Privacy Policy and Terms of Service"; Fonts.INTER_MEDIUM.drawCentered(footerText, centerX, screenHeight - 17, 6.5f, new Color(100, 100, 100).getRGB()); Fonts.INTER_MEDIUM.drawCentered(policyLinks, centerX, screenHeight - 8, 6.5f, new Color(100, 100, 100).getRGB()); } private String getTimeOfDay() { int hour = java.time.LocalTime.now().getHour(); if (hour >= 5 && hour < 12) return "morning"; if (hour >= 12 && hour < 17) return "afternoon"; if (hour >= 17 && hour < 21) return "evening"; return "night"; } private void drawButton(float x, float y, float width, float height, String text, int index, float mouseX, float mouseY, Color baseColor, boolean isPurple) { boolean hovered = isMouseOver(mouseX, mouseY, x, y, width, height); float hoverProgress = buttonHoverProgress[index]; Color bgColor = baseColor; if (isPurple) { int brightness = (int) (hoverProgress * 20); bgColor = new Color( Math.min(255, baseColor.getRed() + brightness), Math.min(255, baseColor.getGreen() + brightness), Math.min(255, baseColor.getBlue() + brightness) ); } else { int brightness = (int) (hoverProgress * 15); bgColor = new Color( Math.min(255, baseColor.getRed() + brightness), Math.min(255, baseColor.getGreen() + brightness), Math.min(255, baseColor.getBlue() + brightness) ); } Render2D.rect(x, y, width, height, bgColor.getRGB(), 8); if (!isPurple) { Render2D.outline(x, y, width, height, 1f, new Color(50, 55, 65, 80).getRGB(), 8); } if (hoverProgress > 0.01f) { int borderAlpha = (int) (hoverProgress * 100); Color borderColor = isPurple ? new Color(138, 43, 226, borderAlpha) : new Color(100, 110, 130, borderAlpha); Render2D.outline(x, y, width, height, 1f, borderColor.getRGB(), 8); } float fontSize = 9f; float textHeight = Fonts.INTER_MEDIUM.getHeight(fontSize); Color textColor = isPurple ? new Color(255, 255, 255) : new Color(160, 160, 160); Fonts.INTER_MEDIUM.drawCentered(text, x + width / 2f, y + (height - textHeight) / 2f, fontSize, textColor.getRGB()); } private void drawSmallButton(float x, float y, float width, float height, String text, int index, float mouseX, float mouseY) { float hoverProgress = buttonHoverProgress[index]; int baseAlpha = 150; int hoverAlpha = (int) (baseAlpha + hoverProgress * 50); float fontSize = 8f; float textHeight = Fonts.INTER_MEDIUM.getHeight(fontSize); Fonts.INTER_MEDIUM.drawCentered(text, x + width / 2f, y + (height - textHeight) / 2f, fontSize, new Color(180, 180, 180, hoverAlpha).getRGB()); } private boolean isMouseOver(float mouseX, float mouseY, float x, float y, float width, float height) { return mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height; } private void updateButtonAnimations(float deltaTime, float mouseX, float mouseY, int screenWidth, int screenHeight) { float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float lerpSpeed = 1f - (float) Math.pow(0.001f, deltaTime); if (currentView == View.MAIN_MENU) { float buttonWidth = 220; float buttonHeight = 30; float buttonSpacing = 7; float buttonStartY = centerY + 3; for (int i = 0; i < 2; i++) { float y = buttonStartY + i * (buttonHeight + buttonSpacing); boolean hovered = isMouseOver(mouseX, mouseY, centerX - buttonWidth / 2f, y, buttonWidth, buttonHeight); float target = hovered ? 1f : 0f; buttonHoverProgress[i] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[i], target); } float swapAccountsY = buttonStartY + (buttonHeight + buttonSpacing) * 2 + 5; boolean swapHovered = isMouseOver(mouseX, mouseY, centerX - buttonWidth / 2f, swapAccountsY, buttonWidth, buttonHeight); buttonHoverProgress[2] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[2], swapHovered ? 1f : 0f); float bottomY = swapAccountsY + buttonHeight + 5; float bottomButtonWidth = 65; float bottomButtonHeight = 20; float bottomSpacing = 10; float totalBottomWidth = bottomButtonWidth * 3 + bottomSpacing * 2; float bottomStartX = centerX - totalBottomWidth / 2f; for (int i = 0; i < 3; i++) { float x = bottomStartX + i * (bottomButtonWidth + bottomSpacing); boolean hovered = isMouseOver(mouseX, mouseY, x, bottomY, bottomButtonWidth, bottomButtonHeight); float target = hovered ? 1f : 0f; buttonHoverProgress[i + 3] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[i + 3], target); } } else { for (int i = 0; i < 6; i++) { buttonHoverProgress[i] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[i], 0f); } } } private void renderAltScreen(int screenWidth, int screenHeight, float mouseX, float mouseY, long currentTime) { float totalWidth = 405; float totalHeight = 163; float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float startX = centerX - totalWidth / 2f; float startY = centerY - totalHeight / 2f; float leftPanelX = startX; float leftPanelTopY = startY; accountRenderer.renderLeftPanelTop(leftPanelX, leftPanelTopY, 100, 100, 1f, nicknameText, nicknameFieldFocused, mouseX, mouseY, currentTime); float leftPanelBottomY = startY + 100 + 5; accountRenderer.renderLeftPanelBottom(leftPanelX, leftPanelBottomY, 100, 58, 1f, accountConfig.getActiveAccountName(), accountConfig.getActiveAccountDate(), accountConfig.getActiveAccountSkin()); float rightPanelX = startX + 100 + 5; float rightPanelY = startY; List<AccountEntry> sortedAccounts = accountConfig.getSortedAccounts(); accountRenderer.renderRightPanel(rightPanelX, rightPanelY, 300, 165, 1f, sortedAccounts, scrollOffset, mouseX, mouseY, 1f, (int) FIXED_GUI_SCALE); } @Override public boolean mouseClicked(Click click, boolean doubled) { float scaledMouseX = toFixedCoord(click.x()); float scaledMouseY = toFixedCoord(click.y()); if (currentView == View.MAIN_MENU) { if (click.button() == 0) { int fixedWidth = getFixedScaledWidth(); int fixedHeight = getFixedScaledHeight(); float centerX = fixedWidth / 2f; float centerY = fixedHeight / 2f; float buttonWidth = 220; float buttonHeight = 30; float buttonSpacing = 7; float buttonStartY = centerY + 3; for (int i = 0; i < 2; i++) { float y = buttonStartY + i * (buttonHeight + buttonSpacing); if (isMouseOver(scaledMouseX, scaledMouseY, centerX - buttonWidth / 2f, y, buttonWidth, buttonHeight)) { handleMainMenuButtonClick(i); return true; } } float swapAccountsY = buttonStartY + (buttonHeight + buttonSpacing) * 2 + 5; if (isMouseOver(scaledMouseX, scaledMouseY, centerX - buttonWidth / 2f, swapAccountsY, buttonWidth, buttonHeight)) { handleMainMenuButtonClick(2); return true; } float bottomY = swapAccountsY + buttonHeight + 5; float bottomButtonWidth = 65; float bottomButtonHeight = 20; float bottomSpacing = 10; float totalBottomWidth = bottomButtonWidth * 3 + bottomSpacing * 2; float bottomStartX = centerX - totalBottomWidth / 2f; for (int i = 0; i < 3; i++) { float x = bottomStartX + i * (bottomButtonWidth + bottomSpacing); if (isMouseOver(scaledMouseX, scaledMouseY, x, bottomY, bottomButtonWidth, bottomButtonHeight)) { handleMainMenuButtonClick(i + 3); return true; } } } } else if (currentView == View.ALT_SCREEN) { return handleAltScreenClick(scaledMouseX, scaledMouseY, click); } return super.mouseClicked(click, doubled); } private void handleMainMenuButtonClick(int index) { switch (index) { case 0 -> this.client.setScreen(new SelectWorldScreen(this)); case 1 -> { Screen screen = this.client.options.skipMultiplayerWarning ? new MultiplayerScreen(this) : new MultiplayerWarningScreen(this); this.client.setScreen(screen); } case 2 -> currentView = View.ALT_SCREEN; case 3 -> this.client.setScreen(new OptionsScreen(this, this.client.options)); case 4 -> {} case 5 -> this.client.scheduleStop(); } } private boolean handleAltScreenClick(float mouseX, float mouseY, Click click) { int screenWidth = getFixedScaledWidth(); int screenHeight = getFixedScaledHeight(); float totalWidth = 100 + 5 + 300; float totalHeight = 100 + 5 + 58; float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float startX = centerX - totalWidth / 2f; float startY = centerY - totalHeight / 2f; float leftPanelX = startX; float leftPanelTopY = startY; float fieldX = leftPanelX + 5; float fieldY = leftPanelTopY + 38; float fieldHeight = 14; float addButtonSize = 14; float buttonGap = 3; float fieldWidth = 100 - 10 - addButtonSize - buttonGap; if (accountRenderer.isMouseOver(mouseX, mouseY, fieldX, fieldY, fieldWidth, fieldHeight)) { nicknameFieldFocused = true; return true; } else { nicknameFieldFocused = false; } float addButtonX = fieldX + fieldWidth + buttonGap; float addButtonY = fieldY; if (accountRenderer.isMouseOver(mouseX, mouseY, addButtonX, addButtonY, addButtonSize, addButtonSize)) { if (!nicknameText.isEmpty()) { addAccount(nicknameText); nicknameText = ""; } return true; } float buttonWidth = 100 - 10; float buttonHeight = 16; float randomButtonX = leftPanelX + 5; float randomButtonY = fieldY + fieldHeight + 6; if (accountRenderer.isMouseOver(mouseX, mouseY, randomButtonX, randomButtonY, buttonWidth, buttonHeight)) { String randomNick = generateRandomNickname(); addAccount(randomNick); nicknameText = ""; return true; } float clearButtonX = leftPanelX + 5; float clearButtonY = randomButtonY + buttonHeight + 5; if (accountRenderer.isMouseOver(mouseX, mouseY, clearButtonX, clearButtonY, buttonWidth, buttonHeight)) { accountConfig.clearAllAccounts(); targetScrollOffset = 0f; scrollOffset = 0f; return true; } float rightPanelX = startX + 100 + 5; float rightPanelY = startY; float accountListX = rightPanelX + 5; float accountListY = rightPanelY + 26; float accountListWidth = 300 - 10; float accountListHeight = 165 - 31; if (!accountRenderer.isMouseOver(mouseX, mouseY, accountListX, accountListY, accountListWidth, accountListHeight)) { return false; } float cardWidth = (accountListWidth - 5) / 2f; float cardHeight = 40; float cardGap = 5; List<AccountEntry> sortedAccounts = accountConfig.getSortedAccounts(); for (int i = 0; i < sortedAccounts.size(); i++) { int col = i % 2; int row = i / 2; float cardX = accountListX + col * (cardWidth + cardGap); float cardY = accountListY + row * (cardHeight + cardGap) - scrollOffset; if (cardY + cardHeight < accountListY || cardY > accountListY + accountListHeight) { continue; } float btnSize = 12; float buttonYPos = cardY + cardHeight - btnSize - 5; float pinButtonX = cardX + cardWidth - btnSize * 2 - 8; float deleteButtonX = cardX + cardWidth - btnSize - 5; if (accountRenderer.isMouseOver(mouseX, mouseY, pinButtonX, buttonYPos, btnSize, btnSize)) { AccountEntry entry = sortedAccounts.get(i); entry.togglePinned(); if (entry.isPinned()) { setActiveAccount(entry); } accountConfig.save(); return true; } if (accountRenderer.isMouseOver(mouseX, mouseY, deleteButtonX, buttonYPos, btnSize, btnSize)) { accountConfig.removeAccountByIndex(i); return true; } if (accountRenderer.isMouseOver(mouseX, mouseY, cardX, cardY, cardWidth, cardHeight)) { setActiveAccount(sortedAccounts.get(i)); return true; } } return false; } @Override public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { if (currentView != View.ALT_SCREEN) return false; float scaledMouseX = toFixedCoord(mouseX); float scaledMouseY = toFixedCoord(mouseY); int screenWidth = getFixedScaledWidth(); int screenHeight = getFixedScaledHeight(); float totalWidth = 100 + 5 + 300; float totalHeight = 100 + 5 + 58; float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float startX = centerX - totalWidth / 2f; float startY = centerY - totalHeight / 2f; float rightPanelX = startX + 100 + 5; float rightPanelY = startY; if (accountRenderer.isMouseOver(scaledMouseX, scaledMouseY, rightPanelX, rightPanelY, 300, 165)) { float cardHeight = 40; float cardGap = 5; float accountListHeight = 165 - 31; int rows = (int) Math.ceil(accountConfig.getSortedAccounts().size() / 2.0); float maxScroll = Math.max(0, rows * (cardHeight + cardGap) - accountListHeight); targetScrollOffset -= (float) verticalAmount * 25; targetScrollOffset = MathHelper.clamp(targetScrollOffset, 0, maxScroll); float scrollSpeed = 12f; float deltaTime = 0.016f; float scrollDiff = targetScrollOffset - scrollOffset; scrollOffset += scrollDiff * Math.min(1f, deltaTime * scrollSpeed); return true; } return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); } @Override public boolean keyPressed(KeyInput input) { if (currentView == View.ALT_SCREEN) { if (nicknameFieldFocused) { int keyCode = input.key(); if (keyCode == 259) { if (!nicknameText.isEmpty()) { nicknameText = nicknameText.substring(0, nicknameText.length() - 1); } return true; } if (keyCode == 256) { nicknameFieldFocused = false; return true; } if (keyCode == 257 || keyCode == 335) { if (!nicknameText.isEmpty()) { addAccount(nicknameText); nicknameText = ""; } nicknameFieldFocused = false; return true; } } if (input.key() == 256) { currentView = View.MAIN_MENU; accountConfig.save(); return true; } } return super.keyPressed(input); } @Override public boolean charTyped(CharInput input) { if (currentView == View.ALT_SCREEN && nicknameFieldFocused) { int codepoint = input.codepoint(); if (Character.isLetterOrDigit(codepoint) || codepoint == '_') { if (nicknameText.length() < 16) { nicknameText += Character.toString(codepoint); } return true; } } return super.charTyped(input); } private void setActiveAccount(AccountEntry account) { accountConfig.setActiveAccount(account.getName(), account.getDate(), account.getSkin()); SessionChanger.changeUsername(account.getName()); } private void addAccount(String nickname) { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); String date = now.format(formatter); AccountEntry entry = new AccountEntry(nickname, date, null); accountConfig.addAccount(entry); setActiveAccount(entry); SessionChanger.changeUsername(nickname); } private String generateRandomNickname() { Random random = new Random(); StringBuilder username = new StringBuilder(); char[] vowels = {'a', 'e', 'i', 'o', 'u'}; char[] consonants = {'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'}; String finalUsername = null; int attempts = 0; final int MAX_ATTEMPTS = 10; List<AccountEntry> existingAccounts = accountConfig.getAccounts(); do { username.setLength(0); int length = 6 + random.nextInt(5); boolean startWithVowel = random.nextBoolean(); for (int i = 0; i < length; i++) { if (i % 2 == 0) { username.append(startWithVowel ? vowels[random.nextInt(vowels.length)] : consonants[random.nextInt(consonants.length)]); } else { username.append(startWithVowel ? consonants[random.nextInt(consonants.length)] : vowels[random.nextInt(vowels.length)]); } } if (random.nextInt(100) < 30) { username.append(random.nextInt(100)); } String tempUsername = username.substring(0, 1).toUpperCase() + username.substring(1); attempts++; boolean exists = false; for (AccountEntry account : existingAccounts) { if (account.getName().equalsIgnoreCase(tempUsername)) { exists = true; break; } } if (!exists) { finalUsername = tempUsername; break; } } while (attempts < MAX_ATTEMPTS); if (finalUsername == null) { finalUsername = username.substring(0, 1).toUpperCase() + username.substring(1) + (System.currentTimeMillis() % 1000); } return finalUsername; } @Override public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { drawBackground(); } @Override public boolean shouldCloseOnEsc() { return false; } @Override public boolean shouldPause() { return false; } private int withAlpha(int color, int alpha) { return (color & 0x00FFFFFF) | (MathHelper.clamp(alpha, 0, 255) << 24); } } }
Посмотреть вложение 327281
мое:Посмотреть вложение 327344
upd: добавил обводку
где фонт этот взять
ну мне нрав, да и вроде повторил как у вексаврод похоже хз
фонты думаю сами найдете
векса:код:package rich.screens.menu; import net.minecraft.client.gui.Click; 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.multiplayer.MultiplayerWarningScreen; import net.minecraft.client.gui.screen.option.OptionsScreen; import net.minecraft.client.gui.screen.world.SelectWorldScreen; import net.minecraft.client.input.KeyInput; import net.minecraft.client.input.CharInput; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.Util; import net.minecraft.util.math.MathHelper; import rich.Initialization; import rich.screens.account.AccountEntry; import rich.screens.account.AccountRenderer; import rich.util.config.impl.account.AccountConfig; import rich.util.render.Render2D; import rich.util.render.font.Fonts; import rich.util.session.SessionChanger; import rich.util.sounds.SoundManager; import antidaunleak.api.UserProfile; import java.awt.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Random; public class MainMenuScreen extends Screen { private static final Identifier BACKGROUND_TEXTURE = Identifier.of("rich", "textures/menu/backmenu.png"); private static final float FIXED_GUI_SCALE = 2.0f; private static final int PARTICLE_COUNT = 50; private static final float PARTICLE_FADE_THRESHOLD = 0.8f; private static class Particle { float x, y; float vx, vy; float size; float alpha; float lifetime; float maxLifetime; boolean isDead = false; Particle(float x, float y) { this.x = x; this.y = y; Random rand = new Random(); this.vx = (rand.nextFloat() - 0.5f) * 0.2f; this.vy = (rand.nextFloat() - 0.5f) * 0.2f; this.size = 0.5f + rand.nextFloat() * 1f; this.alpha = 0.2f + rand.nextFloat() * 0.3f; this.maxLifetime = 10f + rand.nextFloat() * 10f; this.lifetime = 0f; } void update(float delta, int width, int height) { lifetime += delta / 60f; if (lifetime > maxLifetime * PARTICLE_FADE_THRESHOLD) { float fadeProgress = (lifetime - maxLifetime * PARTICLE_FADE_THRESHOLD) / (maxLifetime * (1f - PARTICLE_FADE_THRESHOLD)); alpha = Math.max(0, alpha * (1f - fadeProgress)); } if (lifetime >= maxLifetime) { isDead = true; return; } x += vx * delta; y += vy * delta; if (x < -10 || x > width + 10 || y < -10 || y > height + 10) { isDead = true; } } } private final List<Particle> particles = new java.util.ArrayList<>(); private boolean particlesInitialized = false; private int lastWindowWidth = 0; private int lastWindowHeight = 0; private enum View { MAIN_MENU, ALT_SCREEN } private View currentView = View.MAIN_MENU; private long screenStartTime = 0L; private boolean initialized = false; private long lastRenderTime = 0L; private int hoveredButton = -1; private float[] buttonHoverProgress = new float[6]; private final AccountRenderer accountRenderer; private final AccountConfig accountConfig; private String nicknameText = ""; private boolean nicknameFieldFocused = false; private float scrollOffset = 0f; private float targetScrollOffset = 0f; public MainMenuScreen() { super(Text.literal("Main Menu")); for (int i = 0; i < 6; i++) { buttonHoverProgress[i] = 0f; } this.accountRenderer = new AccountRenderer(); this.accountConfig = AccountConfig.getInstance(); this.accountConfig.load(); } @Override protected void init() { initialized = false; particlesInitialized = false; } private int getFixedScaledWidth() { return (int) Math.ceil((double) client.getWindow().getFramebufferWidth() / FIXED_GUI_SCALE); } private int getFixedScaledHeight() { return (int) Math.ceil((double) client.getWindow().getFramebufferHeight() / FIXED_GUI_SCALE); } private float toFixedCoord(double coord) { float currentScale = (float) client.getWindow().getScaleFactor(); return (float) (coord * currentScale / FIXED_GUI_SCALE); } private void initParticles(int width, int height) { if (particlesInitialized) return; Random rand = new Random(); for (int i = 0; i < PARTICLE_COUNT; i++) { particles.add(new Particle(rand.nextFloat() * width, rand.nextFloat() * height)); } particlesInitialized = true; } private void drawBackground() { int screenWidth = getFixedScaledWidth(); int screenHeight = getFixedScaledHeight(); Render2D.rect(0, 0, screenWidth, screenHeight, new Color(12, 15, 18).getRGB()); initParticles(screenWidth, screenHeight); for (Particle p : particles) { if (!p.isDead && p.alpha > 0.01f) { int alpha = (int) (p.alpha * 255); Render2D.rect(p.x, p.y, p.size, p.size, new Color(255, 255, 255, alpha).getRGB()); } } } @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { long currentTime = Util.getMeasuringTimeMs(); if (!initialized) { screenStartTime = currentTime; lastRenderTime = currentTime; initialized = true; } float deltaTime = Math.min(delta, 0.05f); lastRenderTime = currentTime; int fixedWidth = getFixedScaledWidth(); int fixedHeight = getFixedScaledHeight(); if (lastWindowWidth != fixedWidth || lastWindowHeight != fixedHeight) { particles.clear(); particlesInitialized = false; lastWindowWidth = fixedWidth; lastWindowHeight = fixedHeight; } for (Particle p : particles) { p.update(deltaTime * 60f, fixedWidth, fixedHeight); } particles.removeIf(p -> p.isDead); Random rand = new Random(); while (particles.size() < PARTICLE_COUNT) { particles.add(new Particle(rand.nextFloat() * fixedWidth, rand.nextFloat() * fixedHeight)); } float scaledMouseX = toFixedCoord(mouseX); float scaledMouseY = toFixedCoord(mouseY); updateButtonAnimations(deltaTime, scaledMouseX, scaledMouseY, fixedWidth, fixedHeight); Render2D.beginOverlay(); drawBackground(); if (currentView == View.MAIN_MENU) { renderMainMenu(fixedWidth, fixedHeight, scaledMouseX, scaledMouseY); } else { renderAltScreen(fixedWidth, fixedHeight, scaledMouseX, scaledMouseY, currentTime); } Render2D.endOverlay(); } private void renderMainMenu(int screenWidth, int screenHeight, float mouseX, float mouseY) { float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; String username = "user"; float avatarSize = 20; float avatarX = 8; float avatarY = 10; Fonts.INTER_MEDIUM.draw("Logged in as", avatarX + avatarSize + 5, avatarY, 7f, new Color(150, 150, 150).getRGB()); Fonts.INTER_MEDIUM.draw(username, avatarX + avatarSize + 5, avatarY + 9, 8f, new Color(255, 255, 255).getRGB()); Render2D.rect(avatarX, avatarY, avatarSize, avatarSize, new Color(40, 45, 55).getRGB(), avatarSize / 2f); Identifier userAvatar = Identifier.of("rich", "user.png"); int[] avatarColors = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; float[] avatarRadii = {avatarSize / 2f, avatarSize / 2f, avatarSize / 2f, avatarSize / 2f}; Initialization.getInstance().getManager().getRenderCore().getTexturePipeline() .drawTexture(userAvatar, avatarX, avatarY, avatarSize, avatarSize, 0, 0, 1, 1, avatarColors, avatarRadii, 1f); float logoSize = 35; float logoY = centerY - 90; Identifier logoTexture = Identifier.of("rich", "images/logo.png"); int[] logoColors = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; float[] logoRadii = {0, 0, 0, 0}; Initialization.getInstance().getManager().getRenderCore().getTexturePipeline() .drawTexture(logoTexture, centerX - logoSize / 2f, logoY, logoSize, logoSize, 0, 0, 1, 1, logoColors, logoRadii, 1f); String timeOfDay = getTimeOfDay(); String greeting = "Good " + timeOfDay + ", "; String usernameColored = username; float greetingWidth = Fonts.INTER_SEMIBOLD.getWidth(greeting, 14f); float usernameWidth = Fonts.INTER_SEMIBOLD.getWidth(usernameColored, 14f); float totalGreetingWidth = greetingWidth + usernameWidth; float greetingStartX = centerX - totalGreetingWidth / 2f; float greetingY = centerY - 38; Fonts.INTER_SEMIBOLD.draw(greeting, greetingStartX, greetingY, 14f, new Color(255, 255, 255).getRGB()); Fonts.INTER_SEMIBOLD.draw(usernameColored, greetingStartX + greetingWidth, greetingY, 14f, new Color(100, 180, 255).getRGB()); String welcomeText = "Welcome to "; String clientName = "WexSide. The best client."; String restText = ""; float welcomeWidth = Fonts.INTER_MEDIUM.getWidth(welcomeText, 9f); float clientWidth = Fonts.INTER_MEDIUM.getWidth(clientName, 9f); float restWidth = Fonts.INTER_MEDIUM.getWidth(restText, 9f); float totalWidth = welcomeWidth + clientWidth + restWidth; float startX = centerX - totalWidth / 2f; float textY = centerY - 20; Fonts.INTER_MEDIUM.draw(welcomeText, startX, textY, 9f, new Color(180, 180, 180).getRGB()); Fonts.INTER_SEMIBOLD.draw(clientName, startX + welcomeWidth, textY, 9f, new Color(90, 22, 134).getRGB()); Fonts.INTER_MEDIUM.draw(restText, startX + welcomeWidth + clientWidth, textY, 9f, new Color(180, 180, 180).getRGB()); float buttonWidth = 220; float buttonHeight = 30; float buttonSpacing = 7; float buttonStartY = centerY + 3; drawButton(centerX - buttonWidth / 2f, buttonStartY, buttonWidth, buttonHeight, "Singleplayer", 0, mouseX, mouseY, new Color(30, 35, 45), false); drawButton(centerX - buttonWidth / 2f, buttonStartY + buttonHeight + buttonSpacing, buttonWidth, buttonHeight, "Multiplayer", 1, mouseX, mouseY, new Color(30, 35, 45), false); float swapAccountsY = buttonStartY + (buttonHeight + buttonSpacing) * 2 + 5; drawButton(centerX - buttonWidth / 2f, swapAccountsY, buttonWidth, buttonHeight, "Swap Accounts", 2, mouseX, mouseY, new Color(90, 22, 134), true); float bottomY = swapAccountsY + buttonHeight + 5; float bottomButtonWidth = 65; float bottomButtonHeight = 20; float bottomSpacing = 10; float totalBottomWidth = bottomButtonWidth * 3 + bottomSpacing * 2; float bottomStartX = centerX - totalBottomWidth / 2f; drawSmallButton(bottomStartX, bottomY, bottomButtonWidth, bottomButtonHeight, "Options", 3, mouseX, mouseY); drawSmallButton(bottomStartX + bottomButtonWidth + bottomSpacing, bottomY, bottomButtonWidth, bottomButtonHeight, "Proxies", 4, mouseX, mouseY); drawSmallButton(bottomStartX + (bottomButtonWidth + bottomSpacing) * 2, bottomY, bottomButtonWidth, bottomButtonHeight, "Exit", 5, mouseX, mouseY); String footerText = "By logging into your account, you agree to all of our policies,"; String policyLinks = "including our Privacy Policy and Terms of Service"; Fonts.INTER_MEDIUM.drawCentered(footerText, centerX, screenHeight - 17, 6.5f, new Color(100, 100, 100).getRGB()); Fonts.INTER_MEDIUM.drawCentered(policyLinks, centerX, screenHeight - 8, 6.5f, new Color(100, 100, 100).getRGB()); } private String getTimeOfDay() { int hour = java.time.LocalTime.now().getHour(); if (hour >= 5 && hour < 12) return "morning"; if (hour >= 12 && hour < 17) return "afternoon"; if (hour >= 17 && hour < 21) return "evening"; return "night"; } private void drawButton(float x, float y, float width, float height, String text, int index, float mouseX, float mouseY, Color baseColor, boolean isPurple) { boolean hovered = isMouseOver(mouseX, mouseY, x, y, width, height); float hoverProgress = buttonHoverProgress[index]; Color bgColor = baseColor; if (isPurple) { int brightness = (int) (hoverProgress * 20); bgColor = new Color( Math.min(255, baseColor.getRed() + brightness), Math.min(255, baseColor.getGreen() + brightness), Math.min(255, baseColor.getBlue() + brightness) ); } else { int brightness = (int) (hoverProgress * 15); bgColor = new Color( Math.min(255, baseColor.getRed() + brightness), Math.min(255, baseColor.getGreen() + brightness), Math.min(255, baseColor.getBlue() + brightness) ); } Render2D.rect(x, y, width, height, bgColor.getRGB(), 8); if (!isPurple) { Render2D.outline(x, y, width, height, 1f, new Color(50, 55, 65, 80).getRGB(), 8); } if (hoverProgress > 0.01f) { int borderAlpha = (int) (hoverProgress * 100); Color borderColor = isPurple ? new Color(138, 43, 226, borderAlpha) : new Color(100, 110, 130, borderAlpha); Render2D.outline(x, y, width, height, 1f, borderColor.getRGB(), 8); } float fontSize = 9f; float textHeight = Fonts.INTER_MEDIUM.getHeight(fontSize); Color textColor = isPurple ? new Color(255, 255, 255) : new Color(160, 160, 160); Fonts.INTER_MEDIUM.drawCentered(text, x + width / 2f, y + (height - textHeight) / 2f, fontSize, textColor.getRGB()); } private void drawSmallButton(float x, float y, float width, float height, String text, int index, float mouseX, float mouseY) { float hoverProgress = buttonHoverProgress[index]; int baseAlpha = 150; int hoverAlpha = (int) (baseAlpha + hoverProgress * 50); float fontSize = 8f; float textHeight = Fonts.INTER_MEDIUM.getHeight(fontSize); Fonts.INTER_MEDIUM.drawCentered(text, x + width / 2f, y + (height - textHeight) / 2f, fontSize, new Color(180, 180, 180, hoverAlpha).getRGB()); } private boolean isMouseOver(float mouseX, float mouseY, float x, float y, float width, float height) { return mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height; } private void updateButtonAnimations(float deltaTime, float mouseX, float mouseY, int screenWidth, int screenHeight) { float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float lerpSpeed = 1f - (float) Math.pow(0.001f, deltaTime); if (currentView == View.MAIN_MENU) { float buttonWidth = 220; float buttonHeight = 30; float buttonSpacing = 7; float buttonStartY = centerY + 3; for (int i = 0; i < 2; i++) { float y = buttonStartY + i * (buttonHeight + buttonSpacing); boolean hovered = isMouseOver(mouseX, mouseY, centerX - buttonWidth / 2f, y, buttonWidth, buttonHeight); float target = hovered ? 1f : 0f; buttonHoverProgress[i] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[i], target); } float swapAccountsY = buttonStartY + (buttonHeight + buttonSpacing) * 2 + 5; boolean swapHovered = isMouseOver(mouseX, mouseY, centerX - buttonWidth / 2f, swapAccountsY, buttonWidth, buttonHeight); buttonHoverProgress[2] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[2], swapHovered ? 1f : 0f); float bottomY = swapAccountsY + buttonHeight + 5; float bottomButtonWidth = 65; float bottomButtonHeight = 20; float bottomSpacing = 10; float totalBottomWidth = bottomButtonWidth * 3 + bottomSpacing * 2; float bottomStartX = centerX - totalBottomWidth / 2f; for (int i = 0; i < 3; i++) { float x = bottomStartX + i * (bottomButtonWidth + bottomSpacing); boolean hovered = isMouseOver(mouseX, mouseY, x, bottomY, bottomButtonWidth, bottomButtonHeight); float target = hovered ? 1f : 0f; buttonHoverProgress[i + 3] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[i + 3], target); } } else { for (int i = 0; i < 6; i++) { buttonHoverProgress[i] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[i], 0f); } } } private void renderAltScreen(int screenWidth, int screenHeight, float mouseX, float mouseY, long currentTime) { float totalWidth = 405; float totalHeight = 163; float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float startX = centerX - totalWidth / 2f; float startY = centerY - totalHeight / 2f; float leftPanelX = startX; float leftPanelTopY = startY; accountRenderer.renderLeftPanelTop(leftPanelX, leftPanelTopY, 100, 100, 1f, nicknameText, nicknameFieldFocused, mouseX, mouseY, currentTime); float leftPanelBottomY = startY + 100 + 5; accountRenderer.renderLeftPanelBottom(leftPanelX, leftPanelBottomY, 100, 58, 1f, accountConfig.getActiveAccountName(), accountConfig.getActiveAccountDate(), accountConfig.getActiveAccountSkin()); float rightPanelX = startX + 100 + 5; float rightPanelY = startY; List<AccountEntry> sortedAccounts = accountConfig.getSortedAccounts(); accountRenderer.renderRightPanel(rightPanelX, rightPanelY, 300, 165, 1f, sortedAccounts, scrollOffset, mouseX, mouseY, 1f, (int) FIXED_GUI_SCALE); } @Override public boolean mouseClicked(Click click, boolean doubled) { float scaledMouseX = toFixedCoord(click.x()); float scaledMouseY = toFixedCoord(click.y()); if (currentView == View.MAIN_MENU) { if (click.button() == 0) { int fixedWidth = getFixedScaledWidth(); int fixedHeight = getFixedScaledHeight(); float centerX = fixedWidth / 2f; float centerY = fixedHeight / 2f; float buttonWidth = 220; float buttonHeight = 30; float buttonSpacing = 7; float buttonStartY = centerY + 3; for (int i = 0; i < 2; i++) { float y = buttonStartY + i * (buttonHeight + buttonSpacing); if (isMouseOver(scaledMouseX, scaledMouseY, centerX - buttonWidth / 2f, y, buttonWidth, buttonHeight)) { handleMainMenuButtonClick(i); return true; } } float swapAccountsY = buttonStartY + (buttonHeight + buttonSpacing) * 2 + 5; if (isMouseOver(scaledMouseX, scaledMouseY, centerX - buttonWidth / 2f, swapAccountsY, buttonWidth, buttonHeight)) { handleMainMenuButtonClick(2); return true; } float bottomY = swapAccountsY + buttonHeight + 5; float bottomButtonWidth = 65; float bottomButtonHeight = 20; float bottomSpacing = 10; float totalBottomWidth = bottomButtonWidth * 3 + bottomSpacing * 2; float bottomStartX = centerX - totalBottomWidth / 2f; for (int i = 0; i < 3; i++) { float x = bottomStartX + i * (bottomButtonWidth + bottomSpacing); if (isMouseOver(scaledMouseX, scaledMouseY, x, bottomY, bottomButtonWidth, bottomButtonHeight)) { handleMainMenuButtonClick(i + 3); return true; } } } } else if (currentView == View.ALT_SCREEN) { return handleAltScreenClick(scaledMouseX, scaledMouseY, click); } return super.mouseClicked(click, doubled); } private void handleMainMenuButtonClick(int index) { switch (index) { case 0 -> this.client.setScreen(new SelectWorldScreen(this)); case 1 -> { Screen screen = this.client.options.skipMultiplayerWarning ? new MultiplayerScreen(this) : new MultiplayerWarningScreen(this); this.client.setScreen(screen); } case 2 -> currentView = View.ALT_SCREEN; case 3 -> this.client.setScreen(new OptionsScreen(this, this.client.options)); case 4 -> {} case 5 -> this.client.scheduleStop(); } } private boolean handleAltScreenClick(float mouseX, float mouseY, Click click) { int screenWidth = getFixedScaledWidth(); int screenHeight = getFixedScaledHeight(); float totalWidth = 100 + 5 + 300; float totalHeight = 100 + 5 + 58; float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float startX = centerX - totalWidth / 2f; float startY = centerY - totalHeight / 2f; float leftPanelX = startX; float leftPanelTopY = startY; float fieldX = leftPanelX + 5; float fieldY = leftPanelTopY + 38; float fieldHeight = 14; float addButtonSize = 14; float buttonGap = 3; float fieldWidth = 100 - 10 - addButtonSize - buttonGap; if (accountRenderer.isMouseOver(mouseX, mouseY, fieldX, fieldY, fieldWidth, fieldHeight)) { nicknameFieldFocused = true; return true; } else { nicknameFieldFocused = false; } float addButtonX = fieldX + fieldWidth + buttonGap; float addButtonY = fieldY; if (accountRenderer.isMouseOver(mouseX, mouseY, addButtonX, addButtonY, addButtonSize, addButtonSize)) { if (!nicknameText.isEmpty()) { addAccount(nicknameText); nicknameText = ""; } return true; } float buttonWidth = 100 - 10; float buttonHeight = 16; float randomButtonX = leftPanelX + 5; float randomButtonY = fieldY + fieldHeight + 6; if (accountRenderer.isMouseOver(mouseX, mouseY, randomButtonX, randomButtonY, buttonWidth, buttonHeight)) { String randomNick = generateRandomNickname(); addAccount(randomNick); nicknameText = ""; return true; } float clearButtonX = leftPanelX + 5; float clearButtonY = randomButtonY + buttonHeight + 5; if (accountRenderer.isMouseOver(mouseX, mouseY, clearButtonX, clearButtonY, buttonWidth, buttonHeight)) { accountConfig.clearAllAccounts(); targetScrollOffset = 0f; scrollOffset = 0f; return true; } float rightPanelX = startX + 100 + 5; float rightPanelY = startY; float accountListX = rightPanelX + 5; float accountListY = rightPanelY + 26; float accountListWidth = 300 - 10; float accountListHeight = 165 - 31; if (!accountRenderer.isMouseOver(mouseX, mouseY, accountListX, accountListY, accountListWidth, accountListHeight)) { return false; } float cardWidth = (accountListWidth - 5) / 2f; float cardHeight = 40; float cardGap = 5; List<AccountEntry> sortedAccounts = accountConfig.getSortedAccounts(); for (int i = 0; i < sortedAccounts.size(); i++) { int col = i % 2; int row = i / 2; float cardX = accountListX + col * (cardWidth + cardGap); float cardY = accountListY + row * (cardHeight + cardGap) - scrollOffset; if (cardY + cardHeight < accountListY || cardY > accountListY + accountListHeight) { continue; } float btnSize = 12; float buttonYPos = cardY + cardHeight - btnSize - 5; float pinButtonX = cardX + cardWidth - btnSize * 2 - 8; float deleteButtonX = cardX + cardWidth - btnSize - 5; if (accountRenderer.isMouseOver(mouseX, mouseY, pinButtonX, buttonYPos, btnSize, btnSize)) { AccountEntry entry = sortedAccounts.get(i); entry.togglePinned(); if (entry.isPinned()) { setActiveAccount(entry); } accountConfig.save(); return true; } if (accountRenderer.isMouseOver(mouseX, mouseY, deleteButtonX, buttonYPos, btnSize, btnSize)) { accountConfig.removeAccountByIndex(i); return true; } if (accountRenderer.isMouseOver(mouseX, mouseY, cardX, cardY, cardWidth, cardHeight)) { setActiveAccount(sortedAccounts.get(i)); return true; } } return false; } @Override public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { if (currentView != View.ALT_SCREEN) return false; float scaledMouseX = toFixedCoord(mouseX); float scaledMouseY = toFixedCoord(mouseY); int screenWidth = getFixedScaledWidth(); int screenHeight = getFixedScaledHeight(); float totalWidth = 100 + 5 + 300; float totalHeight = 100 + 5 + 58; float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float startX = centerX - totalWidth / 2f; float startY = centerY - totalHeight / 2f; float rightPanelX = startX + 100 + 5; float rightPanelY = startY; if (accountRenderer.isMouseOver(scaledMouseX, scaledMouseY, rightPanelX, rightPanelY, 300, 165)) { float cardHeight = 40; float cardGap = 5; float accountListHeight = 165 - 31; int rows = (int) Math.ceil(accountConfig.getSortedAccounts().size() / 2.0); float maxScroll = Math.max(0, rows * (cardHeight + cardGap) - accountListHeight); targetScrollOffset -= (float) verticalAmount * 25; targetScrollOffset = MathHelper.clamp(targetScrollOffset, 0, maxScroll); float scrollSpeed = 12f; float deltaTime = 0.016f; float scrollDiff = targetScrollOffset - scrollOffset; scrollOffset += scrollDiff * Math.min(1f, deltaTime * scrollSpeed); return true; } return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); } @Override public boolean keyPressed(KeyInput input) { if (currentView == View.ALT_SCREEN) { if (nicknameFieldFocused) { int keyCode = input.key(); if (keyCode == 259) { if (!nicknameText.isEmpty()) { nicknameText = nicknameText.substring(0, nicknameText.length() - 1); } return true; } if (keyCode == 256) { nicknameFieldFocused = false; return true; } if (keyCode == 257 || keyCode == 335) { if (!nicknameText.isEmpty()) { addAccount(nicknameText); nicknameText = ""; } nicknameFieldFocused = false; return true; } } if (input.key() == 256) { currentView = View.MAIN_MENU; accountConfig.save(); return true; } } return super.keyPressed(input); } @Override public boolean charTyped(CharInput input) { if (currentView == View.ALT_SCREEN && nicknameFieldFocused) { int codepoint = input.codepoint(); if (Character.isLetterOrDigit(codepoint) || codepoint == '_') { if (nicknameText.length() < 16) { nicknameText += Character.toString(codepoint); } return true; } } return super.charTyped(input); } private void setActiveAccount(AccountEntry account) { accountConfig.setActiveAccount(account.getName(), account.getDate(), account.getSkin()); SessionChanger.changeUsername(account.getName()); } private void addAccount(String nickname) { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); String date = now.format(formatter); AccountEntry entry = new AccountEntry(nickname, date, null); accountConfig.addAccount(entry); setActiveAccount(entry); SessionChanger.changeUsername(nickname); } private String generateRandomNickname() { Random random = new Random(); StringBuilder username = new StringBuilder(); char[] vowels = {'a', 'e', 'i', 'o', 'u'}; char[] consonants = {'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'}; String finalUsername = null; int attempts = 0; final int MAX_ATTEMPTS = 10; List<AccountEntry> existingAccounts = accountConfig.getAccounts(); do { username.setLength(0); int length = 6 + random.nextInt(5); boolean startWithVowel = random.nextBoolean(); for (int i = 0; i < length; i++) { if (i % 2 == 0) { username.append(startWithVowel ? vowels[random.nextInt(vowels.length)] : consonants[random.nextInt(consonants.length)]); } else { username.append(startWithVowel ? consonants[random.nextInt(consonants.length)] : vowels[random.nextInt(vowels.length)]); } } if (random.nextInt(100) < 30) { username.append(random.nextInt(100)); } String tempUsername = username.substring(0, 1).toUpperCase() + username.substring(1); attempts++; boolean exists = false; for (AccountEntry account : existingAccounts) { if (account.getName().equalsIgnoreCase(tempUsername)) { exists = true; break; } } if (!exists) { finalUsername = tempUsername; break; } } while (attempts < MAX_ATTEMPTS); if (finalUsername == null) { finalUsername = username.substring(0, 1).toUpperCase() + username.substring(1) + (System.currentTimeMillis() % 1000); } return finalUsername; } @Override public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { drawBackground(); } @Override public boolean shouldCloseOnEsc() { return false; } @Override public boolean shouldPause() { return false; } private int withAlpha(int color, int alpha) { return (color & 0x00FFFFFF) | (MathHelper.clamp(alpha, 0, 255) << 24); } } }
Посмотреть вложение 327281
мое:Посмотреть вложение 327344
upd: добавил обводку
+repврод похоже хз
фонты думаю сами найдете
векса:код:package rich.screens.menu; import net.minecraft.client.gui.Click; 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.multiplayer.MultiplayerWarningScreen; import net.minecraft.client.gui.screen.option.OptionsScreen; import net.minecraft.client.gui.screen.world.SelectWorldScreen; import net.minecraft.client.input.KeyInput; import net.minecraft.client.input.CharInput; import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.Util; import net.minecraft.util.math.MathHelper; import rich.Initialization; import rich.screens.account.AccountEntry; import rich.screens.account.AccountRenderer; import rich.util.config.impl.account.AccountConfig; import rich.util.render.Render2D; import rich.util.render.font.Fonts; import rich.util.session.SessionChanger; import rich.util.sounds.SoundManager; import antidaunleak.api.UserProfile; import java.awt.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.List; import java.util.Random; public class MainMenuScreen extends Screen { private static final Identifier BACKGROUND_TEXTURE = Identifier.of("rich", "textures/menu/backmenu.png"); private static final float FIXED_GUI_SCALE = 2.0f; private static final int PARTICLE_COUNT = 50; private static final float PARTICLE_FADE_THRESHOLD = 0.8f; private static class Particle { float x, y; float vx, vy; float size; float alpha; float lifetime; float maxLifetime; boolean isDead = false; Particle(float x, float y) { this.x = x; this.y = y; Random rand = new Random(); this.vx = (rand.nextFloat() - 0.5f) * 0.2f; this.vy = (rand.nextFloat() - 0.5f) * 0.2f; this.size = 0.5f + rand.nextFloat() * 1f; this.alpha = 0.2f + rand.nextFloat() * 0.3f; this.maxLifetime = 10f + rand.nextFloat() * 10f; this.lifetime = 0f; } void update(float delta, int width, int height) { lifetime += delta / 60f; if (lifetime > maxLifetime * PARTICLE_FADE_THRESHOLD) { float fadeProgress = (lifetime - maxLifetime * PARTICLE_FADE_THRESHOLD) / (maxLifetime * (1f - PARTICLE_FADE_THRESHOLD)); alpha = Math.max(0, alpha * (1f - fadeProgress)); } if (lifetime >= maxLifetime) { isDead = true; return; } x += vx * delta; y += vy * delta; if (x < -10 || x > width + 10 || y < -10 || y > height + 10) { isDead = true; } } } private final List<Particle> particles = new java.util.ArrayList<>(); private boolean particlesInitialized = false; private int lastWindowWidth = 0; private int lastWindowHeight = 0; private enum View { MAIN_MENU, ALT_SCREEN } private View currentView = View.MAIN_MENU; private long screenStartTime = 0L; private boolean initialized = false; private long lastRenderTime = 0L; private int hoveredButton = -1; private float[] buttonHoverProgress = new float[6]; private final AccountRenderer accountRenderer; private final AccountConfig accountConfig; private String nicknameText = ""; private boolean nicknameFieldFocused = false; private float scrollOffset = 0f; private float targetScrollOffset = 0f; public MainMenuScreen() { super(Text.literal("Main Menu")); for (int i = 0; i < 6; i++) { buttonHoverProgress[i] = 0f; } this.accountRenderer = new AccountRenderer(); this.accountConfig = AccountConfig.getInstance(); this.accountConfig.load(); } @Override protected void init() { initialized = false; particlesInitialized = false; } private int getFixedScaledWidth() { return (int) Math.ceil((double) client.getWindow().getFramebufferWidth() / FIXED_GUI_SCALE); } private int getFixedScaledHeight() { return (int) Math.ceil((double) client.getWindow().getFramebufferHeight() / FIXED_GUI_SCALE); } private float toFixedCoord(double coord) { float currentScale = (float) client.getWindow().getScaleFactor(); return (float) (coord * currentScale / FIXED_GUI_SCALE); } private void initParticles(int width, int height) { if (particlesInitialized) return; Random rand = new Random(); for (int i = 0; i < PARTICLE_COUNT; i++) { particles.add(new Particle(rand.nextFloat() * width, rand.nextFloat() * height)); } particlesInitialized = true; } private void drawBackground() { int screenWidth = getFixedScaledWidth(); int screenHeight = getFixedScaledHeight(); Render2D.rect(0, 0, screenWidth, screenHeight, new Color(12, 15, 18).getRGB()); initParticles(screenWidth, screenHeight); for (Particle p : particles) { if (!p.isDead && p.alpha > 0.01f) { int alpha = (int) (p.alpha * 255); Render2D.rect(p.x, p.y, p.size, p.size, new Color(255, 255, 255, alpha).getRGB()); } } } @Override public void render(DrawContext context, int mouseX, int mouseY, float delta) { long currentTime = Util.getMeasuringTimeMs(); if (!initialized) { screenStartTime = currentTime; lastRenderTime = currentTime; initialized = true; } float deltaTime = Math.min(delta, 0.05f); lastRenderTime = currentTime; int fixedWidth = getFixedScaledWidth(); int fixedHeight = getFixedScaledHeight(); if (lastWindowWidth != fixedWidth || lastWindowHeight != fixedHeight) { particles.clear(); particlesInitialized = false; lastWindowWidth = fixedWidth; lastWindowHeight = fixedHeight; } for (Particle p : particles) { p.update(deltaTime * 60f, fixedWidth, fixedHeight); } particles.removeIf(p -> p.isDead); Random rand = new Random(); while (particles.size() < PARTICLE_COUNT) { particles.add(new Particle(rand.nextFloat() * fixedWidth, rand.nextFloat() * fixedHeight)); } float scaledMouseX = toFixedCoord(mouseX); float scaledMouseY = toFixedCoord(mouseY); updateButtonAnimations(deltaTime, scaledMouseX, scaledMouseY, fixedWidth, fixedHeight); Render2D.beginOverlay(); drawBackground(); if (currentView == View.MAIN_MENU) { renderMainMenu(fixedWidth, fixedHeight, scaledMouseX, scaledMouseY); } else { renderAltScreen(fixedWidth, fixedHeight, scaledMouseX, scaledMouseY, currentTime); } Render2D.endOverlay(); } private void renderMainMenu(int screenWidth, int screenHeight, float mouseX, float mouseY) { float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; String username = "user"; float avatarSize = 20; float avatarX = 8; float avatarY = 10; Fonts.INTER_MEDIUM.draw("Logged in as", avatarX + avatarSize + 5, avatarY, 7f, new Color(150, 150, 150).getRGB()); Fonts.INTER_MEDIUM.draw(username, avatarX + avatarSize + 5, avatarY + 9, 8f, new Color(255, 255, 255).getRGB()); Render2D.rect(avatarX, avatarY, avatarSize, avatarSize, new Color(40, 45, 55).getRGB(), avatarSize / 2f); Identifier userAvatar = Identifier.of("rich", "user.png"); int[] avatarColors = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; float[] avatarRadii = {avatarSize / 2f, avatarSize / 2f, avatarSize / 2f, avatarSize / 2f}; Initialization.getInstance().getManager().getRenderCore().getTexturePipeline() .drawTexture(userAvatar, avatarX, avatarY, avatarSize, avatarSize, 0, 0, 1, 1, avatarColors, avatarRadii, 1f); float logoSize = 35; float logoY = centerY - 90; Identifier logoTexture = Identifier.of("rich", "images/logo.png"); int[] logoColors = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; float[] logoRadii = {0, 0, 0, 0}; Initialization.getInstance().getManager().getRenderCore().getTexturePipeline() .drawTexture(logoTexture, centerX - logoSize / 2f, logoY, logoSize, logoSize, 0, 0, 1, 1, logoColors, logoRadii, 1f); String timeOfDay = getTimeOfDay(); String greeting = "Good " + timeOfDay + ", "; String usernameColored = username; float greetingWidth = Fonts.INTER_SEMIBOLD.getWidth(greeting, 14f); float usernameWidth = Fonts.INTER_SEMIBOLD.getWidth(usernameColored, 14f); float totalGreetingWidth = greetingWidth + usernameWidth; float greetingStartX = centerX - totalGreetingWidth / 2f; float greetingY = centerY - 38; Fonts.INTER_SEMIBOLD.draw(greeting, greetingStartX, greetingY, 14f, new Color(255, 255, 255).getRGB()); Fonts.INTER_SEMIBOLD.draw(usernameColored, greetingStartX + greetingWidth, greetingY, 14f, new Color(100, 180, 255).getRGB()); String welcomeText = "Welcome to "; String clientName = "WexSide. The best client."; String restText = ""; float welcomeWidth = Fonts.INTER_MEDIUM.getWidth(welcomeText, 9f); float clientWidth = Fonts.INTER_MEDIUM.getWidth(clientName, 9f); float restWidth = Fonts.INTER_MEDIUM.getWidth(restText, 9f); float totalWidth = welcomeWidth + clientWidth + restWidth; float startX = centerX - totalWidth / 2f; float textY = centerY - 20; Fonts.INTER_MEDIUM.draw(welcomeText, startX, textY, 9f, new Color(180, 180, 180).getRGB()); Fonts.INTER_SEMIBOLD.draw(clientName, startX + welcomeWidth, textY, 9f, new Color(90, 22, 134).getRGB()); Fonts.INTER_MEDIUM.draw(restText, startX + welcomeWidth + clientWidth, textY, 9f, new Color(180, 180, 180).getRGB()); float buttonWidth = 220; float buttonHeight = 30; float buttonSpacing = 7; float buttonStartY = centerY + 3; drawButton(centerX - buttonWidth / 2f, buttonStartY, buttonWidth, buttonHeight, "Singleplayer", 0, mouseX, mouseY, new Color(30, 35, 45), false); drawButton(centerX - buttonWidth / 2f, buttonStartY + buttonHeight + buttonSpacing, buttonWidth, buttonHeight, "Multiplayer", 1, mouseX, mouseY, new Color(30, 35, 45), false); float swapAccountsY = buttonStartY + (buttonHeight + buttonSpacing) * 2 + 5; drawButton(centerX - buttonWidth / 2f, swapAccountsY, buttonWidth, buttonHeight, "Swap Accounts", 2, mouseX, mouseY, new Color(90, 22, 134), true); float bottomY = swapAccountsY + buttonHeight + 5; float bottomButtonWidth = 65; float bottomButtonHeight = 20; float bottomSpacing = 10; float totalBottomWidth = bottomButtonWidth * 3 + bottomSpacing * 2; float bottomStartX = centerX - totalBottomWidth / 2f; drawSmallButton(bottomStartX, bottomY, bottomButtonWidth, bottomButtonHeight, "Options", 3, mouseX, mouseY); drawSmallButton(bottomStartX + bottomButtonWidth + bottomSpacing, bottomY, bottomButtonWidth, bottomButtonHeight, "Proxies", 4, mouseX, mouseY); drawSmallButton(bottomStartX + (bottomButtonWidth + bottomSpacing) * 2, bottomY, bottomButtonWidth, bottomButtonHeight, "Exit", 5, mouseX, mouseY); String footerText = "By logging into your account, you agree to all of our policies,"; String policyLinks = "including our Privacy Policy and Terms of Service"; Fonts.INTER_MEDIUM.drawCentered(footerText, centerX, screenHeight - 17, 6.5f, new Color(100, 100, 100).getRGB()); Fonts.INTER_MEDIUM.drawCentered(policyLinks, centerX, screenHeight - 8, 6.5f, new Color(100, 100, 100).getRGB()); } private String getTimeOfDay() { int hour = java.time.LocalTime.now().getHour(); if (hour >= 5 && hour < 12) return "morning"; if (hour >= 12 && hour < 17) return "afternoon"; if (hour >= 17 && hour < 21) return "evening"; return "night"; } private void drawButton(float x, float y, float width, float height, String text, int index, float mouseX, float mouseY, Color baseColor, boolean isPurple) { boolean hovered = isMouseOver(mouseX, mouseY, x, y, width, height); float hoverProgress = buttonHoverProgress[index]; Color bgColor = baseColor; if (isPurple) { int brightness = (int) (hoverProgress * 20); bgColor = new Color( Math.min(255, baseColor.getRed() + brightness), Math.min(255, baseColor.getGreen() + brightness), Math.min(255, baseColor.getBlue() + brightness) ); } else { int brightness = (int) (hoverProgress * 15); bgColor = new Color( Math.min(255, baseColor.getRed() + brightness), Math.min(255, baseColor.getGreen() + brightness), Math.min(255, baseColor.getBlue() + brightness) ); } Render2D.rect(x, y, width, height, bgColor.getRGB(), 8); if (!isPurple) { Render2D.outline(x, y, width, height, 1f, new Color(50, 55, 65, 80).getRGB(), 8); } if (hoverProgress > 0.01f) { int borderAlpha = (int) (hoverProgress * 100); Color borderColor = isPurple ? new Color(138, 43, 226, borderAlpha) : new Color(100, 110, 130, borderAlpha); Render2D.outline(x, y, width, height, 1f, borderColor.getRGB(), 8); } float fontSize = 9f; float textHeight = Fonts.INTER_MEDIUM.getHeight(fontSize); Color textColor = isPurple ? new Color(255, 255, 255) : new Color(160, 160, 160); Fonts.INTER_MEDIUM.drawCentered(text, x + width / 2f, y + (height - textHeight) / 2f, fontSize, textColor.getRGB()); } private void drawSmallButton(float x, float y, float width, float height, String text, int index, float mouseX, float mouseY) { float hoverProgress = buttonHoverProgress[index]; int baseAlpha = 150; int hoverAlpha = (int) (baseAlpha + hoverProgress * 50); float fontSize = 8f; float textHeight = Fonts.INTER_MEDIUM.getHeight(fontSize); Fonts.INTER_MEDIUM.drawCentered(text, x + width / 2f, y + (height - textHeight) / 2f, fontSize, new Color(180, 180, 180, hoverAlpha).getRGB()); } private boolean isMouseOver(float mouseX, float mouseY, float x, float y, float width, float height) { return mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height; } private void updateButtonAnimations(float deltaTime, float mouseX, float mouseY, int screenWidth, int screenHeight) { float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float lerpSpeed = 1f - (float) Math.pow(0.001f, deltaTime); if (currentView == View.MAIN_MENU) { float buttonWidth = 220; float buttonHeight = 30; float buttonSpacing = 7; float buttonStartY = centerY + 3; for (int i = 0; i < 2; i++) { float y = buttonStartY + i * (buttonHeight + buttonSpacing); boolean hovered = isMouseOver(mouseX, mouseY, centerX - buttonWidth / 2f, y, buttonWidth, buttonHeight); float target = hovered ? 1f : 0f; buttonHoverProgress[i] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[i], target); } float swapAccountsY = buttonStartY + (buttonHeight + buttonSpacing) * 2 + 5; boolean swapHovered = isMouseOver(mouseX, mouseY, centerX - buttonWidth / 2f, swapAccountsY, buttonWidth, buttonHeight); buttonHoverProgress[2] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[2], swapHovered ? 1f : 0f); float bottomY = swapAccountsY + buttonHeight + 5; float bottomButtonWidth = 65; float bottomButtonHeight = 20; float bottomSpacing = 10; float totalBottomWidth = bottomButtonWidth * 3 + bottomSpacing * 2; float bottomStartX = centerX - totalBottomWidth / 2f; for (int i = 0; i < 3; i++) { float x = bottomStartX + i * (bottomButtonWidth + bottomSpacing); boolean hovered = isMouseOver(mouseX, mouseY, x, bottomY, bottomButtonWidth, bottomButtonHeight); float target = hovered ? 1f : 0f; buttonHoverProgress[i + 3] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[i + 3], target); } } else { for (int i = 0; i < 6; i++) { buttonHoverProgress[i] = MathHelper.lerp(lerpSpeed, buttonHoverProgress[i], 0f); } } } private void renderAltScreen(int screenWidth, int screenHeight, float mouseX, float mouseY, long currentTime) { float totalWidth = 405; float totalHeight = 163; float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float startX = centerX - totalWidth / 2f; float startY = centerY - totalHeight / 2f; float leftPanelX = startX; float leftPanelTopY = startY; accountRenderer.renderLeftPanelTop(leftPanelX, leftPanelTopY, 100, 100, 1f, nicknameText, nicknameFieldFocused, mouseX, mouseY, currentTime); float leftPanelBottomY = startY + 100 + 5; accountRenderer.renderLeftPanelBottom(leftPanelX, leftPanelBottomY, 100, 58, 1f, accountConfig.getActiveAccountName(), accountConfig.getActiveAccountDate(), accountConfig.getActiveAccountSkin()); float rightPanelX = startX + 100 + 5; float rightPanelY = startY; List<AccountEntry> sortedAccounts = accountConfig.getSortedAccounts(); accountRenderer.renderRightPanel(rightPanelX, rightPanelY, 300, 165, 1f, sortedAccounts, scrollOffset, mouseX, mouseY, 1f, (int) FIXED_GUI_SCALE); } @Override public boolean mouseClicked(Click click, boolean doubled) { float scaledMouseX = toFixedCoord(click.x()); float scaledMouseY = toFixedCoord(click.y()); if (currentView == View.MAIN_MENU) { if (click.button() == 0) { int fixedWidth = getFixedScaledWidth(); int fixedHeight = getFixedScaledHeight(); float centerX = fixedWidth / 2f; float centerY = fixedHeight / 2f; float buttonWidth = 220; float buttonHeight = 30; float buttonSpacing = 7; float buttonStartY = centerY + 3; for (int i = 0; i < 2; i++) { float y = buttonStartY + i * (buttonHeight + buttonSpacing); if (isMouseOver(scaledMouseX, scaledMouseY, centerX - buttonWidth / 2f, y, buttonWidth, buttonHeight)) { handleMainMenuButtonClick(i); return true; } } float swapAccountsY = buttonStartY + (buttonHeight + buttonSpacing) * 2 + 5; if (isMouseOver(scaledMouseX, scaledMouseY, centerX - buttonWidth / 2f, swapAccountsY, buttonWidth, buttonHeight)) { handleMainMenuButtonClick(2); return true; } float bottomY = swapAccountsY + buttonHeight + 5; float bottomButtonWidth = 65; float bottomButtonHeight = 20; float bottomSpacing = 10; float totalBottomWidth = bottomButtonWidth * 3 + bottomSpacing * 2; float bottomStartX = centerX - totalBottomWidth / 2f; for (int i = 0; i < 3; i++) { float x = bottomStartX + i * (bottomButtonWidth + bottomSpacing); if (isMouseOver(scaledMouseX, scaledMouseY, x, bottomY, bottomButtonWidth, bottomButtonHeight)) { handleMainMenuButtonClick(i + 3); return true; } } } } else if (currentView == View.ALT_SCREEN) { return handleAltScreenClick(scaledMouseX, scaledMouseY, click); } return super.mouseClicked(click, doubled); } private void handleMainMenuButtonClick(int index) { switch (index) { case 0 -> this.client.setScreen(new SelectWorldScreen(this)); case 1 -> { Screen screen = this.client.options.skipMultiplayerWarning ? new MultiplayerScreen(this) : new MultiplayerWarningScreen(this); this.client.setScreen(screen); } case 2 -> currentView = View.ALT_SCREEN; case 3 -> this.client.setScreen(new OptionsScreen(this, this.client.options)); case 4 -> {} case 5 -> this.client.scheduleStop(); } } private boolean handleAltScreenClick(float mouseX, float mouseY, Click click) { int screenWidth = getFixedScaledWidth(); int screenHeight = getFixedScaledHeight(); float totalWidth = 100 + 5 + 300; float totalHeight = 100 + 5 + 58; float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float startX = centerX - totalWidth / 2f; float startY = centerY - totalHeight / 2f; float leftPanelX = startX; float leftPanelTopY = startY; float fieldX = leftPanelX + 5; float fieldY = leftPanelTopY + 38; float fieldHeight = 14; float addButtonSize = 14; float buttonGap = 3; float fieldWidth = 100 - 10 - addButtonSize - buttonGap; if (accountRenderer.isMouseOver(mouseX, mouseY, fieldX, fieldY, fieldWidth, fieldHeight)) { nicknameFieldFocused = true; return true; } else { nicknameFieldFocused = false; } float addButtonX = fieldX + fieldWidth + buttonGap; float addButtonY = fieldY; if (accountRenderer.isMouseOver(mouseX, mouseY, addButtonX, addButtonY, addButtonSize, addButtonSize)) { if (!nicknameText.isEmpty()) { addAccount(nicknameText); nicknameText = ""; } return true; } float buttonWidth = 100 - 10; float buttonHeight = 16; float randomButtonX = leftPanelX + 5; float randomButtonY = fieldY + fieldHeight + 6; if (accountRenderer.isMouseOver(mouseX, mouseY, randomButtonX, randomButtonY, buttonWidth, buttonHeight)) { String randomNick = generateRandomNickname(); addAccount(randomNick); nicknameText = ""; return true; } float clearButtonX = leftPanelX + 5; float clearButtonY = randomButtonY + buttonHeight + 5; if (accountRenderer.isMouseOver(mouseX, mouseY, clearButtonX, clearButtonY, buttonWidth, buttonHeight)) { accountConfig.clearAllAccounts(); targetScrollOffset = 0f; scrollOffset = 0f; return true; } float rightPanelX = startX + 100 + 5; float rightPanelY = startY; float accountListX = rightPanelX + 5; float accountListY = rightPanelY + 26; float accountListWidth = 300 - 10; float accountListHeight = 165 - 31; if (!accountRenderer.isMouseOver(mouseX, mouseY, accountListX, accountListY, accountListWidth, accountListHeight)) { return false; } float cardWidth = (accountListWidth - 5) / 2f; float cardHeight = 40; float cardGap = 5; List<AccountEntry> sortedAccounts = accountConfig.getSortedAccounts(); for (int i = 0; i < sortedAccounts.size(); i++) { int col = i % 2; int row = i / 2; float cardX = accountListX + col * (cardWidth + cardGap); float cardY = accountListY + row * (cardHeight + cardGap) - scrollOffset; if (cardY + cardHeight < accountListY || cardY > accountListY + accountListHeight) { continue; } float btnSize = 12; float buttonYPos = cardY + cardHeight - btnSize - 5; float pinButtonX = cardX + cardWidth - btnSize * 2 - 8; float deleteButtonX = cardX + cardWidth - btnSize - 5; if (accountRenderer.isMouseOver(mouseX, mouseY, pinButtonX, buttonYPos, btnSize, btnSize)) { AccountEntry entry = sortedAccounts.get(i); entry.togglePinned(); if (entry.isPinned()) { setActiveAccount(entry); } accountConfig.save(); return true; } if (accountRenderer.isMouseOver(mouseX, mouseY, deleteButtonX, buttonYPos, btnSize, btnSize)) { accountConfig.removeAccountByIndex(i); return true; } if (accountRenderer.isMouseOver(mouseX, mouseY, cardX, cardY, cardWidth, cardHeight)) { setActiveAccount(sortedAccounts.get(i)); return true; } } return false; } @Override public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) { if (currentView != View.ALT_SCREEN) return false; float scaledMouseX = toFixedCoord(mouseX); float scaledMouseY = toFixedCoord(mouseY); int screenWidth = getFixedScaledWidth(); int screenHeight = getFixedScaledHeight(); float totalWidth = 100 + 5 + 300; float totalHeight = 100 + 5 + 58; float centerX = screenWidth / 2f; float centerY = screenHeight / 2f; float startX = centerX - totalWidth / 2f; float startY = centerY - totalHeight / 2f; float rightPanelX = startX + 100 + 5; float rightPanelY = startY; if (accountRenderer.isMouseOver(scaledMouseX, scaledMouseY, rightPanelX, rightPanelY, 300, 165)) { float cardHeight = 40; float cardGap = 5; float accountListHeight = 165 - 31; int rows = (int) Math.ceil(accountConfig.getSortedAccounts().size() / 2.0); float maxScroll = Math.max(0, rows * (cardHeight + cardGap) - accountListHeight); targetScrollOffset -= (float) verticalAmount * 25; targetScrollOffset = MathHelper.clamp(targetScrollOffset, 0, maxScroll); float scrollSpeed = 12f; float deltaTime = 0.016f; float scrollDiff = targetScrollOffset - scrollOffset; scrollOffset += scrollDiff * Math.min(1f, deltaTime * scrollSpeed); return true; } return super.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount); } @Override public boolean keyPressed(KeyInput input) { if (currentView == View.ALT_SCREEN) { if (nicknameFieldFocused) { int keyCode = input.key(); if (keyCode == 259) { if (!nicknameText.isEmpty()) { nicknameText = nicknameText.substring(0, nicknameText.length() - 1); } return true; } if (keyCode == 256) { nicknameFieldFocused = false; return true; } if (keyCode == 257 || keyCode == 335) { if (!nicknameText.isEmpty()) { addAccount(nicknameText); nicknameText = ""; } nicknameFieldFocused = false; return true; } } if (input.key() == 256) { currentView = View.MAIN_MENU; accountConfig.save(); return true; } } return super.keyPressed(input); } @Override public boolean charTyped(CharInput input) { if (currentView == View.ALT_SCREEN && nicknameFieldFocused) { int codepoint = input.codepoint(); if (Character.isLetterOrDigit(codepoint) || codepoint == '_') { if (nicknameText.length() < 16) { nicknameText += Character.toString(codepoint); } return true; } } return super.charTyped(input); } private void setActiveAccount(AccountEntry account) { accountConfig.setActiveAccount(account.getName(), account.getDate(), account.getSkin()); SessionChanger.changeUsername(account.getName()); } private void addAccount(String nickname) { LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); String date = now.format(formatter); AccountEntry entry = new AccountEntry(nickname, date, null); accountConfig.addAccount(entry); setActiveAccount(entry); SessionChanger.changeUsername(nickname); } private String generateRandomNickname() { Random random = new Random(); StringBuilder username = new StringBuilder(); char[] vowels = {'a', 'e', 'i', 'o', 'u'}; char[] consonants = {'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'}; String finalUsername = null; int attempts = 0; final int MAX_ATTEMPTS = 10; List<AccountEntry> existingAccounts = accountConfig.getAccounts(); do { username.setLength(0); int length = 6 + random.nextInt(5); boolean startWithVowel = random.nextBoolean(); for (int i = 0; i < length; i++) { if (i % 2 == 0) { username.append(startWithVowel ? vowels[random.nextInt(vowels.length)] : consonants[random.nextInt(consonants.length)]); } else { username.append(startWithVowel ? consonants[random.nextInt(consonants.length)] : vowels[random.nextInt(vowels.length)]); } } if (random.nextInt(100) < 30) { username.append(random.nextInt(100)); } String tempUsername = username.substring(0, 1).toUpperCase() + username.substring(1); attempts++; boolean exists = false; for (AccountEntry account : existingAccounts) { if (account.getName().equalsIgnoreCase(tempUsername)) { exists = true; break; } } if (!exists) { finalUsername = tempUsername; break; } } while (attempts < MAX_ATTEMPTS); if (finalUsername == null) { finalUsername = username.substring(0, 1).toUpperCase() + username.substring(1) + (System.currentTimeMillis() % 1000); } return finalUsername; } @Override public void renderBackground(DrawContext context, int mouseX, int mouseY, float delta) { drawBackground(); } @Override public boolean shouldCloseOnEsc() { return false; } @Override public boolean shouldPause() { return false; } private int withAlpha(int color, int alpha) { return (color & 0x00FFFFFF) | (MathHelper.clamp(alpha, 0, 255) << 24); } } }
Посмотреть вложение 327281
мое:Посмотреть вложение 327344
upd: добавил обводку
где найти именно етот фонтПожалуйста, авторизуйтесь для просмотра ссылки.и потом https://yougame.biz/threads/362210/
Проект предоставляет различный материал, относящийся к сфере киберспорта, программирования, ПО для игр, а также позволяет его участникам общаться на многие другие темы. Почта для жалоб: admin@yougame.biz