User Tools

Site Tools


zh_cn:tutorial:fluids

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:fluids [2020/11/15 01:30] – [创建抽象流体] solidblockzh_cn:tutorial:fluids [2023/05/04 11:30] – [渲染设置] solidblock
Line 3: Line 3:
 在这里,我们将介绍自定义流体的创建。如果计划创建多个流体,建议创建一个抽象的基本流体类,在其中设置必要的默认值,这些默认值将在其子类中共享。我们还将使其像湖泊一样在世界中生成。 在这里,我们将介绍自定义流体的创建。如果计划创建多个流体,建议创建一个抽象的基本流体类,在其中设置必要的默认值,这些默认值将在其子类中共享。我们还将使其像湖泊一样在世界中生成。
 ===== 创建抽象流体 ===== ===== 创建抽象流体 =====
-原版流体扩展了''net.minecraft.fluid.FlowableFluid'',我们也应如此。 +原版流体继承了 ''<yarn net.minecraft.class_3609>'',我们也应如此。 
-<code java [enable_line_numbers="true"]> +<yarncode java [enable_line_numbers="true"]> 
-public abstract class TutorialFluid extends FlowableFluid +public abstract class TutorialFluid extends class_3609 {
-{+
  /**  /**
  * @return 给定的流体是否为该流体的实例?  * @return 给定的流体是否为该流体的实例?
  */  */
  @Override  @Override
- public boolean matchesType(Fluid fluid) + public boolean method_15780(class_3611 fluid) {
- {+
  return fluid == getStill() || fluid == getFlowing();  return fluid == getStill() || fluid == getFlowing();
  }  }
   
  /**  /**
- * @return 流体是否可以像无限刷水的方法一样无限生成?+ * @return 流体是否可以像无限刷水的方法一样无限生成?在原版,这取决于游戏规则。
  */  */
  @Override  @Override
- protected boolean isInfinite() + protected boolean method_15737() {
- {+
  return false;  return false;
  }  }
Line 30: Line 27:
  */  */
  @Override  @Override
- protected void beforeBreakingBlock(WorldAccess world, BlockPos pos, BlockState state) + protected void method_15730(class_1936 world, class_2338 pos, class_2680 state) {
- {+
  final BlockEntity blockEntity = state.getBlock().hasBlockEntity() ? world.getBlockEntity(pos) : null;  final BlockEntity blockEntity = state.getBlock().hasBlockEntity() ? world.getBlockEntity(pos) : null;
  Block.dropStacks(state, world, pos, blockEntity);  Block.dropStacks(state, world, pos, blockEntity);
Line 37: Line 33:
   
  /**  /**
-Lava returns true if its FluidState is above a certain height and the +熔岩在其 FluidState 高于指定的高度且该流体为水时返回 true。
- * Fluid is Water.+
  
- * @return 给定的流体能否流入它的FluidState?+ * @return 给定的流体能否流入它的 FluidState?
  */  */
  @Override  @Override
- protected boolean canBeReplacedWith(FluidState fluidState, BlockView blockView, BlockPos blockPos, Fluid fluid, Direction direction) + protected boolean method_15777(class_3610 fluidState, class_1922 blockView, class_2338 blockPos, class_3611 fluid, class_2350 direction) {
- {+
  return false;  return false;
  }  }
Line 53: Line 47:
  */  */
  @Override  @Override
- protected int getFlowSpeed(WorldView worldView) + protected int method_15733(class_4538 worldView) {
- {+
  return 4;  return 4;
  }  }
Line 62: Line 55:
  */  */
  @Override  @Override
- protected int getLevelDecreasePerBlock(WorldView worldView) + protected int method_15739(class_4538 worldView) {
- {+
  return 1;  return 1;
  }  }
Line 71: Line 63:
  */  */
  @Override  @Override
- public int getTickRate(WorldView worldView) + public int method_15789(class_4538 worldView) {
- {+
  return 5;  return 5;
  }  }
Line 80: Line 71:
  */  */
  @Override  @Override
- protected float getBlastResistance() + protected float method_15784() {
- {+
  return 100.0F;  return 100.0F;
  }  }
 } }
-</code>+</yarncode>
  
-===== 进行 =====+===== 实现 =====
 现在让我们制作一个拥有静止和流动两个变种的实际流体。在此教程中,我们将其称为“酸”。缺失的引用稍后补全。 现在让我们制作一个拥有静止和流动两个变种的实际流体。在此教程中,我们将其称为“酸”。缺失的引用稍后补全。
  
-<code java [enable_line_numbers="true"]> +<yarncode java [enable_line_numbers="true"]> 
-public abstract class AcidFluid extends TutorialFluid +public abstract class AcidFluid extends TutorialFluid {
-{+
  @Override  @Override
- public Fluid getStill() + public class_3611 method_15751() { 
- + return YOUR_STILL_FLUID_HERE;
- return <YOUR_STILL_FLUID_HERE>;+
  }  }
- +
  @Override  @Override
- public Fluid getFlowing() + public class_3611 method_15750() { 
- + return YOUR_FLOWING_FLUID_HERE;
- return <YOUR_FLOWING_FLUID_HERE>;+
  }  }
- +
  @Override  @Override
- public Item getBucketItem() + public class_1792 method_15774() { 
- + return YOUR_BUCKET_ITEM_HERE;
- return <YOUR_BUCKET_ITEM_HERE>;+
  }  }
- +
  @Override  @Override
- protected BlockState toBlockState(FluidState fluidState) + protected class_2680 method_15790(class_3610 fluidState) { 
- { + return YOUR_FLUID_BLOCK_HERE.method_9564().method_11657(class_2741.field_12538, method_15741(fluidState));
- // method_15741 converts the LEVEL_1_8 of the fluid state to the LEVEL_15 the fluid block uses +
- return <YOUR_FLUID_BLOCK_HERE>.getDefaultState().with(Properties.LEVEL_15, method_15741(fluidState));+
  }  }
-  + 
- public static class Flowing extends AcidFluid + public static class Flowing extends AcidFluid {
- {+
  @Override  @Override
- protected void appendProperties(StateManager.Builder<FluidFluidState> builder) + protected void method_15775(class_2689.class_2690<class_3611class_3610> builder) { 
- + super.method_15775(builder); 
- super.appendProperties(builder); + builder.method_11667(field_15900);
- builder.add(LEVEL);+
  }  }
- +
  @Override  @Override
- public int getLevel(FluidState fluidState) + public int method_15779(class_3610 fluidState) { 
- + return fluidState.method_11654(field_15900);
- return fluidState.get(LEVEL);+
  }  }
- +
  @Override  @Override
- public boolean isStill(FluidState fluidState) + public boolean method_15793(class_3610 fluidState) {
- {+
  return false;  return false;
  }  }
  }  }
-  + 
- public static class Still extends AcidFluid + public static class Still extends AcidFluid {
- {+
  @Override  @Override
- public int getLevel(FluidState fluidState) + public int method_15779(class_3610 fluidState) {
- {+
  return 8;  return 8;
  }  }
- +
  @Override  @Override
- public boolean isStill(FluidState fluidState) + public boolean method_15793(class_3610 fluidState) {
- {+
  return true;  return true;
  }  }
  }  }
 } }
-</code+</yarncode
-接下来,我们将制作静态和动态酸变体的静态实例,以及一个酸桶。 在您的''ModInitializer''中: +接下来,我们将制作静态和动态酸变体的静态实例,以及一个酸桶。在您的 ''ModInitializer'' 中: 
-<code java [enable_line_numbers="true"]> +<yarncode java [enable_line_numbers="true"]> 
-// ... +public static class_3609 STILL_ACID; 
- +public static class_3609 FLOWING_ACID; 
-public static FlowableFluid STILL_ACID; +public static class_1792 ACID_BUCKET; 
-public static FlowableFluid FLOWING_ACID; + 
- +
-public static Item ACID_BUCKET; +
- +
-// ... +
 @Override @Override
-public void onInitialize() +public void onInitialize() { 
-{ + STILL_ACID = class_2378.method_10230(class_7923.field_41173, new class_2960("tutorial", "acid"), new AcidFluid.Still()); 
- // ... + FLOWING_ACID = class_2378.method_10230(class_7923.field_41173, new class_2960("tutorial", "flowing_acid"), new AcidFluid.Flowing()); 
-  + ACID_BUCKET = class_2378.method_10230(class_7923.field_41178, new class_2960("tutorial", "acid_bucket"),  
- STILL_ACID = Registry.register(Registry.FLUID, new Identifier(MOD_ID, "acid"), new AcidFluid.Still()); +        new class_1755(STILL_ACID, new class_1792.class_1793().method_7896(class_1802.field_8550).method_7889(1))); 
-  + 
- FLOWING_ACID = Registry.register(Registry.FLUID, new Identifier(MOD_ID, "flowing_acid"), new AcidFluid.Flowing()); +
-  +
- ACID_BUCKET = Registry.register(Registry.ITEM, new Identifier(MOD_ID, "acid_bucket"), new BucketItem(STILL_ACID, new Item.Settings().recipeRemainder(Items.BUCKET).maxCount(1))); +
- +
  // ...  // ...
 } }
 + 
 // ... // ...
-</code>+</yarncode>
  
-为了使自定义流体表现得像水或熔岩,您必须将其添加到相应的流体标签中:对于水,制作''data/minecraft/tags/fluids/ water.json''文件,并在其中写入流体的标识符+为了使自定义流体表现得像水或熔岩,您必须将其添加到相应的流体标签中:对于水,制作 ''data/minecraft/tags/fluids/water.json'' 文件,并在其中写入流体 id
 <code json [enable_line_numbers="true"]> <code json [enable_line_numbers="true"]>
 { {
Line 190: Line 158:
  "values":  "values":
  [  [
- "your_mod_id:acid", + "tutorial:acid", 
- "your_mod_id:flowing_acid"+ "tutorial:flowing_acid"
  ]  ]
 } }
Line 198: Line 166:
  
 ==== 制作一个流体方块 ==== ==== 制作一个流体方块 ====
-接下来,我们需要在世界中创建表示酸的方块。''net.minecraft.block.FluidBlock''是我们需要使用的类,但由于其构造器受保护,我们不能直接构造它。一种解决方法是制作子类或者匿名子类。这里我们展示后一种方式。在您的''ModInitializer''中: +接下来,我们需要在世界中创建表示酸的方块。''<yarn net.minecraft.class_2404>'' 是我们需要使用的类,但由于其构造器受保护,我们不能直接构造它。一种解决方法是制作子类或者匿名子类。这里我们展示后一种方式。在您的 ''ModInitializer'' 中: 
-<code java [enable_line_numbers="true"]> +<yarncode java [enable_line_numbers="true"]> 
-// ... +public static class_2248 ACID;
- +
-public static Block ACID; +
- +
-// ...+
  
 @Override @Override
-public void onInitialize() +public void onInitialize() { 
-{ + ACID = class_2378.method_10230(class_7923.field_41175, new class_2960("tutorial", "acid"), new class_2404(STILL_ACID, FabricBlockSettings.method_9630(class_2246.field_10382)){});
- // ... +
-  +
- ACID = Registry.register(Registry.BLOCK, new Identifier(MOD_ID, "acid"), new FluidBlock(STILL_ACID, FabricBlockSettings.copy(Blocks.WATER)){});+
   
  // ...  // ...
-}+ 
 +</yarncode>
  
-// ...     +既然我们有了这些静态对象,我们回到 ''AcidFluid'' 并补全被重写的方法: 
-</code> +<yarncode java [enable_line_numbers="true"]> 
- +public abstract class AcidFluid extends TutorialFluid {
-既然我们有了这些静态对象,我们回到''AcidFluid''并补全被重写的方法: +
-<code java [enable_line_numbers="true"]> +
-public abstract class AcidFluid extends TutorialFluid +
-{+
  @Override  @Override
- public Fluid getStill() + public class_3611 method_15751() {
- {+
  return TutorialMod.STILL_ACID;  return TutorialMod.STILL_ACID;
  }  }
- + 
  @Override  @Override
- public Fluid getFlowing() + public class_3611 method_15750() {
- {+
  return TutorialMod.FLOWING_ACID;  return TutorialMod.FLOWING_ACID;
  }  }
- + 
  @Override  @Override
- public Item getBucketItem() + public class_1792 method_15774() {
- {+
  return TutorialMod.ACID_BUCKET;  return TutorialMod.ACID_BUCKET;
  }  }
- + 
  @Override  @Override
- protected BlockState toBlockState(FluidState fluidState) + protected class_2680 method_15790(class_3610 fluidState) { 
- + // method_15741 将流体状态的 LEVEL_1_8 转换为流体方块使用的 LEVEL_15 
- // method_15741 converts the LEVEL_1_8 of the fluid state to the LEVEL_15 the fluid block uses + return TutorialMod.ACID.method_9564().method_11657(class_2741.field_12538, method_15741(fluidState)); 
- return TutorialMod.ACID.getDefaultState().with(Properties.LEVEL_15, method_15741(fluidState));+
 + 
 + public static class Flowing extends AcidFluid { 
 + @Override 
 + protected void method_15775(class_2689.class_2690<class_3611, class_3610> builder) { 
 + super.method_15775(builder); 
 + builder.method_11667(field_15900); 
 +
 + 
 + @Override 
 + public int method_15779(class_3610 fluidState) { 
 + return fluidState.method_11654(field_15900); 
 +
 + 
 + @Override 
 + public boolean method_15793(class_3610 fluidState) { 
 + return false; 
 + }
  }  }
-  + 
- // ... + public static class Still extends AcidFluid { 
-    + @Override 
-</code>+ public int method_15779(class_3610 fluidState) { 
 + return 8; 
 +
 + 
 + @Override 
 + public boolean method_15793(class_3610 fluidState) { 
 + return true; 
 +
 + } 
 +  
 +</yarncode>
 ===== 渲染设置 ===== ===== 渲染设置 =====
-为了让流体拥有材质,或者与一个颜色绑定,你需要为其注册一个''FluidRenderHandler''。这里,我们重用水的材质,并仅仅改变用于其上的颜色。为确保材质渲染为半透明的,你可以使用Fabric的''BlockRenderLayerMap''+为了让流体拥有纹理,或者与一个颜色绑定,你需要为其注册一个''FluidRenderHandler''。这里,我们重用水的纹理,并仅仅改变用于其上的颜色。为确保纹理渲染为半透明的,你可以使用 Fabric 的 ''BlockRenderLayerMap'' 
 + 
 +<yarncode java [enable_line_numbers="true"]> 
 +@Environment(EnvType.CLIENT) 
 +public class TutorialModClient implements ClientModInitializer {
  
-<code java [enable_line_numbers="true"]> 
-public class TutorialModClient implements ClientModInitializer 
-{ 
- // ... 
-  
  @Override  @Override
- public void onInitializeClient() + public void onInitializeClient() { 
- + FluidRenderHandlerRegistry.INSTANCE.register(TutorialMod.STILL_ACID, TutorialMod.FLOWING_ACID, new SimpleFluidRenderHandler( 
- // ..+ new class_2960("minecraft:block/water_still"), 
-  + new class_2960("minecraft:block/water_flow"), 
- setupFluidRendering(TutorialMod.STILL_ACID, TutorialMod.FLOWING_ACID, new Identifier("minecraft", "water"), 0x4CC248); + 0x4CC248 
- BlockRenderLayerMap.INSTANCE.putFluids(RenderLayer.getTranslucent(), TutorialMod.STILL_ACID, TutorialMod.FLOWING_ACID); + )); 
- + 
 + BlockRenderLayerMap.INSTANCE.putFluids(class_1921.method_23583(), TutorialMod.STILL_ACID, TutorialMod.FLOWING_ACID); 
 + 
 + //if you want to use custom textures they needs to be registered. 
 + //In this example this is unnecessary because the vanilla water textures are already registered. 
 + //To register your custom textures use this method. 
 + //ClientSpriteRegistryCallback.event(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE).register((atlasTexture, registry) -> { 
 + //    registry.register(new Identifier("tutorial:block/custom_fluid_still")); 
 + //    registry.register(new Identifier("tutorial:block/custom_fluid_flowing")); 
 + //}); 
  // ...  // ...
  }  }
-  
- // ... 
-  
- public static void setupFluidRendering(final Fluid still, final Fluid flowing, final Identifier textureFluidId, final int color) 
- { 
- final Identifier stillSpriteId = new Identifier(textureFluidId.getNamespace(), "block/" + textureFluidId.getPath() + "_still"); 
- final Identifier flowingSpriteId = new Identifier(textureFluidId.getNamespace(), "block/" + textureFluidId.getPath() + "_flow"); 
-  
- // If they're not already present, add the sprites to the block atlas 
- ClientSpriteRegistryCallback.event(SpriteAtlasTexture.BLOCK_ATLAS_TEX).register((atlasTexture, registry) -> 
- { 
- registry.register(stillSpriteId); 
- registry.register(flowingSpriteId); 
- }); 
-  
- final Identifier fluidId = Registry.FLUID.getId(still); 
- final Identifier listenerId = new Identifier(fluidId.getNamespace(), fluidId.getPath() + "_reload_listener"); 
-  
- final Sprite[] fluidSprites = { null, null }; 
-  
- ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() 
- { 
- @Override 
- public Identifier getFabricId() 
- { 
- return listenerId; 
- } 
-  
- /** 
- * Get the sprites from the block atlas when resources are reloaded 
- */ 
- @Override 
- public void apply(ResourceManager resourceManager) 
- { 
- final Function<Identifier, Sprite> atlas = MinecraftClient.getInstance().getSpriteAtlas(SpriteAtlasTexture.BLOCK_ATLAS_TEX); 
- fluidSprites[0] = atlas.apply(stillSpriteId); 
- fluidSprites[1] = atlas.apply(flowingSpriteId); 
- } 
- }); 
-  
- // The FluidRenderer gets the sprites and color from a FluidRenderHandler during rendering 
- final FluidRenderHandler renderHandler = new FluidRenderHandler() 
- { 
- @Override 
- public Sprite[] getFluidSprites(BlockRenderView view, BlockPos pos, FluidState state) 
- { 
- return fluidSprites; 
- } 
-  
- @Override 
- public int getFluidColor(BlockRenderView view, BlockPos pos, FluidState state) 
- { 
- return color; 
- } 
- }; 
-  
- FluidRenderHandlerRegistry.INSTANCE.register(still, renderHandler); 
- FluidRenderHandlerRegistry.INSTANCE.register(flowing, renderHandler); 
- } 
-  
- // ... 
 } }
-</code>+</yarncode>
  
-如果你需要使用你自己的流体材质,你可以参考原版资源包((''assets/minecraft/blockstates/water.json''\\ ''assets/minecraft/models/block/water.json''\\ ''assets/minecraft/textures/block/water_still.png''\\ ''assets/minecraft/textures/block/water_still.png.mcmeta''\\ ''assets/minecraft/textures/block/water_flow.png''\\ ''assets/minecraft/textures/block/water_flow.png.mcmeta''))作为一个模板。+如果你需要使用你自己的流体纹理,你可以参考原版资源包((''assets/minecraft/blockstates/water.json''\\ ''assets/minecraft/models/block/water.json''\\ ''assets/minecraft/textures/block/water_still.png''\\ ''assets/minecraft/textures/block/water_still.png.mcmeta''\\ ''assets/minecraft/textures/block/water_flow.png''\\ ''assets/minecraft/textures/block/water_flow.png.mcmeta''))作为一个模板。
  
 ===== 在世界中生成 ===== ===== 在世界中生成 =====
zh_cn/tutorial/fluids.txt · Last modified: 2023/05/04 11:31 by solidblock