zh_cn:tutorial:fluids
                Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| zh_cn:tutorial:fluids [2020/11/15 01:20] – [制作一个流体方块] solidblock | zh_cn:tutorial:fluids [2023/05/04 11:31] (current) – [渲染设置] solidblock | ||
|---|---|---|---|
| Line 3: | Line 3: | ||
| 在这里,我们将介绍自定义流体的创建。如果计划创建多个流体,建议创建一个抽象的基本流体类,在其中设置必要的默认值,这些默认值将在其子类中共享。我们还将使其像湖泊一样在世界中生成。 | 在这里,我们将介绍自定义流体的创建。如果计划创建多个流体,建议创建一个抽象的基本流体类,在其中设置必要的默认值,这些默认值将在其子类中共享。我们还将使其像湖泊一样在世界中生成。 | ||
| ===== 创建抽象流体 ===== | ===== 创建抽象流体 ===== | ||
| - | 原版流体扩展了'' | + | 原版流体继承了 '' | 
| - | <code java [enable_line_numbers=" | + | <yarncode  | 
| - | public abstract class TutorialFluid extends  | + | public abstract class TutorialFluid extends  | 
| - | { | + | |
| /** | /** | ||
| - | 	 * @return  | + | 	 * @return  | 
| */ | */ | ||
| @Override | @Override | ||
| - | 	public boolean  | + | 	public boolean  | 
| - | { | + | |
| 		return fluid == getStill() || fluid == getFlowing(); | 		return fluid == getStill() || fluid == getFlowing(); | ||
| } | } | ||
| /** | /** | ||
| - | 	 * @return  | + | 	 * @return  | 
| */ | */ | ||
| @Override | @Override | ||
| - | 	protected boolean  | + | 	protected boolean  | 
| - | { | + | |
| return false; | return false; | ||
| } | } | ||
| /** | /** | ||
| - | * Perform actions when fluid flows into a replaceable block. Water drops | + | * 流体流入一个可替换的方块时的行为。 | 
| - | 	 * the block' | + | * 水会掉落方块的战利品表。熔岩会播放“block.lava.extinguish”音效。 | 
| */ | */ | ||
| @Override | @Override | ||
| - | 	protected void beforeBreakingBlock(WorldAccess  | + | 	protected void method_15730(class_1936  | 
| - | { | + | |
| final BlockEntity blockEntity = state.getBlock().hasBlockEntity() ? world.getBlockEntity(pos) : null; | final BlockEntity blockEntity = state.getBlock().hasBlockEntity() ? world.getBlockEntity(pos) : null; | ||
| 		Block.dropStacks(state, | 		Block.dropStacks(state, | ||
| Line 37: | Line 33: | ||
| /** | /** | ||
| - | 	 * Lava returns true if its FluidState  | + | 	 * 熔岩在其  | 
| - | * Fluid is Water. | + | |
| * | * | ||
| - | 	 * @return  | + | 	 * @return  | 
| */ | */ | ||
| @Override | @Override | ||
| - | 	protected boolean  | + | 	protected boolean  | 
| - | { | + | |
| return false; | return false; | ||
| } | } | ||
| /** | /** | ||
| - | * Possibly related to the distance checks for flowing into nearby holes? | + | * 或许与流入周围附近凹洞的距离检查有关? | 
| - | 	 * Water returns  | + | * 水返回4。熔岩在主世界返回2,而在下界返回4。 | 
| */ | */ | ||
| @Override | @Override | ||
| - | 	protected int getFlowSpeed(WorldView  | + | 	protected int method_15733(class_4538  | 
| - | { | + | |
| return 4; | return 4; | ||
| } | } | ||
| /** | /** | ||
| - | 	 * Water returns  | + | * 返回每次流动一格,其等级减少的数值。水返回1,熔岩在主世界返回2,在下界返回1。 | 
| */ | */ | ||
| @Override | @Override | ||
| - | 	protected int getLevelDecreasePerBlock(WorldView  | + | 	protected int method_15739(class_4538  | 
| - | { | + | |
| return 1; | return 1; | ||
| } | } | ||
| /** | /** | ||
| - | 	 * Water returns  | + | * 返回每流一格需要花费的时间(按刻计算)。水返回5。熔岩在主世界返回30,在下界返回10。 | 
| */ | */ | ||
| @Override | @Override | ||
| - | 	public int getTickRate(WorldView  | + | 	public int method_15789(class_4538  | 
| - | { | + | |
| return 5; | return 5; | ||
| } | } | ||
| /** | /** | ||
| - | 	 * Water and Lava both return  | + | * 返回爆炸抗性。水和熔岩都返回100.0F。 | 
| */ | */ | ||
| @Override | @Override | ||
| - | protected float getBlastResistance() | + | protected float method_15784() { | 
| - | { | + | |
| return 100.0F; | return 100.0F; | ||
| } | } | ||
| } | } | ||
| - | </code> | + | </yarncode> | 
| - | ===== 进行  | + | ===== 实现  | 
| 现在让我们制作一个拥有静止和流动两个变种的实际流体。在此教程中,我们将其称为“酸”。缺失的引用稍后补全。 | 现在让我们制作一个拥有静止和流动两个变种的实际流体。在此教程中,我们将其称为“酸”。缺失的引用稍后补全。 | ||
| - | <code java [enable_line_numbers=" | + | <yarncode  | 
| - | public abstract class AcidFluid extends TutorialFluid | + | public abstract class AcidFluid extends TutorialFluid { | 
| - | { | + | |
| @Override | @Override | ||
| - | 	public  | + | 	public  | 
| - | { | + | 		return YOUR_STILL_FLUID_HERE; | 
| - | 		return  | + | |
| } | } | ||
| - | + | ||
| @Override | @Override | ||
| - | 	public  | + | 	public  | 
| - | { | + | 		return YOUR_FLOWING_FLUID_HERE; | 
| - | 		return  | + | |
| } | } | ||
| - | + | ||
| @Override | @Override | ||
| - | 	public  | + | 	public  | 
| - | { | + | 		return YOUR_BUCKET_ITEM_HERE; | 
| - | 		return  | + | |
| } | } | ||
| - | + | ||
| @Override | @Override | ||
| - | 	protected  | + | 	protected  | 
| - | { | + | 		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  | + | |
| } | } | ||
| - | + | ||
| - | public static class Flowing extends AcidFluid | + | public static class Flowing extends AcidFluid { | 
| - | { | + | |
| @Override | @Override | ||
| - | protected void appendProperties(StateManager.Builder<Fluid, FluidState> builder) | + | protected void method_15775(class_2689.class_2690<class_3611, class_3610> builder) { | 
| - | { | + | 			super.method_15775(builder); | 
| - | 			super.appendProperties(builder); | + | builder.method_11667(field_15900); | 
| - | builder.add(LEVEL); | + | |
| } | } | ||
| - | + | ||
| @Override | @Override | ||
| - | 		public int getLevel(FluidState  | + | 		public int method_15779(class_3610  | 
| - | { | + | return fluidState.method_11654(field_15900); | 
| - | return fluidState.get(LEVEL); | + | |
| } | } | ||
| - | + | ||
| @Override | @Override | ||
| - | 		public boolean  | + | 		public boolean  | 
| - | { | + | |
| return false; | return false; | ||
| } | } | ||
| } | } | ||
| - | + | ||
| - | public static class Still extends AcidFluid | + | public static class Still extends AcidFluid { | 
| - | { | + | |
| @Override | @Override | ||
| - | 		public int getLevel(FluidState  | + | 		public int method_15779(class_3610  | 
| - | { | + | |
| return 8; | return 8; | ||
| } | } | ||
| - | + | ||
| @Override | @Override | ||
| - | 		public boolean  | + | 		public boolean  | 
| - | { | + | |
| return true; | return true; | ||
| } | } | ||
| } | } | ||
| } | } | ||
| - | </code> | + | </yarncode> | 
| - | 接下来,我们将制作静态和动态酸变体的静态实例,以及一个酸桶。 在您的'' | + | 接下来,我们将制作静态和动态酸变体的静态实例,以及一个酸桶。在您的 '' | 
| - | <code java [enable_line_numbers=" | + | <yarncode  | 
| - | // ... | + | public static  | 
| - | + | public static  | |
| - | public static  | + | public static  | 
| - | public static  | + | |
| - | + | ||
| - | public static  | + | |
| - | + | ||
| - | // ... | + | |
| @Override | @Override | ||
| - | public void onInitialize() | + | public void onInitialize() { | 
| - | { | + | 	STILL_ACID = class_2378.method_10230(class_7923.field_41173, new class_2960(" | 
| - | // ... | + | 	FLOWING_ACID = class_2378.method_10230(class_7923.field_41173, new class_2960(" | 
| - | + | 	ACID_BUCKET = class_2378.method_10230(class_7923.field_41178, new class_2960(" | |
| - | 	STILL_ACID = Registry.register(Registry.FLUID, new Identifier(MOD_ID, " | + |          | 
| - | + | ||
| - | 	FLOWING_ACID = Registry.register(Registry.FLUID, new Identifier(MOD_ID, " | + | |
| - | + | ||
| - | 	ACID_BUCKET = Registry.register(Registry.ITEM, new Identifier(MOD_ID, " | + | |
| - | + | ||
| // ... | // ... | ||
| } | } | ||
| + | |||
| // ... | // ... | ||
| - | </code> | + | </yarncode> | 
| - | 为了使自定义流体表现得像水或熔岩,您必须将其添加到相应的流体标签中:对于水,制作'' | + | 为了使自定义流体表现得像水或熔岩,您必须将其添加到相应的流体标签中:对于水,制作 '' | 
| <code json [enable_line_numbers=" | <code json [enable_line_numbers=" | ||
| { | { | ||
| Line 190: | Line 158: | ||
| 	" | 	" | ||
| [ | [ | ||
| - | 		"your_mod_id: | + | 		"tutorial: | 
| - | 		"your_mod_id: | + | 		"tutorial: | 
| ] | ] | ||
| } | } | ||
| Line 198: | Line 166: | ||
| ==== 制作一个流体方块 ==== | ==== 制作一个流体方块 ==== | ||
| - | 接下来,我们需要在世界中创建表示酸的方块。'' | + | 接下来,我们需要在世界中创建表示酸的方块。'' | 
| - | <code java [enable_line_numbers=" | + | <yarncode  | 
| - | // ... | + | public static  | 
| - | + | ||
| - | public static  | + | |
| - | + | ||
| - | // ... | + | |
| @Override | @Override | ||
| - | public void onInitialize() | + | public void onInitialize() { | 
| - | { | + | 	ACID = class_2378.method_10230(class_7923.field_41175, new class_2960(" | 
| - | // ... | + | |
| - | + | ||
| - | 	ACID = Registry.register(Registry.BLOCK, new Identifier(MOD_ID, " | + | |
| // ... | // ... | ||
| - | } | + | } | 
| + | </ | ||
| - | // ... | + | 既然我们有了这些静态对象,我们回到 '' | 
| - | </ | + | <yarncode  | 
| - | + | public abstract class AcidFluid extends TutorialFluid { | |
| - | 既然我们有了这些静态对象,我们回到'' | + | |
| - | <code java [enable_line_numbers=" | + | |
| - | public abstract class AcidFluid extends TutorialFluid | + | |
| - | { | + | |
| @Override | @Override | ||
| - | 	public  | + | 	public  | 
| - | { | + | |
| 		return TutorialMod.STILL_ACID; | 		return TutorialMod.STILL_ACID; | ||
| } | } | ||
| - | + | ||
| @Override | @Override | ||
| - | 	public  | + | 	public  | 
| - | { | + | |
| 		return TutorialMod.FLOWING_ACID; | 		return TutorialMod.FLOWING_ACID; | ||
| } | } | ||
| - | + | ||
| @Override | @Override | ||
| - | 	public  | + | 	public  | 
| - | { | + | |
| 		return TutorialMod.ACID_BUCKET; | 		return TutorialMod.ACID_BUCKET; | ||
| } | } | ||
| - | + | ||
| @Override | @Override | ||
| - | 	protected  | + | 	protected  | 
| - | { | + | 		// method_15741  | 
| - | 		// method_15741  | + | 		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)); | + | |
| } | } | ||
| - | |||
| - | // ... | ||
| - | }     | ||
| - | </ | ||
| - | ===== Rendering setup ===== | ||
| - | 是时候做客户端的事情了。 在** ClientModInitializer **中,您需要为流体指定精灵的位置并定义其渲染。 我将重复使用水纹理,只是更改应用于它们的颜色。 | + | public static class Flowing extends AcidFluid { | 
| - | <code java> | + | @Override | 
| - |      | + | 		protected  | 
| - |      | + | super.method_15775(builder); | 
| - | { | + | builder.method_11667(field_15900); | 
| - | + | } | |
| - | // adding the sprites to the block texture atlas | + | |
| - | ClientSpriteRegistryCallback.event(SpriteAtlasTexture.BLOCK_ATLAS_TEX).register((spriteAtlasTexture, registry) -> { | + | |
| - | + | ||
| - |             Identifier stillSpriteLocation = new Identifier(" | + | |
| - |             Identifier dynamicSpriteLocation = new Identifier(" | + | |
| - | // here I tell to use only 16x16 area of the water texture | + | |
| - |             FabricSprite stillAcidSprite = new FabricSprite(stillSpriteLocation, | + | |
| - | // same, but 32 | + | |
| - |             FabricSprite dynamicAcidSprite = new FabricSprite(dynamicSpriteLocation, | + | |
| - | + | ||
| - | registry.register(stillAcidSprite); | + | |
| - |              | + | |
| - | + | ||
| - | + | ||
| - | // this renderer is responsible for drawing fluids in a world | + | |
| - | FluidRenderHandler acidRenderHandler = new FluidRenderHandler() | + | |
| - | { | + | |
| - |                 // return the sprites: still sprite goes first into the array, flowing/ | + | |
| - | @Override | + | |
| - |                 public Sprite[] getFluidSprites(ExtendedBlockView extendedBlockView, | + | |
| - | { | + | |
| - |                     return new Sprite[] {stillAcidSprite, | + | |
| - |                  | + | |
| - | // apply light green color | + | @Override | 
| - |                  | + | public int method_15779(class_3610 fluidState) { | 
| - | public int getFluidColor(ExtendedBlockView view, BlockPos pos, FluidState state) | + | 			return  | 
| - |                  | + | } | 
| - |                     return  | + | |
| - | } | + | |
| - | }; | + | |
| - | // registering the same renderer for both fluid variants is intentional | + | @Override | 
| + | public boolean method_15793(class_3610 fluidState) { | ||
| + | return false; | ||
| + | } | ||
| + | } | ||
| - |             FluidRenderHandlerRegistry.INSTANCE.register(Mod.stillAcid, | + | public static class Still extends AcidFluid { | 
| - |              | + | @Override | 
| - | }); | + | public int method_15779(class_3610 fluidState) { | 
| + | return 8; | ||
| + | } | ||
| - | </code> | + | @Override | 
| + | public boolean method_15793(class_3610 fluidState) { | ||
| + | return true; | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | </yarncode> | ||
| + | ===== 渲染设置 ===== | ||
| + | 为了让流体拥有纹理,或者与一个颜色绑定,你需要为其注册一个'' | ||
| - | 然后剩下要做的就是创建必要的Json文件和纹理,但是您现在应该知道该怎么做。 | + | < | 
| + | @Environment(EnvType.CLIENT) | ||
| + | public class TutorialModClient implements ClientModInitializer { | ||
| - | ===== Generation in a world ===== | + | @Override | 
| + | public void onInitializeClient() { | ||
| + | 		FluidRenderHandlerRegistry.INSTANCE.register(TutorialMod.STILL_ACID, | ||
| + | 				new class_2960(" | ||
| + | 				new class_2960(" | ||
| + | 0x4CC248 | ||
| + | )); | ||
| - | 要在世界上产生酸湖,可以使用在ModInitializer中创建的** net.minecraft.world.gen.feature.LakeFeature **: | + | BlockRenderLayerMap.INSTANCE.putFluids(class_1921.method_23583(), TutorialMod.STILL_ACID, TutorialMod.FLOWING_ACID); | 
| - | <code java> | + | |
| - | + | ||
| - |         LakeFeature acidFeature = Registry.register(Registry.FEATURE, new Identifier(MODID," | + | |
| + | //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. | ||
| + | 		// | ||
| + | 		//    registry.register(new Identifier(" | ||
| + | 		//    registry.register(new Identifier(" | ||
| + | //}); | ||
| + | |||
| + | // ... | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | 如果你需要使用你自己的流体纹理,你可以参考原版资源包(('' | ||
| + | |||
| + | ===== 在世界中生成 ===== | ||
| + | 为使得酸湖在世界中生成,你可以在你的'' | ||
| + | |||
| + | <code java [enable_line_numbers=" | ||
| + | // ... | ||
| + | |||
| + | public static LakeFeature ACID_LAKE; | ||
| + | |||
| + | // ... | ||
| + | |||
| + | @Override | ||
| + | public void onInitialize() | ||
| + | { | ||
| + | // ... | ||
| + | |||
| + | 	ACID_LAKE = Registry.register(Registry.FEATURE, | ||
| + | |||
| + | // 在沼泽中生成,类似于水湖,但是概率为40(数字越高,生成几率越低) | ||
| + | Biomes.SWAMP.addFeature( | ||
| + | 		GenerationStep.Feature.LOCAL_MODIFICATIONS, | ||
| + | ACID_LAKE.configure(new SingleStateFeatureConfig(ACID.getDefaultState())) | ||
| + | .createDecoratedFeature(Decorator.WATER_LAKE.configure(new ChanceDecoratorConfig(40))) | ||
| + | ); | ||
| + | |||
| + | // ... | ||
| + | } | ||
| + | |||
| + | // ... | ||
| </ | </ | ||
| - | 然后将其放入所需的生物群系中以生成: | ||
| - | <code java> | ||
| - | // I tell it to generate like water lakes, with a rarity of 40 (the higher is the number, the lesser is the generation chance): | ||
| - |         Biomes.FOREST.addFeature(GenerationStep.Feature.LOCAL_MODIFICATIONS, | ||
| - | </ | ||
| - | 本教程到此结束。 | ||
zh_cn/tutorial/fluids.1605403225.txt.gz · Last modified: 2020/11/15 01:20 by solidblock