zh_cn:tutorial:screenhandler
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
zh_cn:tutorial:screenhandler [2022/12/09 04:51] – solidblock | zh_cn:tutorial:screenhandler [2024/08/27 04:50] (current) – update translations solidblock | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== 创建一个容器方块 ====== | + | ====== 创建容器方块 ====== |
这篇教程会创建一个类似发射器的简单存储方块,并解释如何使用 Fabric 和原版 Minecraft 中的 ScreenHandler API 构建用户界面。 | 这篇教程会创建一个类似发射器的简单存储方块,并解释如何使用 Fabric 和原版 Minecraft 中的 ScreenHandler API 构建用户界面。 | ||
先解释一些词汇: | 先解释一些词汇: | ||
- | **Screenhandler:** | + | **Screenhandler:** |
'' | '' | ||
- | **Screen:** | + | **Screen:** |
'' | '' | ||
Line 18: | Line 18: | ||
protected BoxBlock(Settings settings) { | protected BoxBlock(Settings settings) { | ||
super(settings); | super(settings); | ||
+ | } | ||
+ | | ||
+ | // 从 1.20.5 开始需要有这个方法。 | ||
+ | @Override | ||
+ | protected MapCodec<? | ||
+ | return createCodec(BoxBlock:: | ||
} | } | ||
Line 106: | Line 112: | ||
public Text getDisplayName() { | public Text getDisplayName() { | ||
return Text.translatable(getCachedState().getBlock().getTranslationKey()); | return Text.translatable(getCachedState().getBlock().getTranslationKey()); | ||
- | // 对于1.19之前的版本,请使用: | + | // 对于 1.19 之前的版本,请使用: |
// return new TranslatableText(getCachedState().getBlock().getTranslationKey()); | // return new TranslatableText(getCachedState().getBlock().getTranslationKey()); | ||
} | } | ||
| | ||
+ | // 以下两个方法,旧版本请移除参数 `registryLookup`。 | ||
@Override | @Override | ||
- | public void readNbt(NbtCompound nbt) { | + | public void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { |
- | super.readNbt(nbt); | + | super.readNbt(nbt, registryLookup); |
- | Inventories.readNbt(nbt, | + | Inventories.readNbt(nbt, |
} | } | ||
@Override | @Override | ||
- | public NbtCompound writeNbt(NbtCompound nbt) { | + | public NbtCompound writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) { |
- | super.writeNbt(nbt); | + | super.writeNbt(nbt, registryLookup); |
- | Inventories.writeNbt(nbt, | + | Inventories.writeNbt(nbt, |
return nbt; | return nbt; | ||
} | } | ||
Line 127: | Line 134: | ||
===== 注册方块、物品和方块实体 ===== | ===== 注册方块、物品和方块实体 ===== | ||
+ | 在这个例子中,方块、方块物品。方块实体直接注册在 '' | ||
<code java [enable_line_numbers=" | <code java [enable_line_numbers=" | ||
public class ExampleMod implements ModInitializer { | public class ExampleMod implements ModInitializer { | ||
- | | + | // 对于 1.21 之前的版本,将 `Identifier.of` 替换为 `new Identifier`。 |
- | public static final BlockItem BOX_BLOCK_ITEM; | + | |
- | public static final BlockEntityType< | + | |
- | + | | |
- | public static final String MOD_ID = " | + | public static final BlockItem |
- | | + | |
- | public static final Identifier | + | |
- | + | | |
- | static | + | |
- | | + | // 在 1.17 使用 FabricBlockEntityTypeBuilder 而不是 BlockEntityType.Builder |
- | BOX_BLOCK_ITEM = Registry.register(Registry.ITEM, | + | // public static final BlockEntityType< |
- | + | // FabricBlockEntityTypeBuilder.create(BoxBlockEntity:: | |
- | | + | |
- | // 1.17 之前 | + | |
- | BOX_BLOCK_ENTITY = Registry.register(Registry.BLOCK_ENTITY_TYPE, | + | |
- | // 在 1.17 使用 FabricBlockEntityTypeBuilder 而不是 BlockEntityType.Builder | + | |
- | BOX_BLOCK_ENTITY = Registry.register(Registry.BLOCK_ENTITY_TYPE, | + | |
- | } | + | |
@Override | @Override | ||
public void onInitialize() { | public void onInitialize() { | ||
- | |||
} | } | ||
} | } | ||
- | |||
- | |||
</ | </ | ||
Line 174: | Line 173: | ||
} | } | ||
- | // 这个构造器是在服务器的 BlockEntity 中被调用的,无需线调用其他构造器,服务器知道容器的物品栏 | + | // 这个构造器是在服务器的 BlockEntity 中被调用的,无需先调用其他构造器,服务器知道容器的物品栏 |
// 并直接将其作为参数传入。然后物品栏在客户端完成同步。 | // 并直接将其作为参数传入。然后物品栏在客户端完成同步。 | ||
public BoxScreenHandler(int syncId, PlayerInventory playerInventory, | public BoxScreenHandler(int syncId, PlayerInventory playerInventory, | ||
Line 184: | Line 183: | ||
// 这会将槽位放置在 3×3 网格的正确位置中。这些槽位在客户端和服务器中都存在! | // 这会将槽位放置在 3×3 网格的正确位置中。这些槽位在客户端和服务器中都存在! | ||
- | // 但是这不会渲染槽位的背景,这是 Screens | + | // 但是这不会渲染槽位的背景,这是 Screens |
int m; | int m; | ||
int l; | int l; | ||
Line 243: | Line 242: | ||
public class BoxScreen extends HandledScreen< | public class BoxScreen extends HandledScreen< | ||
// GUI 纹理的路径,本例中使用发射器中的纹理 | // GUI 纹理的路径,本例中使用发射器中的纹理 | ||
- | private static final Identifier TEXTURE = new Identifier(" | + | private static final Identifier TEXTURE = Identifier.ofVanilla(" |
public BoxScreen(ScreenHandler handler, PlayerInventory inventory, Text title) { | public BoxScreen(ScreenHandler handler, PlayerInventory inventory, Text title) { | ||
Line 250: | Line 249: | ||
@Override | @Override | ||
- | protected void drawBackground(MatrixStack matrices, float delta, int mouseX, int mouseY) { | + | protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) { |
- | RenderSystem.setShader(GameRenderer:: | + | RenderSystem.setShader(GameRenderer:: |
RenderSystem.setShaderColor(1.0F, | RenderSystem.setShaderColor(1.0F, | ||
RenderSystem.setShaderTexture(0, | RenderSystem.setShaderTexture(0, | ||
int x = (width - backgroundWidth) / 2; | int x = (width - backgroundWidth) / 2; | ||
int y = (height - backgroundHeight) / 2; | int y = (height - backgroundHeight) / 2; | ||
- | drawTexture(matrices, x, y, 0, 0, backgroundWidth, | + | |
} | } | ||
@Override | @Override | ||
- | public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { | + | public void render(DrawContext context, int mouseX, int mouseY, float delta) { |
- | renderBackground(matrices); | + | renderBackground(context, mouseX, mouseY, delta); |
- | super.render(matrices, mouseX, mouseY, delta); | + | super.render(context, mouseX, mouseY, delta); |
- | drawMouseoverTooltip(matrices, mouseX, mouseY); | + | drawMouseoverTooltip(context, mouseX, mouseY); |
} | } | ||
Line 280: | Line 279: | ||
<code java [enable_line_numbers=" | <code java [enable_line_numbers=" | ||
- | |||
@Environment(EnvType.CLIENT) | @Environment(EnvType.CLIENT) | ||
public class ExampleClientMod implements ClientModInitializer { | public class ExampleClientMod implements ClientModInitializer { | ||
@Override | @Override | ||
public void onInitializeClient() { | public void onInitializeClient() { | ||
- | | + | |
} | } | ||
} | } | ||
Line 292: | Line 290: | ||
别忘了在 '' | 别忘了在 '' | ||
- | <code json> | + | < |
- | /* ... */ | + | { |
+ | /* ... */ | ||
" | " | ||
/* ... */ | /* ... */ | ||
" | " | ||
- | "(到这个 | + | "net.fabricmc.example.ExampleModClient" |
] | ] | ||
}, | }, | ||
+ | /* ... */ | ||
+ | } | ||
</ | </ | ||
Line 307: | Line 308: | ||
public class ExampleMod implements ModInitializer { | public class ExampleMod implements ModInitializer { | ||
[...] | [...] | ||
- | public static final ScreenHandlerType< | + | public static final ScreenHandlerType< |
- | [...] | + | |
- | static { | + | |
- | [...] | + | |
- | // 我们在这里使用 registerSimple 因为实体不是 ExtendedScreenHandlerFactory | + | |
- | // 而是 NamedScreenHandlerFactory. | + | |
- | // 后面的教程中,你将会看到 ExtendedScreenHandlerFactory 能做什么! | + | |
- | BOX_SCREEN_HANDLER = ScreenHandlerRegistry.registerSimple(BOX, BoxScreenHandler:: | + | |
- | | + | |
@Override | @Override | ||
public void onInitialize() { | public void onInitialize() { | ||
+ | [...] | ||
} | } | ||
} | } | ||
Line 330: | Line 323: | ||
===== 延伸阅读 ===== | ===== 延伸阅读 ===== | ||
- | - [[extendedscreenhandler|屏幕开启时,使用 Extended ScreenHandlers 同步自定义的数据]] | + | * [[extendedscreenhandler|屏幕开启时,使用 Extended ScreenHandlers 同步自定义的数据]] |
- | + | | |
- | - [[propertydelegates|使用 PropertyDelegates 持续同步整数]] | + | |
- | - 使用 '' | + | 使用 '' |
zh_cn/tutorial/screenhandler.1670561465.txt.gz · Last modified: 2022/12/09 04:51 by solidblock