对于我的Minecraft mod,我编写了一个自定义按钮类,以便当按下按钮时,它会向服务器发送一个数据包来更新功能。按钮也应该改变纹理,所以与功能中设置的“样式”具有相同id的按钮是红色的,而其他按钮是灰色的。
然而,我遇到的一个问题是,在具有正确id的按钮之后的下一个按钮实际上是红色的按钮(例如,如果id为0的按钮是活动id,id为1的按钮是打开的按钮红色代替)。
这是我的按钮类:
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”不应该是静态的(他们不会说为什么,只是“请了解静态的含义”,尽管我找不到足够多的类似示例来理解为什么)。
但问题是,我之所以将其设置为静态,首先是因为eclipse在第二个构造函数中给出了错误“无法在显式调用构造函数时引用实例字段yTex”,并告诉我将其设置为静态。
据我所知,错误是因为在实例化yTex时,它在调用构造函数之前没有值,因此构造函数无法继续。但我不知道如何重写这个类,使它做同样的事情。我想在这个类中设置yTex的值,由if语句决定它的值。
那么,我如何重写这个类,使它做我已经告诉它做的事情,但yTex不是静态的?
如果您想添加逻辑来计算要传递给超类构造函数的值,您不能使用调用类中的任何实例变量或方法,因为在调用超类构造函数时,调用类的任何内容都不存在。
静态方法可用于运行代码,以计算作为参数传递给超类构造函数的值。上面提到的规则同样适用于这个静态方法中的代码。下面是如何使用这种技术来计算传递到超类构造函数中的值,以代替计算的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));
});
}
}
你在评论中说:“第一个构造函数之所以存在,是因为这个类是从另一个类扩展而来的。第二个构造函数就是我使用的那个。”我不知道你在这里说什么,为什么你有第一个构造函数。如果只使用第二个构造函数实例化了AttackStyleButton
类,那么没有理由存在第一个构造函数。
问题内容: 有谁知道为什么可以使用或而不是非静态方法在构造函数的第一行中引用方法? 考虑以下工作: 以及以下非工作示例: 问题答案: 非静态方法是实例方法。这只能在现有实例中访问,并且在构造函数中时实例尚不存在(它仍在构建中)。 为什么会这样呢?因为实例方法可以访问实例(非静态)字段,该字段在不同实例中可以具有不同的值,所以在现有的已完成实例之外的其他地方调用这种方法没有任何意义。
问题内容: 我有一个类A,并写了一个子类B。A只有一个参数化的构造函数。B必须调用A的这个超级构造函数。现在,我想使用一个Object作为参数。该对象应调用B的方法。因此,参数对象必须持有B的引用,或者必须是内部类。 现在,当我想调用构造函数时,……Eclipse说: 在显式调用构造函数时无法引用“ this”或“ super” 我唯一想解决的是设置方法,将“ this”实例注入到参数对象中。我不
问题内容: 可以这么说,我有一个扩展超类的子类。在什么情况下我需要显式键入以使超类构造函数运行? 我正在看一本书中有关抽象类的示例,当它们使用非抽象子类对其进行扩展时,该子类的默认构造函数为空,并且有一条评论说将调用超类的默认构造函数。同时,我还在这里看到有人未明确致电问题的实例。 与从子类的默认/非默认构造函数调用超类的默认/非默认构造函数有区别吗? 问题答案: 你 永远都不 需要 如果您不指定
问题内容: 为什么Eclipse总是在构造函数上给我错误: 错误是: 类 密集板 类 板 问题答案: 您只需执行此操作即可将值发送到父类。
我正在从事一个C语言的项目,当我显式实例化模板类时,很难理解模板类的哪些成员被显式实例化。我编写了以下文件,然后使用Visual C 2008 Express Edition的发布配置编译该文件,然后将其放入反汇编程序。 忽略这个文件目前并不真正需要模板,这可以很好地编译。我将exe放入反汇编程序,它告诉我该测试 这导致测试
我试图从Spock测试中扩展GebSpec的类调用java构造函数。我有这样一个错误:“不允许构造函数;相反,定义一个'setup()'或'setup spec()'方法”。我需要打这样的电话:
我学到了两件事: -操作符创建一个新实例,然后执行声明的connstuctor来初始化该新实例 根据我的理解,这些说法互相反对。 例如,不会创建两个实例,因为-操作符创建一个实例,构造函数调用并创建另一个实例?当然不会,但现在到底是什么创建了一个实例。。。?
构造函数与析构函数是自动调用的。这些函数的调用顺序取决于执行过程进入和离开实例化对象范围的顺序。一般来说,析构函数的调用顺序与构造函数相反。但图6.9将介绍对象存储类可以改变析构函数的调用顺序。 全局范围中定义的对象的构造函数在文件中的任何其他函数(包括 main)执行之前调用(但不同文件之间全局对象构造函数的执行顺序是不确定的)。当main终止或调用exit函数时(见第18章)调用相应的析构函数