当前位置: 首页 > 知识库问答 >
问题:

使用单个类从任何元块命名子块?

盖嘉庆
2023-03-14

我试图使使用该类注册的任何元块中的子块只需要一个类来命名,也就是说,将它们命名为参数值,但不使用参数值。

虽然这是围绕一个API(Minecraft Forge)展开的,但我认为这是一个Java问题,所以我在这里快速解释一下我打算做什么。

元块由子块组成,子块是同一块的变体(例如,同一块,但仅纹理和名称发生变化)。每个子块都需要一个名称来标识它。这些名称以字符串[]的形式列在类ExampleItemBlock中,然后以MetablockName的格式命名。子块名(例如:ExampleMetablock.blueExampleMetablock.green,等等),使用

// ExampleItemBlock Class

public static final String[] SUBNAMES = new String[] {"blue", "green", "yellow"};

@Override
public String getUnlocalizedName(ItemStack itemStack) 
{
    int i = itemStack.getItemDamage();
    return getUnlocalizedName() + "." + SUBNAMES[i];
}

然后,使用

// Class where the registrations are made  

public static Block ExampleMetablock = new ExampleMetablock(); 

GameRegistry.registerBlock(ExampleMetablock, ExampleItemBlock.class, "ExampleMetablock");

在这之后,一切都不会有问题,但是我必须为我创建的每个新元块创建一个新的*ItemBlock类,我认为这不是一件好的或合适的事情,我认为最好创建一个单独的类,供将来的任何元块使用。

值得注意的是,GameRegistry的第二个参数。registerBlock()method(即API中的方法)需要类型为Class的值。这就是问题所在:在不使用实例的情况下,我如何将ExampleItemBlock类变成动态的?

我甚至试图添加一个String[]参数在ExpleItemBlock构造函数,然后使用一个实例的名称代替类,但正如预期的那样,它声明类型不匹配。

我到处寻找实现这一目标的方法,但我只找到了两种方法:

1.为每个新元块创建一个ItemBlock类
2。将getUnlocalizedName()中的SUBNAMES[i]更改为iitemStack。getItemDamage(),这将导致子块以数字而不是名称命名(例如:ExampleMetablock.0ExampleMetablock.1,等等),不需要使用字符串[]或任何东西,并使其成为一个通用类。然而,这种方法也非常不切实际,因为在识别哪个子块是哪个子块时,这会使很多事情变得复杂。

我还在GitHub上搜索了一些mod,但在代码中没有找到任何与此相关的内容(据我所知)。

所以我的问题是:有没有办法创建一个通用的*ItemBlock类,但仍然用名称(单词)命名子块?

类内容:ExampleMetablock、ExamplItemBlock。

共有2个答案

苏星宇
2023-03-14

我最终发现解决方案就在Forge本身,如图所示。

但为了提供信息,我会解释解决方案。

我不知道,但方法是GameRegistry。registerBlock()还接受第四个参数,类型为Object[]。因此,只需将名称列表放入对象[],只需从ExampleMetablock创建字符串[]字段,并将定义的对象[]参数值传递到字符串[]字段。就像这样:

public static String[] SUBNAMES;
private IIcon[] icon;

public ExampleMetaBlock(Material material, String name, CreativeTabs tab, String[] subnames)
{
    super(material, name, tab);
    SUBNAMES = subnames;
}

参数中,我建议您不要使用单独创建的类ExampleItemBlock,而是使用Minecraft代码中已经存在的类,该类的功能与ExampleItemBlock几乎相同,这是itemmultexture类(在这种情况下,itemmultexture类中没有其他内容)。注册信息如下:

public static final String[] SubNames = new String[] {"blue", "green", "yellow", "red"}; 
public static Block ExampleMetablock = new ExampleMetablock(Material.rock, "ExampleMetablock", Tabs.ExampleModTab, SubNames); 

GameRegistry.registerBlock(ExampleMetablock, ItemMultiTexture.class, "ExampleMetablock", new Object[]{SubNames});

但是,这不会编译。错误NoSuchmetodExctive将发生在注册行(GameRegistry.registerBlock...)。

ItemMultiTexture类构造函数获取与它的构造函数参数类型(Block, Block, String[])相匹配的方法参数中的设置值。

是否提供了字符串[]?对是否提供了?对是否提供了第二个?否。“没有这样的方法”,没有来自ItemMultiTexture的构造函数,参数为块,字符串[]

这是因为,如前所述,来自ItemMultiTexture的构造函数需要两个Block值。

要解决这个问题,只需创建一个新类(或编辑ExemploItemBlock),扩展ItemMultiTexture,它supers两个参数。就像这样:

public class ItemMultiTextureHelper extends ItemMultiTexture
{
    public ItemMultiTextureHelper(Block block, String[] names)
    {
        super(block, block, names);
    }
}

registerBlock()如下所示:

GameRegistry.registerBlock(ExampleMetablock, ItemMultiTextureHelper.class, "ExampleMetablock", new Object[]{SubNames});

还有最后一件事,但同样重要的是:从子名称中删除静态修饰符,否则这将在新的元块上造成一团混乱,就像所有元块的子块都被命名为与第一个创建的元块相同的名称,重复的子块,等等。
(我刚刚遇到了这些问题,并修复了删除静态)所以正确的答案实际上是:

public String[] SUBNAMES;
姬博瀚
2023-03-14

我的建议是创建一个基类来实现所有功能。

public class BaseItemMetaBlock {
    .....
}

这一个具有元块渲染的所有功能,但没有分配给任何块。

然后,有一个街区

public class MySuperAwesomeBlockItem extends BaseItemMetaBlock {
    public MySuperAwesomeBlockItem(Block block) {
       super(block);
    }
}

因为ItemBlock与块本身相关联,所以可以执行一些编程魔术来获取定义BlockState的枚举,以返回所需的名称。

我所做的是给我的块一个特殊的接口,这样我就可以在将它们转换为通用接口后调用我自己的方法

 @Override
 public String getUnlocalizedName(ItemStack stack) {
    return super.getUnlocalizedName(stack) + "." + ((IMetaBlockName)this.block).getSpecialName(stack);
  }

反正是这样的。

 类似资料:
  • 我有几个共享一些字段。我有一个接受这些元组的函数,并保证只与共享字段交互。我想在mypy中键入检查此类代码。 代码的一个示例是: 当我对这段代码运行mypy时,我得到了一个可预见的错误: mypy_example.py:20:错误:“DoSomething”的参数1具有不兼容的类型“base extended”;预期的“基数” 有没有办法构造我的代码并保持我的py类型检查?我无法从< code>B

  • 问题内容: 最初,我使用下划线作为类名。新的Java8编译器抱怨它“ 在Java SE 8之后可能不受支持 ”。我将其更改为,不再有警告。但是我记得Java使用它在字节码中指示一个内部/嵌入式类。我想知道使用美元符号作为类名是否有任何风险 这个问题的一些背景。我想做的是克服Java不支持纯函数的事实,而_或$是放置一个命名空间来封装一些非常通用的概念(类/静态方法)。我对此也没有好名,也不想让li

  • 问题内容: 我正在尝试使用该函数进行复制,但似乎遇到了麻烦。 一个简单的例子很简单: 我遇到的问题是我正在从子包中导入名称(即): 所以我想要的是 但这只是导入了顶级包,而不是子包: 问题答案: 该函数将返回包的顶级模块,除非您传递了非空参数: 请参阅该函数的Python文档。

  • 问题内容: 昨天我刚刚下载了Java的eclipse,但是当我尝试制作自己的第一个程序时,我不断收到此错误: 我该如何解决? 问题答案: 只需在Project Explorer选项卡上删除 module-info.java 。

  • 问题内容: 我尝试使用PyInstaller在Windows 7下编译Python项目。该项目运行正常,没有问题,但是当我尝试对其进行编译时,结果将不起作用。尽管在编译过程中没有收到警告,但目录中的文件中有很多警告:warnmain.txt 我不是很了解这些警告,例如“没有名为numpy.pi的模块”,因为它不是模块而是数字。我从未尝试导入。我确实导入并明确。另外,我正在使用PyQt4。我认为错误

  • 问题内容: 考虑下面的代码: html文件的一部分: js文件的一部分: 我总是将控制器放在某个模块中,该模块的名称在ng-app中定义。当我不定义任何模块时,它如何工作? 问题答案: Angular具有此“自动发现”功能,如果在全局作用域上定义了控制器,则可以按其名称查找控制器。 此功能主要用于快速演示/原型/概念验证摘要,而非实际应用。 从Angular的 开发人员指南中 : 注意: 尽管An