繁体   English   中英

Minecraft Forge - 显式调用构造函数时无法引用实例字段

[英]Minecraft Forge - Cannot refer to an instance field while explicitly invoking a constructor

对于我的 Minecraft 模组,我编写了一个自定义按钮 class 以便当按下按钮时,它会向服务器发送一个数据包以更新功能。 按钮也应该改变纹理,因此与能力中设置的“样式”具有相同 id 的按钮是红色的,而其他按钮是灰色的。

但是,我遇到的一个问题是,具有正确 id 的按钮之后的下一个按钮是实际变为红色的按钮(例如,如果 id 为 0 的按钮是活动 id,则 id 为 1 的按钮是那个变成红色的按钮)。

这是我的按钮 class:

package lk1905.gielinorcraft.client.gui.widget;
import lk1905.gielinorcraft.Gielinorcraft;
import lk1905.gielinorcraft.capability.attackstyle.AttackStyleCapability;
import lk1905.gielinorcraft.capability.attackstyle.IAttackStyle;
import lk1905.gielinorcraft.network.AttackStyleClientPacket;
import lk1905.gielinorcraft.network.PacketHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.widget.button.ImageButton;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ResourceLocation;

public class AttackStyleButton extends ImageButton{

    
    private PlayerEntity player =  Minecraft.getInstance().player;
    private IAttackStyle styleCap = player.getCapability(AttackStyleCapability.STYLE_CAP).orElse(null);
    private static int yTex = 0;
    
    public AttackStyleButton(int xIn, int yIn, int widthIn, int heightIn, int xTexStartIn, int yTexStartIn,
            int yDiffTextIn, ResourceLocation resourceLocationIn, IPressable onPressIn) {
        super(xIn, yIn, widthIn, heightIn, xTexStartIn, yTexStartIn, yDiffTextIn, resourceLocationIn, onPressIn);
    }
    
    public AttackStyleButton(int xIn, int yIn, int slotId) {    
        this(xIn, yIn, 56, 20, 137, yTex, 0 , new ResourceLocation(Gielinorcraft.MODID, "textures/gui/combat.png"), (button) -> {
            PacketHandler.sendToServer(new AttackStyleClientPacket(slotId));
        });
    
        if(styleCap.getActiveStyleId() == slotId) {
            yTex = 23;
        }else {
            yTex = 0;
        }
    }
    
}

在此之前,我去了 Minecraft forge 网站询问问题是什么,他们声称变量“yTex”不应该是 static(但他们实际上不会说为什么,只是“请了解 static 是什么意思”,即使我找不到足够相似的例子让我理解为什么)。

不过,问题在于,我首先将其设为 static 的原因是因为 eclipse 给了我错误“在显式调用构造函数时无法引用实例字段 yTex”,位于第二个构造函数中,并告诉我进行它是 static。

据我了解,错误是因为 yTex 被实例化,在调用构造函数之前它没有值,所以构造函数无法继续。 但我不确定如何重写 class 以便它做同样的事情。 我希望在此 class 中设置 yTex 的值,并由 if 语句决定其值。

那么我将如何重写这个 class 以便它完成我已经告诉它要做的事情,但 yTex 不是 static?

如果要添加逻辑来计算要传递给超类构造函数的值,则不能使用来自调用 class 的任何实例变量或方法,因为在调用超类的构造函数时不存在调用 class 的任何内容。

static 方法可用于运行代码以计算要作为参数传递给超类构造函数的值。 上面提到的相同规则适用于此 static 方法中的代码。 以下是您如何使用此技术来计算要传递给超类构造函数的值来代替计算的yTex值:

package lk1905.gielinorcraft.client.gui.widget;

import lk1905.gielinorcraft.Gielinorcraft;
import lk1905.gielinorcraft.capability.attackstyle.AttackStyleCapability;
import lk1905.gielinorcraft.capability.attackstyle.IAttackStyle;
import lk1905.gielinorcraft.network.AttackStyleClientPacket;
import lk1905.gielinorcraft.network.PacketHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.widget.button.ImageButton;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ResourceLocation;

public class AttackStyleButton extends ImageButton{

    private static int yTex(int slotId) {
        PlayerEntity player =  Minecraft.getInstance().player;
        IAttackStyle styleCap = player.getCapability(AttackStyleCapability.STYLE_CAP).orElse(null);
        if (styleCap.getActiveStyleId() == slotId) {
            return 23;
        } else {
            return 0;
        }
    }
    
    public AttackStyleButton(int xIn, int yIn, int slotId) {    
        super(xIn, yIn, 56, 20, 137, yTex(slotId), 0 , new ResourceLocation(Gielinorcraft.MODID, "textures/gui/combat.png"), (button) -> {
            PacketHandler.sendToServer(new AttackStyleClientPacket(slotId));
        });    
    }
}

您在评论中说“第一个构造函数存在只是因为这个 class 是从另一个 class 扩展而来的。第二个构造函数是我使用的那个。” 我不确定你在这里说的是为什么你有第一个构造函数。 如果AttackStyleButton class 只使用第二个构造函数实例化,那么第一个构造函数就没有理由存在。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM