User Tools

Site Tools


zh_cn:tutorial:extendedscreenhandler

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
Last revisionBoth sides next revision
zh_cn:tutorial:extendedscreenhandler [2022/02/10 13:02] – [方块实体] timothy_starmanzh_cn:tutorial:extendedscreenhandler [2022/02/10 13:26] – 注册我们的 ScreenHandler timothy_starman
Line 1: Line 1:
 +====== ​使用扩展的 ScreenHandler 同步数据 ​======
 +在本教程中,我们将使用 ExtendedScreenHandler ​在 ScreenHandler 打开时将任意数据从服务器传输到客户端 ScreenHandler。
 + 
 +在我们的示例中,我们将用方块的位置作为容器的标题。
 +
 ====== 方块实体 ====== ====== 方块实体 ======
 由于 Block 类根本不需要更改,我们将其留在这里。 由于 Block 类根本不需要更改,我们将其留在这里。
Line 50: Line 55:
 } }
  
 +</code>
 +
 +====== 新的 ExtendedScreenHandler (实例) ======
 +
 +<code java [enable_line_numbers="true"] BoxScreenHandler.java>
 +public class BoxScreenHandler extends ScreenHandler {
 +    //我们保存从服务器获得的 blockPos 并为其提供一个 getter,以便 BoxScreen 可以读取该信息
 +    private BlockPos pos;
 +    private final Inventory inventory;
 +
 +    //当服务器(Server)希望它打开 screenHandler 时,在客户端(Cilent)上调用此构造函数,
 +    //客户端将使用一个空的 Inventory 调用超级构造函数,并且 screenHandler 将自动将此空库存与服务器上的库存同步。
 +
 +    //新:客户端的构造函数现在获取我们在 BlockEntity 中填充的 PacketByteBuf
 +    public BoxScreenHandler(int syncId, PlayerInventory playerInventory, PacketByteBuf buf) {
 +        this(syncId, playerInventory, new SimpleInventory(9));
 +        pos = buf.readBlockPos();
 +    }
 +
 +    //此构造函数从服务器上的 BlockEntity 调用,服务器知道容器的库存(你可以将它理解为物品栏),因此可以直接将其作为参数提供。 然后,此库存(物品栏)将同步到客户端。
 +    public BoxScreenHandler(int syncId, PlayerInventory playerInventory, Inventory inventory) {
 +        //[...]
 +        //有关其余代码,请参阅第一个 Screenhandler 教程
 +        
 +        //想一想,为什么我们在这里使用 BlockPos.ORIGIN?
 +        //This is because the packetByteBuf with our blockPosition is only availible on the Client, so we need a placeholder
 +        //value here. This is not a problem however, as the Server version of the ScreenHandler does not really need this
 +        //information.
 +        //(机翻警告)这是因为带有我们 blockPosition 的 packetByteBuf 仅在 Client 上可用,所以我们这里需要一个占位符值。 然而,这不是问题,
 +        //因为 ScreenHandler 的服务器版本并不真正需要此信息。
 +        pos = BlockPos.ORIGIN;
 +
 +        [...]
 +    }
 +
 +    //这个 getter 将被我们的 Screen 类使用
 +    public BlockPos getPos() {
 +        return pos;
 +    }
 +
 +    @Override
 +    public boolean canUse(PlayerEntity player) {
 +        return this.inventory.canPlayerUse(player);
 +    }
 +
 +    // 参阅 Screenhandler 教程
 +    // Shift + Player Inv Slot
 +    @Override
 +    public ItemStack transferSlot(PlayerEntity player, int invSlot);
 +}
 +</code>
 +
 +====== 在 Screen 中使用 ExtendedScreenHandler 信息 ======
 +
 +<code java [enable_line_numbers="true"] BoxScreen.java>
 +
 +public class BoxScreen extends HandledScreen<ScreenHandler> {
 +    private static final Identifier TEXTURE = new Identifier("minecraft", "textures/gui/container/dispenser.png");
 +
 +    public BoxScreen(ScreenHandler handler, PlayerInventory inventory, Text title) {
 +        super(handler, inventory, getPositionText(handler).orElse(title));
 +        //我们尝试获取方块位置以将其用作我们的标题,如果由于某种原因失败,我们将使用默认标题
 +    }
 +
 +    //此方法将尝试从 ScreenHandler 获取位置,因为 ScreenRendering 仅发生在客户端上,
 +    //我们在此处获取具有正确 BlockPos 的 ScreenHandler 实例!
 +    private static Optional<Text> getPositionText(ScreenHandler handler) {
 +        if (handler instanceof BoxScreenHandler) {
 +            BlockPos pos = ((BoxScreenHandler) handler).getPos();
 +            return pos != null ? Optional.of(new LiteralText("(" + pos.toShortString() + ")")) : Optional.empty();
 +        } else {
 +            return Optional.empty();
 +        }
 +    }
 +
 +
 +    @Override
 +    protected void drawBackground(MatrixStack matrices, float delta, int mouseX, int mouseY) { [...] }
 +
 +    @Override
 +    public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { [...] }
 +
 +    @Override
 +    protected void init() { [...] }
 +}
 +
 +</code>
 +
 +====== 注册我们的 ScreenHandler ======
 +
 +<code java [enable_line_numbers="true"] ExampleMod.java>
 +public class ExampleMod implements ModInitializer {
 +
 +    [...]
 +    public static final ScreenHandlerType<BoxScreenHandler> BOX_SCREEN_HANDLER;
 +
 +    static {
 +        [...]
 +       
 +        //我们现在使用 registerExtended 作为我们的 screenHandler 现在在其构造函数中接受一个 packetByteBuf
 +        BOX_SCREEN_HANDLER = ScreenHandlerRegistry.registerExtended(BOX, BoxScreenHandler::new);
 +    }
 +
 +    @Override
 +    public void onInitialize() {
 +
 +    }
 +}
 </code> </code>
  
zh_cn/tutorial/extendedscreenhandler.txt · Last modified: 2022/02/10 13:32 by timothy_starman