WinScreen.java

net.minecraft.client.gui.screens.WinScreen

信息

  • 全限定名:net.minecraft.client.gui.screens.WinScreen
  • 类型:public class
  • 包:net.minecraft.client.gui.screens
  • 源码路径:src/main/java/net/minecraft/client/gui/screens/WinScreen.java
  • 起始行号:L39
  • 继承:Screen
  • 职责:

    TODO

字段/常量

  • VIGNETTE_LOCATION

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L40
    • 说明:

      TODO

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L41
    • 说明:

      TODO

  • SECTION_HEADING

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L42
    • 说明:

      TODO

  • NAME_PREFIX

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L43
    • 说明:

      TODO

  • OBFUSCATE_TOKEN

    • 类型: String
    • 修饰符: private static final
    • 源码定位: L44
    • 说明:

      TODO

  • SPEEDUP_FACTOR

    • 类型: float
    • 修饰符: private static final
    • 源码定位: L45
    • 说明:

      TODO

  • SPEEDUP_FACTOR_FAST

    • 类型: float
    • 修饰符: private static final
    • 源码定位: L46
    • 说明:

      TODO

  • END_POEM_LOCATION

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L47
    • 说明:

      TODO

  • CREDITS_LOCATION

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L48
    • 说明:

      TODO

  • POSTCREDITS_LOCATION

    • 类型: Identifier
    • 修饰符: private static final
    • 源码定位: L49
    • 说明:

      TODO

  • poem

    • 类型: boolean
    • 修饰符: private final
    • 源码定位: L50
    • 说明:

      TODO

  • onFinished

    • 类型: Runnable
    • 修饰符: private final
    • 源码定位: L51
    • 说明:

      TODO

  • scroll

    • 类型: float
    • 修饰符: private
    • 源码定位: L52
    • 说明:

      TODO

  • lines

    • 类型: List<FormattedCharSequence>
    • 修饰符: private
    • 源码定位: L53
    • 说明:

      TODO

  • narratorComponents

    • 类型: List<Component>
    • 修饰符: private
    • 源码定位: L54
    • 说明:

      TODO

  • centeredLines

    • 类型: IntSet
    • 修饰符: private
    • 源码定位: L55
    • 说明:

      TODO

  • totalScrollLength

    • 类型: int
    • 修饰符: private
    • 源码定位: L56
    • 说明:

      TODO

  • speedupActive

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L57
    • 说明:

      TODO

  • speedupModifiers

    • 类型: IntSet
    • 修饰符: private final
    • 源码定位: L58
    • 说明:

      TODO

  • scrollSpeed

    • 类型: float
    • 修饰符: private
    • 源码定位: L59
    • 说明:

      TODO

  • unmodifiedScrollSpeed

    • 类型: float
    • 修饰符: private final
    • 源码定位: L60
    • 说明:

      TODO

  • direction

    • 类型: int
    • 修饰符: private
    • 源码定位: L61
    • 说明:

      TODO

  • logoRenderer

    • 类型: LogoRenderer
    • 修饰符: private final
    • 源码定位: L62
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.gui.screens.WinScreen.CreditsReader
    • 类型: interface
    • 修饰符: private
    • 源码定位: L332
    • 说明:

      TODO

构造器

public WinScreen(boolean poem, Runnable onFinished) @ L64

  • 构造器名:WinScreen
  • 源码定位:L64
  • 修饰符:public

参数:

  • poem: boolean
  • onFinished: Runnable

说明:

TODO

方法

下面的方法块按源码顺序生成。

private float calculateScrollSpeed() @ L78

  • 方法名:calculateScrollSpeed
  • 源码定位:L78
  • 返回类型:float
  • 修饰符:private

参数:

说明:

TODO

public void tick() @ L84

  • 方法名:tick
  • 源码定位:L84
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public boolean keyPressed(KeyEvent event) @ L94

  • 方法名:keyPressed
  • 源码定位:L94
  • 返回类型:boolean
  • 修饰符:public

参数:

  • event: KeyEvent

说明:

TODO

public boolean keyReleased(KeyEvent event) @ L108

  • 方法名:keyReleased
  • 源码定位:L108
  • 返回类型:boolean
  • 修饰符:public

参数:

  • event: KeyEvent

说明:

TODO

public void onClose() @ L124

  • 方法名:onClose
  • 源码定位:L124
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

private void respawn() @ L129

  • 方法名:respawn
  • 源码定位:L129
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

protected void init() @ L133

  • 方法名:init
  • 源码定位:L133
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

public Component getNarrationMessage() @ L152

  • 方法名:getNarrationMessage
  • 源码定位:L152
  • 返回类型:Component
  • 修饰符:public

参数:

说明:

TODO

private void wrapCreditsIO(Identifier file, WinScreen.CreditsReader creditsReader) @ L157

  • 方法名:wrapCreditsIO
  • 源码定位:L157
  • 返回类型:void
  • 修饰符:private

参数:

  • file: Identifier
  • creditsReader: WinScreen.CreditsReader

说明:

TODO

private void addPoemFile(Reader inputReader) @ L165

  • 方法名:addPoemFile
  • 源码定位:L165
  • 返回类型:void
  • 修饰符:private

参数:

  • inputReader: Reader

说明:

TODO

private void addCreditsFile(Reader inputReader) @ L189

  • 方法名:addCreditsFile
  • 源码定位:L189
  • 返回类型:void
  • 修饰符:private

参数:

  • inputReader: Reader

说明:

TODO

private void addEmptyLine() @ L226

  • 方法名:addEmptyLine
  • 源码定位:L226
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

private void addPoemLines(String line) @ L231

  • 方法名:addPoemLines
  • 源码定位:L231
  • 返回类型:void
  • 修饰符:private

参数:

  • line: String

说明:

TODO

private void addCreditsLine(Component line, boolean centered, boolean narrated) @ L237

  • 方法名:addCreditsLine
  • 源码定位:L237
  • 返回类型:void
  • 修饰符:private

参数:

  • line: Component
  • centered: boolean
  • narrated: boolean

说明:

TODO

public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) @ L248

  • 方法名:extractRenderState
  • 源码定位:L248
  • 返回类型:void
  • 修饰符:public

参数:

  • graphics: GuiGraphicsExtractor
  • mouseX: int
  • mouseY: int
  • a: float

说明:

TODO

private void extractVignette(GuiGraphicsExtractor graphics) @ L285

  • 方法名:extractVignette
  • 源码定位:L285
  • 返回类型:void
  • 修饰符:private

参数:

  • graphics: GuiGraphicsExtractor

说明:

TODO

public void extractBackground(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) @ L289

  • 方法名:extractBackground
  • 源码定位:L289
  • 返回类型:void
  • 修饰符:public

参数:

  • graphics: GuiGraphicsExtractor
  • mouseX: int
  • mouseY: int
  • a: float

说明:

TODO

protected void extractMenuBackground(GuiGraphicsExtractor graphics, int x, int y, int width, int height) @ L304

  • 方法名:extractMenuBackground
  • 源码定位:L304
  • 返回类型:void
  • 修饰符:protected

参数:

  • graphics: GuiGraphicsExtractor
  • x: int
  • y: int
  • width: int
  • height: int

说明:

TODO

public boolean isPauseScreen() @ L310

  • 方法名:isPauseScreen
  • 源码定位:L310
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public boolean isAllowedInPortal() @ L315

  • 方法名:isAllowedInPortal
  • 源码定位:L315
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public void removed() @ L320

  • 方法名:removed
  • 源码定位:L320
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public Music getBackgroundMusic() @ L325

  • 方法名:getBackgroundMusic
  • 源码定位:L325
  • 返回类型:Music
  • 修饰符:public

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class WinScreen extends Screen {
    private static final Identifier VIGNETTE_LOCATION = Identifier.withDefaultNamespace("textures/misc/credits_vignette.png");
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final Component SECTION_HEADING = Component.literal("============").withStyle(ChatFormatting.WHITE);
    private static final String NAME_PREFIX = "           ";
    private static final String OBFUSCATE_TOKEN = "" + ChatFormatting.WHITE + ChatFormatting.OBFUSCATED + ChatFormatting.GREEN + ChatFormatting.AQUA;
    private static final float SPEEDUP_FACTOR = 5.0F;
    private static final float SPEEDUP_FACTOR_FAST = 15.0F;
    private static final Identifier END_POEM_LOCATION = Identifier.withDefaultNamespace("texts/end.txt");
    private static final Identifier CREDITS_LOCATION = Identifier.withDefaultNamespace("texts/credits.json");
    private static final Identifier POSTCREDITS_LOCATION = Identifier.withDefaultNamespace("texts/postcredits.txt");
    private final boolean poem;
    private final Runnable onFinished;
    private float scroll;
    private List<FormattedCharSequence> lines;
    private List<Component> narratorComponents;
    private IntSet centeredLines;
    private int totalScrollLength;
    private boolean speedupActive;
    private final IntSet speedupModifiers = new IntOpenHashSet();
    private float scrollSpeed;
    private final float unmodifiedScrollSpeed;
    private int direction;
    private final LogoRenderer logoRenderer = new LogoRenderer(false);
 
    public WinScreen(boolean poem, Runnable onFinished) {
        super(GameNarrator.NO_TITLE);
        this.poem = poem;
        this.onFinished = onFinished;
        if (!poem) {
            this.unmodifiedScrollSpeed = 0.75F;
        } else {
            this.unmodifiedScrollSpeed = 0.5F;
        }
 
        this.direction = 1;
        this.scrollSpeed = this.unmodifiedScrollSpeed;
    }
 
    private float calculateScrollSpeed() {
        return this.speedupActive
            ? this.unmodifiedScrollSpeed * (5.0F + this.speedupModifiers.size() * 15.0F) * this.direction
            : this.unmodifiedScrollSpeed * this.direction;
    }
 
    @Override
    public void tick() {
        this.minecraft.getMusicManager().tick();
        this.minecraft.getSoundManager().tick(false);
        float maxScroll = this.totalScrollLength + this.height + this.height + 24;
        if (this.scroll > maxScroll) {
            this.respawn();
        }
    }
 
    @Override
    public boolean keyPressed(KeyEvent event) {
        if (event.isUp()) {
            this.direction = -1;
        } else if (event.key() == 341 || event.key() == 345) {
            this.speedupModifiers.add(event.key());
        } else if (event.key() == 32) {
            this.speedupActive = true;
        }
 
        this.scrollSpeed = this.calculateScrollSpeed();
        return super.keyPressed(event);
    }
 
    @Override
    public boolean keyReleased(KeyEvent event) {
        if (event.isUp()) {
            this.direction = 1;
        }
 
        if (event.key() == 32) {
            this.speedupActive = false;
        } else if (event.key() == 341 || event.key() == 345) {
            this.speedupModifiers.remove(event.key());
        }
 
        this.scrollSpeed = this.calculateScrollSpeed();
        return super.keyReleased(event);
    }
 
    @Override
    public void onClose() {
        this.respawn();
    }
 
    private void respawn() {
        this.onFinished.run();
    }
 
    @Override
    protected void init() {
        if (this.lines == null) {
            this.lines = Lists.newArrayList();
            this.narratorComponents = Lists.newArrayList();
            this.centeredLines = new IntOpenHashSet();
            if (this.poem) {
                this.wrapCreditsIO(END_POEM_LOCATION, this::addPoemFile);
            }
 
            this.wrapCreditsIO(CREDITS_LOCATION, this::addCreditsFile);
            if (this.poem) {
                this.wrapCreditsIO(POSTCREDITS_LOCATION, this::addPoemFile);
            }
 
            this.totalScrollLength = this.lines.size() * 12;
        }
    }
 
    @Override
    public Component getNarrationMessage() {
        return CommonComponents.joinForNarration(this.narratorComponents.toArray(Component[]::new));
    }
 
    private void wrapCreditsIO(Identifier file, WinScreen.CreditsReader creditsReader) {
        try (Reader resource = this.minecraft.getResourceManager().openAsReader(file)) {
            creditsReader.read(resource);
        } catch (Exception var8) {
            LOGGER.error("Couldn't load credits from file {}", file, var8);
        }
    }
 
    private void addPoemFile(Reader inputReader) throws IOException {
        BufferedReader reader = new BufferedReader(inputReader);
        RandomSource random = RandomSource.createThreadLocalInstance(8124371L);
 
        String line;
        while ((line = reader.readLine()) != null) {
            line = line.replaceAll("PLAYERNAME", this.minecraft.getUser().getName());
 
            int pos;
            while ((pos = line.indexOf(OBFUSCATE_TOKEN)) != -1) {
                String before = line.substring(0, pos);
                String after = line.substring(pos + OBFUSCATE_TOKEN.length());
                line = before + ChatFormatting.WHITE + ChatFormatting.OBFUSCATED + "XXXXXXXX".substring(0, random.nextInt(4) + 3) + after;
            }
 
            this.addPoemLines(line);
            this.addEmptyLine();
        }
 
        for (int i = 0; i < 8; i++) {
            this.addEmptyLine();
        }
    }
 
    private void addCreditsFile(Reader inputReader) {
        for (JsonElement sectionElement : GsonHelper.parseArray(inputReader)) {
            JsonObject section = sectionElement.getAsJsonObject();
            String sectionName = section.get("section").getAsString();
            this.addCreditsLine(SECTION_HEADING, true, false);
            this.addCreditsLine(Component.literal(sectionName).withStyle(ChatFormatting.YELLOW), true, true);
            this.addCreditsLine(SECTION_HEADING, true, false);
            this.addEmptyLine();
            this.addEmptyLine();
 
            for (JsonElement disciplineElement : section.getAsJsonArray("disciplines")) {
                JsonObject discipline = disciplineElement.getAsJsonObject();
                String disciplineName = discipline.get("discipline").getAsString();
                if (StringUtils.isNotEmpty(disciplineName)) {
                    this.addCreditsLine(Component.literal(disciplineName).withStyle(ChatFormatting.YELLOW), true, true);
                    this.addEmptyLine();
                    this.addEmptyLine();
                }
 
                for (JsonElement titleElement : discipline.getAsJsonArray("titles")) {
                    JsonObject title = titleElement.getAsJsonObject();
                    String titleName = title.get("title").getAsString();
                    JsonArray names = title.getAsJsonArray("names");
                    this.addCreditsLine(Component.literal(titleName).withStyle(ChatFormatting.GRAY), false, true);
 
                    for (JsonElement nameElement : names) {
                        String name = nameElement.getAsString();
                        this.addCreditsLine(Component.literal("           ").append(name).withStyle(ChatFormatting.WHITE), false, true);
                    }
 
                    this.addEmptyLine();
                    this.addEmptyLine();
                }
            }
        }
    }
 
    private void addEmptyLine() {
        this.lines.add(FormattedCharSequence.EMPTY);
        this.narratorComponents.add(CommonComponents.EMPTY);
    }
 
    private void addPoemLines(String line) {
        Component component = Component.literal(line);
        this.lines.addAll(this.minecraft.font.split(component, 256));
        this.narratorComponents.add(component);
    }
 
    private void addCreditsLine(Component line, boolean centered, boolean narrated) {
        if (centered) {
            this.centeredLines.add(this.lines.size());
        }
 
        this.lines.add(line.getVisualOrderText());
        if (narrated) {
            this.narratorComponents.add(line);
        }
    }
 
    @Override
    public void extractRenderState(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) {
        super.extractRenderState(graphics, mouseX, mouseY, a);
        this.extractVignette(graphics);
        this.scroll = Math.max(0.0F, this.scroll + a * this.scrollSpeed);
        int logoX = this.width / 2 - 128;
        int logoY = this.height + 50;
        float yOffs = -this.scroll;
        graphics.pose().pushMatrix();
        graphics.pose().translate(0.0F, yOffs);
        graphics.nextStratum();
        this.logoRenderer.extractRenderState(graphics, this.width, 1.0F, logoY);
        int yPos = logoY + 100;
 
        for (int i = 0; i < this.lines.size(); i++) {
            if (i == this.lines.size() - 1) {
                float diff = yPos + yOffs - (this.height / 2 - 6);
                if (diff < 0.0F) {
                    graphics.pose().translate(0.0F, -diff);
                }
            }
 
            if (yPos + yOffs + 12.0F + 8.0F > 0.0F && yPos + yOffs < this.height) {
                FormattedCharSequence line = this.lines.get(i);
                if (this.centeredLines.contains(i)) {
                    graphics.centeredText(this.font, line, logoX + 128, yPos, -1);
                } else {
                    graphics.text(this.font, line, logoX, yPos, -1);
                }
            }
 
            yPos += 12;
        }
 
        graphics.pose().popMatrix();
    }
 
    private void extractVignette(GuiGraphicsExtractor graphics) {
        graphics.blit(RenderPipelines.VIGNETTE, VIGNETTE_LOCATION, 0, 0, 0.0F, 0.0F, this.width, this.height, this.width, this.height);
    }
 
    @Override
    public void extractBackground(GuiGraphicsExtractor graphics, int mouseX, int mouseY, float a) {
        if (this.poem) {
            TextureManager textureManager = Minecraft.getInstance().getTextureManager();
            AbstractTexture skyTexture = textureManager.getTexture(AbstractEndPortalRenderer.END_SKY_LOCATION);
            AbstractTexture portalTexture = textureManager.getTexture(AbstractEndPortalRenderer.END_PORTAL_LOCATION);
            TextureSetup textureSetup = TextureSetup.doubleTexture(
                skyTexture.getTextureView(), skyTexture.getSampler(), portalTexture.getTextureView(), portalTexture.getSampler()
            );
            graphics.fill(RenderPipelines.END_PORTAL, textureSetup, 0, 0, this.width, this.height);
        } else {
            super.extractBackground(graphics, mouseX, mouseY, a);
        }
    }
 
    @Override
    protected void extractMenuBackground(GuiGraphicsExtractor graphics, int x, int y, int width, int height) {
        float v = this.scroll * 0.5F;
        Screen.extractMenuBackgroundTexture(graphics, Screen.MENU_BACKGROUND, 0, 0, 0.0F, v, width, height);
    }
 
    @Override
    public boolean isPauseScreen() {
        return !this.poem;
    }
 
    @Override
    public boolean isAllowedInPortal() {
        return true;
    }
 
    @Override
    public void removed() {
        this.minecraft.getMusicManager().stopPlaying(Musics.CREDITS);
    }
 
    @Override
    public Music getBackgroundMusic() {
        return Musics.CREDITS;
    }
 
    @FunctionalInterface
    @OnlyIn(Dist.CLIENT)
    private interface CreditsReader {
        void read(final Reader reader) throws IOException;
    }
}

引用的其他类

  • Minecraft

    • 引用位置: 方法调用
    • 关联成员: Minecraft.getInstance()
  • GuiGraphicsExtractor

    • 引用位置: 参数
  • LogoRenderer

    • 引用位置: 字段/构造调用
    • 关联成员: LogoRenderer()
  • TextureSetup

    • 引用位置: 方法调用
    • 关联成员: TextureSetup.doubleTexture()
  • Screen

    • 引用位置: 方法调用/继承
    • 关联成员: Screen.extractMenuBackgroundTexture()
  • KeyEvent

    • 引用位置: 参数
  • CommonComponents

    • 引用位置: 方法调用
    • 关联成员: CommonComponents.joinForNarration()
  • Component

    • 引用位置: 参数/字段/方法调用/返回值
    • 关联成员: Component.literal()
  • ClientboundPlayerInfoUpdatePacket

    • 引用位置: 参数
  • Identifier

    • 引用位置: 参数/字段/方法调用
    • 关联成员: Identifier.withDefaultNamespace()
  • Music

    • 引用位置: 返回值
  • FormattedCharSequence

    • 引用位置: 字段
  • GsonHelper

    • 引用位置: 方法调用
    • 关联成员: GsonHelper.parseArray()
  • RandomSource

    • 引用位置: 方法调用
    • 关联成员: RandomSource.createThreadLocalInstance()