MENU

如何实现一个简易的可拖动面板

July 24, 2022 • Read: 387 • Minecraft,后端,开发日常,Forge

一、前言

近期因为项目要求, 需要开发一个可拖动的面板, 分享一下我实现的代码。

二、代码示例

private int x, y, ox = -1, oy = -1;
private boolean move;

@SubscribeEvent
public void onMouse(GuiScreenEvent.DrawScreenEvent event) {
    if (event.getGui() instanceof GuiChat) {
        // 请去掉下方这个 while 循环, 避免和其他东西冲突
        while (Mouse.next()) {
            if (Mouse.getEventButtonState()) {
                if (Mouse.getEventButton() == 0 && event.getMouseX() >= this.x && event.getMouseY() >= this.y && event.getMouseX() <= this.x + 126 && event.getMouseY() <= this.y + 54) {
                    this.move = true;
                }
            } else {
                if (Mouse.getEventButton() == 0) {
                    this.move = false;
                    this.ox = -1;
                    this.oy = -1;
                }
            }
        }
        if (this.move) {
            if (this.ox >= 0 && this.oy >= 0) {
                this.x += event.getMouseX() - ox;
                this.y += event.getMouseY() - oy;
            }
            this.ox = event.getMouseX();
            this.oy = event.getMouseY();
        }
    }
}

@SubscribeEvent
public void onRender(RenderGameOverlayEvent.Pre event) {
    if (event.getType() != RenderGameOverlayEvent.ElementType.ALL) {
        return;
    }
    Minecraft minecraft = Minecraft.getMinecraft();
    if (minecraft.getRenderViewEntity() instanceof EntityPlayer) {
        // 渲染头像
        GlStateManager.pushMatrix();
        GlStateManager.disableLighting();
        GlStateManager.enableAlpha();
        GlStateManager.color(1, 1, 1, 1);
        GlStateManager.scale(1, 1, 1);
        Minecraft.getMinecraft().getTextureManager().bindTexture(PetInfo.PET_INFO.getAvatarResource());
        Gui.drawScaledCustomSizeModalRect(this.x + 6, this.y + 5, 0, 0, 50, 50, (int) (50 * 0.75), (int) (50 * 0.75), 50, 50);
        GlStateManager.popMatrix();
    }
}

监听Gui绘制事件, 判断界面是否为 GuiChat, 再通过 lwjgl 的 Mouse 控件获取当前鼠标状态来调整 move 变量, x, y 为渲染面板时的 x y 坐标, 而下方代码则是判断点击的是否为我创建的面板(126, 54 是我面板大小)。

event.getMouseX() >= this.x && event.getMouseY() >= this.y && event.getMouseX() <= this.x + 126 && event.getMouseY() <= this.y + 54

ox, oy 为旧鼠标位置, 即上一次鼠标位置, 用于计算鼠标移动及定位的, 初始值为 -1, 当鼠标按下时则设置为当前鼠标位置, 在鼠标松开后重新赋值为 -1。

三、示例图片

示例图

四、结尾

本篇文章仅作为参考, 如果你有更好的办法可以在下方回复。

Last Modified: March 21, 2023