zoukankan      html  css  js  c++  java
  • Minecraft 1.12.2 Mod开发笔记——新的GUI(待完成)/HUD

    总目录:Minecraft 1.12.2 Mod开发笔记

    目录

    新的GUI(施工中...)

    从 Gui 类的继承关系上,大概就是下面这样:

    Gui
    |- GuiButton 等小组件
    |- HUD 组件
    |- GuiScreen 
        |- GuiCreateWorld 等几乎所有游戏界面
        |- GuiContainer 
            |- GuiChest 等各种带有物品栏的东西,也就是游戏内弹出的各种用于交互的游戏GUI
    

    新的GUI

    ustc-zzzz的教程 里已经很详细了,这里就简单总结一下。

    Minecraft的GUI大概分为

    • 显示层,如GuiScreen/GuiContainer的子类,用于显示
    • 逻辑处理,Container类,负责逻辑处理
    • 物品槽,slot,对应着显示层中的一个物品槽
    • 管理类,IGuiHandler接口,负责协调调用

    在界面中添加各种东西

    • 重写GuiContainer.drawGuiContainerBackgroundLayer()用于画背景图
    • 重写GuiContainer.initGui()方法用于初始化各种界面组件
    • 重写GuiContainer.drawGuiContainerForegroundLayer()用于画文字、物品等
    • 在Container构造器中使用addSlotToContainer()添加物品槽

    GuiButton

    最常见的按钮,GuiContainer里使用一个buttonList来管理所有的按钮。添加一个按钮:

    this.buttonList.add(new GuiButton(0, 0, 0, "my button"));
    

    参数分别为按钮ID、坐标x/y,按钮文字。还有一个重载用于规定长宽。按钮默认大小(200x20)与mc主界面的“单人游戏”等按钮相同。

    文字

    文字使用FontRenderer对象的drawString(字符串,x,y,16进制颜色)方法来绘制,FontRenderer可通过this.fontRenderer获得。其中16进制颜色不支持压缩表示,6位为RGB,8位为aRGB。但据说某些情况下有一些颜色不匹配的问题,需要使用GlStateManager.color()来设置颜色。

    线段

    使用this.drawHorizontalLine(x1,x2,y,color)等系列方法绘制,方法和参数名通俗易懂。

    文本框

    文本框的添加稍微复杂,需要同时在initGui()updateScreen()mouseClicked()keyTyped()drawGuiContainerBackgroundLayer()中添加代码才能得到一个正常的文本框,关键代码见下:

    public class MyGUI extends GuiContainer {
        GuiTextField textField;
        public void initGui() {
            super.initGui();    
            textField = new GuiTextField(1,this.fontRenderer,50,50,200,20); // 初始化
        }
        public void updateScreen() {
            super.updateScreen();
            textField.updateCursorCounter();
        }
        protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
            super.mouseClicked(mouseX, mouseY, mouseButton);
            textField.mouseClicked(mouseX,mouseY,mouseButton); // 打开文本框点击获得焦点的功能
        }
        protected void keyTyped(char typedChar, int keyCode) throws IOException {
            super.keyTyped(typedChar, keyCode);
            textField.textboxKeyTyped(typedChar,keyCode); // 打开文本框输入功能
        }
        protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
            this.drawDefaultBackground();
            this.textField.drawTextBox(); // 绘制文本框
        }
    }
    

    物品槽

    界面交互

    物品槽交互

    界面交互通常使用重写匿名内部类方法的形式,以下列举几个常用的

    this.addSlotToContainer(new SlotItemHandler(items,0,0,0){
        {
            // 构造器内
            this.putStack(new ItemStack(Items.APPLE, 5));         // 比如初始物品什么的
        }
        public int getItemStackLimit(@Nonnull ItemStack stack) {} // 最大数量
        public boolean canTakeStack(EntityPlayer playerIn) {}     // 是否能取出
        public boolean isItemValid(@Nonnull ItemStack stack) {}   // 是否能放入
        public void onSlotChanged() {}                            // 当前物品槽内发生变化时
    });
    

    按钮交互

    在GuiContainer中重写actionPerformed()实现按钮交互:

    @Override
    protected void actionPerformed(GuiButton button) throws IOException {
        if (button == myButton){}
    }
    

    新的HUD

    HUD(Head Up Display),简单来说就是游戏界面上方实时显示的各种面板,比如经验条、血条、物品栏、十字准星等等。下面举个例子,在游戏界面两侧各显示一张图片。通常会把多张图片组合成一张图片,使用代码来控制显示图片的哪些区域。在这里图片大小是128x64。

    HUD界面

    新建 MyHUD.java 继承Gui类。Gui类已经实现了一些绘制方法。原版的 HUD 在 GuiIngame 类中定义,可供参考。

    public class MyHUD extends Gui {
        // 材质图
        public static final ResourceLocation hud = new ResourceLocation(MyMod.MODID,"textures/gui/my_hud.png");
        // mc 实例,方便使用
        private Minecraft mc;
    
        public MyHUD() {
            this.mc = Minecraft.getMinecraft();
        }
    
        public void render() {
            ScaledResolution r = new ScaledResolution(this.mc);
            this.mc.getTextureManager().bindTexture(hud);
            int win_w = r.getScaledWidth();
            int win_h = r.getScaledHeight();
            // 分别画左右两边的图
            drawModalRectWithCustomSizedTexture(win_w/3-32, win_h/2-32, 0, 0, 64, 64, 128, 64);
            drawModalRectWithCustomSizedTexture(win_w/3*2-32, win_h/2-32, 64, 0, 64, 64, 128, 64);
        }
    }
    
    • ScaledResolution 类用于获取Minecraft游戏窗口的真实大小,不知道为什么,minecraft实例的displayWidth/displayHeight并不是真实窗口大小。
    • 自定义render()方法来绘制HUD界面
    • drawModalRectWithCustomSizedTexture(x,y,u,v,w,h,textureWidth,textureHeight) 方法表示:将材质图缩放为(textureWidth,textureHeight)大小,然后取材质图上的区域(u,v,u+w,v+h),画到屏幕上的区域(x,y,x+w,y+h)。Gui类中还有很多 draw 系列方法可供使用。

    加载HUD

    Minecraft 中提供了 RenderGameOverlayEvent 事件来管理HUD的加载,它还有 PrePost 等子事件可供使用

    public static final MyHUD hud = new MyHUD();
    
    @SubscribeEvent
    public static void onHUDRender(RenderGameOverlayEvent event){
        if (event.getType() != RenderGameOverlayEvent.ElementType.ALL) {
            return;
        }
        // other code
        hud.render();
    }
    
    • 枚举 RenderGameOverlayEvent.ElementType 中规定了一些原版中特殊的HUD,可以通过这个来控制原版HUD的显示,event.setCanceled(true);后,相应的HUD不再绘制。
    • 调用刚才写的渲染方法 render() 来绘制HUD
    • RenderGameOverlayEvent 类也有一个 ScaledResolution 成员可供使用

    最终效果如下,暂时不清楚如何正确显示透明区域。

  • 相关阅读:
    如何分析matlab程序的主要效率问题
    matlab的二维卷积操作
    移动,联通,电信手机都属于什么频段?
    开始学习Python
    利用R进行多元线性回归分析
    PANGU---Planet and Asteroid Natural scene Generation Utility
    中兴N909手机关闭照相机声音
    0709 C语言常见误区----------函数指针问题
    0709 C语言常见误区----------二维数组做参数
    0707 父子进程之间传递文件描述符
  • 原文地址:https://www.cnblogs.com/moonfan/p/12917066.html
Copyright © 2011-2022 走看看