User Tools

Site Tools


zh_cn:tutorial:trees

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:trees [2021/07/14 17:07] – [Creating a TreeDecoratorType] breakicezh_cn:tutorial:trees [2022/08/18 03:40] – [添加树木 [1.17](高级)] solidblock
Line 1: Line 1:
 +FIXME 本文有一段时间没有更新了,可能对未来版本不起作用。请参考[[tutorial:trees|英文页面]]。
 +
 ===== 添加树木 [1.17](高级) ===== ===== 添加树木 [1.17](高级) =====
 阅读本文之前,建议先学习如何创建一个特征地形。\\ 阅读本文之前,建议先学习如何创建一个特征地形。\\
-参见[[zh_cn:tutorial:features]]+参见 [[zh_cn:tutorial:features]]
  
-树木是在你的mod中拓展原版世界生成的一个好方法。\\+树木是在你的 mod 中拓展原版世界生成的一个好方法。\\
 注意本话题较为高级,因此开始之前,最好要有关于修改世界生成的丰富经验。 注意本话题较为高级,因此开始之前,最好要有关于修改世界生成的丰富经验。
- 
-==== 关于API ==== 
-有个API可以让你非常方便的添加树木,但是他还在开发中,<del>但在2000年之后,相信我们的天神modmuss50从苍穹之空下凡审查了pull request之后,就可以使用了</del> 
- 
-PR[[https://github.com/FabricMC/fabric/pull/1507|见此处。]]. 
  
 ===== 创建简单的树木 ===== ===== 创建简单的树木 =====
Line 25: Line 22:
 如果想让树木长得不那么像是原版的树木,可以选择创建自定义的实现。但是实际上原版的实现通常足够模组的开发了。 如果想让树木长得不那么像是原版的树木,可以选择创建自定义的实现。但是实际上原版的实现通常足够模组的开发了。
  
-==== 创建ConfiguredFeature ==== +==== 创建 ConfiguredFeature ==== 
-不需要创建新的''Feature'',因为原版的''TreeFeature''可以配置。+不需要创建新的 ''Feature'' ,因为原版的 ''TreeFeature'' 可以配置
  
-把这个添加到你的''ModInitializer'''主体:+把这个添加到你的 ''ModInitializer'' 主体:
  
 <code java> <code java>
Line 45: Line 42:
 </code> </code>
  
-现在只需要像往常那样向游戏注册''ConfiguredFeature''然后用Fabric的API修改生物群系:+现在只需要像往常那样向游戏注册 ''ConfiguredFeature'' 然后用 FabricAPI 修改生物群系:
  
 <code java> <code java>
Line 54: Line 51:
   Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, treeRich.getValue(), TREE_RICH);   Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, treeRich.getValue(), TREE_RICH);
  
-  // 应该为树木使用VEGETAL_DECORATION生成步骤+  // 应该为树木使用 VEGETAL_DECORATION 生成步骤
   BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Feature.VEGETAL_DECORATION, treeRich);   BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Feature.VEGETAL_DECORATION, treeRich);
 } }
Line 60: Line 57:
  
 ==== 创建树苗 ==== ==== 创建树苗 ====
-树苗是生长树木的一类特殊方块,需要''SaplingGenerator''\\+树苗是生长树木的一类特殊方块,需要 ''SaplingGenerator''
  
-=== 创建SaplingGenerator === +=== 创建 SaplingGenerator === 
-简单的生成器接收树木的''ConfiguredFeature''并将其返回,如下所示:+简单的生成器接收树木的 ''ConfiguredFeature'' 并将其返回,如下所示:
  
 <code java> <code java>
Line 83: Line 80:
 后面会展示高级的''SaplingGenerator''的例子。 后面会展示高级的''SaplingGenerator''的例子。
  
-=== 创建SaplingBlock === +=== 创建 SaplingBlock === 
-创建方块本身需要继承''SaplingBlock''类,而不是直接将其实例化,因为其构造器的访问权限是protected的。+创建方块本身需要继承''SaplingBlock''类,而不是直接将其实例化,因为其构造器的访问权限是 protected 的。
  
 <code java> <code java>
Line 95: Line 92:
  
 === 注册SaplingBlock === === 注册SaplingBlock ===
-要注册树苗,按照注册方块的以下步骤(参见[[zh_cn:tutorial:blocks]]),但传入带有''ConfiguredFeature''的生成器的实例。+要注册树苗,按照注册方块的以下步骤(参见[[zh_cn:tutorial:blocks]]),但传入带有 ''ConfiguredFeature'' 的生成器的实例。
  
 把这个放在用于你的树苗方块的类中: 把这个放在用于你的树苗方块的类中:
Line 109: Line 106:
 </code> </code>
  
-===== 创建TrunkPlacer ===== +===== 创建 TrunkPlacer ===== 
-''TrunkPlacer''创建由''BlockStateProvider''提供的树干方块。+''TrunkPlacer'' 创建由 ''BlockStateProvider'' 提供的树干方块。
  
-==== 原版TrunkPlacers ==== +==== 原版 TrunkPlacers ==== 
-在创建''TrunkPlacer''之前,先看看可以从原版复用的原版''TrunkPlacer''避免做重复的工作:+在创建 ''TrunkPlacer'' 之前,先看看可以从原版复用的 ''TrunkPlacer'' 避免做重复的工作:
  
   * ''StraightTrunkPlacer''   * ''StraightTrunkPlacer''
Line 121: Line 118:
  
 ==== 创建TrunkPlacerType ==== ==== 创建TrunkPlacerType ====
-往游戏注册''TrunkPlacer''需要''TrunkPlacerType''+往游戏注册 ''TrunkPlacer'' 需要 ''TrunkPlacerType''
  
-可惜Fabric API目前没有用于创建和注册''TrunkPlacer''的API,所以我们需要使用mixins。+可惜 FabricAPI 目前没有用于创建和注册''TrunkPlacer''的API,所以我们需要使用mixins。
  
-我们准备创建一个调用器(见[[https://github.com/2xsaiko/mixin-cheatsheet/blob/master/invoker.md]])来调用私有静态的''TrunkPlacerType.register''方法。+我们准备创建一个调用器(invoker)(见[[https://github.com/2xsaiko/mixin-cheatsheet/blob/master/invoker.md]])来调用私有静态的 ''TrunkPlacerType.register'' 方法。
  
-以下是我们的mixin,不要忘记加到mixin配置中:+以下是我们的 mixin ,不要忘记加到 mixin 配置中:
  
 <code java> <code java>
Line 140: Line 137:
 </code> </code>
  
-==== 创建TrunkPlacer ==== +==== 创建 TrunkPlacer ==== 
-''TrunkPlacer''包含:+''TrunkPlacer'' 包含:
  
-  * 用于序列化的编码解码器。编码解码器(codec)是其自己的话题,这里我们只需要使用''fillTrunkPlacerFields''方法来生成。 +  * 用于序列化的编码解码器。编码解码器(codec)是其自己的话题(topic),这里我们只需要使用 ''fillTrunkPlacerFields'' 方法来生成。 
-  * 获取器(getter),返回''TrunkPlacerType''。 +  * 获取器(getter),返回 ''TrunkPlacerType'' 。 
-  * ''generate''方法,该方法中放置树干并返回''TreeNode''列表,用于树叶放置器放置树木。+  * ''generate'' 方法,该方法中放置树干并返回 ''TreeNode'' 列表,用于树叶放置器放置树木。
  
-''TrunkPlacer''将在世界中创建两个对角线形的树干:+''TrunkPlacer'' 将在世界中创建两个对角线形的树干:
  
 <code java> <code java>
Line 169: Line 166:
         this.setToDirt(world, replacer, random, startPos.down(), config);         this.setToDirt(world, replacer, random, startPos.down(), config);
                  
-        // 迭代到树干高度限制,并使用TrunkPlacer中的getAndSetState方法放置两个方块+        // 迭代到树干高度限制,并使用 TrunkPlacer 中的 getAndSetState 方法放置两个方块
         for (int i = 0; i < height; i++) {         for (int i = 0; i < height; i++) {
             this.getAndSetState(world, replacer, random, startPos.up(i), config);             this.getAndSetState(world, replacer, random, startPos.up(i), config);
Line 176: Line 173:
  
         // 创建两个树木节点——一个用于第一个树干,另一个用于第二个         // 创建两个树木节点——一个用于第一个树干,另一个用于第二个
-        // 将树干中最高的方块设为中心坐标给FoliagePlacer使用+        // 将树干中最高的方块设为中心坐标给 FoliagePlacer 使用
         return ImmutableList.of(new FoliagePlacer.TreeNode(startPos.up(height), 0, false),         return ImmutableList.of(new FoliagePlacer.TreeNode(startPos.up(height), 0, false),
                                 new FoliagePlacer.TreeNode(startPos.east().north().up(height), 0, false));                                 new FoliagePlacer.TreeNode(startPos.east().north().up(height), 0, false));
Line 184: Line 181:
  
 ==== 注册并使用TrunkPlacer ==== ==== 注册并使用TrunkPlacer ====
-使用你的调用器,为你的''TrunkPlacer''创建并注册''TrunkPlacerType''的实例。把这个放到你的''ModInitializer''主体中:+使用你的调用器,为你的 ''TrunkPlacer'' 创建并注册 ''TrunkPlacerType'' 的实例。把这个放到你的 ''ModInitializer'' 主体中:
  
 <code java> <code java>
Line 190: Line 187:
 </code> </code>
  
-现在将你的''StraightTrunkPlacer''替换为你刚创建的''RichTrunkPlacer''就好了:+现在将你的 ''StraightTrunkPlacer'' 替换为你刚创建的 ''RichTrunkPlacer'' 就好了:
 <code java> <code java>
 [...] [...]
Line 198: Line 195:
  
 ===== 创建FoliagePlacer ===== ===== 创建FoliagePlacer =====
-''FoliagePlacer''会从由''BlockStateProvider''提供的方块创建树叶。+''FoliagePlacer'' 会从由 ''BlockStateProvider'' 提供的方块创建树叶,如果你提供钻石矿方块的话或许会变成钻石矿树叶。竟然会如此的闪耀!
  
 ==== 原版FoliagePlacer ==== ==== 原版FoliagePlacer ====
-创建''FoliagePlacer''之前,看看可直接使用的原版''FoliagePlacer''以避免另起炉灶+创建 ''FoliagePlacer'' 之前,看看可直接使用的原版 ''FoliagePlacer'' 以避免重复造轮子
  
   * ''BlobFoliagePlacer''   * ''BlobFoliagePlacer''
Line 207: Line 204:
   * ''RandomSpreadFoliagePlacer''   * ''RandomSpreadFoliagePlacer''
  
-==== 创建FoliagePlacerType ==== +==== 创建 FoliagePlacerType ==== 
-往游戏中注册''FoliagePlacer''需要''FoliagePlacerType''+往游戏中注册 ''FoliagePlacer'' 需要 ''FoliagePlacerType''
  
-和''TrunkPlacerType''类似,Fabric API不提供创建''FoliagePlacerType''的实用功能。我们的mixin看上去几乎相同,不要忘记添加到你的mixin配置+和 ''TrunkPlacerType'' 类似,FabricAPI 不提供创建 ''FoliagePlacerType'' 的实用功能。我们的 mixin 看上去几乎相同,同时不要忘记修改你的 mixin 配置!
  
 <code java> <code java>
Line 222: Line 219:
 </code> </code>
  
-==== 创建FoliagePlacer ==== +==== 创建 FoliagePlacer ==== 
-''FoliagePlacer''比''TrunkPlacer''更加复杂一些,包括:+''FoliagePlacer'' 比 ''TrunkPlacer'' 更加复杂一些,包括:
  
-  * 用于序列化的编码解码器。在此例中我们展示了如何往编码解码器中添加一个额外的IntProvider。 +  * 用于序列化的编码解码器。在此例中我们展示了如何往编码解码器中添加一个额外的 IntProvider。 
-  * 用于获取''FoliagePlacerType''的获取器。 +  * 用于获取 ''FoliagePlacerType'' 的获取器(getter)。 
-  * ''generate''方法,该方法创建树叶。 +  * ''generate'' 方法,该方法创建树叶。 
-  * ''getRandomHeight''方法。不管名字是什么,你通常应该返回你的树叶的最大高度。 +  * ''getRandomHeight'' 方法。不管名字是什么,你通常应该返回你的树叶的最大高度。 
-  * ''isInvalidForLeaves''方法,可以为放置树叶的地方设置限制。+  * ''isInvalidForLeaves'' 方法,可以为放置树叶的地方设置限制。
  
-我们的''FoliagePlacer''会往各个方向(东南西北)创建4行的树叶方块:+我们的 ''FoliagePlacer'' 会往各个方向(东南西北)创建4行的树叶方块:
  
 <code java> <code java>
  
 public class RichFoliagePlacer extends FoliagePlacer { public class RichFoliagePlacer extends FoliagePlacer {
-    // 对于foliageHeight我们使用由IntProvider.createValidatingCodec生成的编码解码器 +    // 对于foliageHeight我们使用由 IntProvider.createValidatingCodec 生成的编码解码器 
-    // 方法参数,我们传入IntProvider的最小值和最大值 +    // 方法参数,我们传入 IntProvider 的最小值和最大值 
-    // 你的TrunkPlacer/FoliagePlacer/TreeDecorator等添加多个域,可调用多次.and。+    // 为了向你的 TrunkPlacer/FoliagePlacer/TreeDecorator 等添加多个域(fields),可调用多次.and。
     //     //
-    // 对于创建我们自己的编码解码器类型的例子,可以参考IntProvider.createValidatingCodec方法的源代码。+    // 如果想创建属于我们自己的编码解码器类型,可以参考 IntProvider.createValidatingCodec 方法的源代码。
     public static final Codec<RichFoliagePlacer> CODEC = RecordCodecBuilder.create(instance ->     public static final Codec<RichFoliagePlacer> CODEC = RecordCodecBuilder.create(instance ->
         fillFoliagePlacerFields(instance)         fillFoliagePlacerFields(instance)
Line 268: Line 265:
  
         for (         for (
-            // 从X开始:中心 - 半径+            // 从 X 开始:中心 - 半径
             Vec3i vec = center.subtract(new Vec3i(radius, 0, 0));             Vec3i vec = center.subtract(new Vec3i(radius, 0, 0));
-            // 在X结束:中心 + 半径+            // 在 X 结束:中心 + 半径
             vec.compareTo(center.add(new Vec3i(radius, 0, 0))) == 0;             vec.compareTo(center.add(new Vec3i(radius, 0, 0))) == 0;
             // 每次移动1             // 每次移动1
Line 284: Line 281:
     @Override     @Override
     public int getRandomHeight(Random random, int trunkHeight, TreeFeatureConfig config) {     public int getRandomHeight(Random random, int trunkHeight, TreeFeatureConfig config) {
-        // 使用IntProvider挑选随机高度+        // 使用 IntProvider 挑选随机高度
         return foliageHeight.get(random);         return foliageHeight.get(random);
     }     }
Line 290: Line 287:
     @Override     @Override
     protected boolean isInvalidForLeaves(Random random, int dx, int y, int dz, int radius, boolean giantTrunk) {     protected boolean isInvalidForLeaves(Random random, int dx, int y, int dz, int radius, boolean giantTrunk) {
-        // 我们的FoliagePlacer不为树叶设置限制+        // 我们的 FoliagePlacer 不为树叶设置限制
         return false;         return false;
     }     }
Line 296: Line 293:
  
 </code> </code>
-==== 注册并使用你的FoliagePlacer ==== +==== 注册并使用你的 FoliagePlacer ==== 
-该过程几乎相同,只需要使用你的调用器创建并注册''FoliagePlacerType''+该过程几乎相同,只需要使用你的调用器(invoker)创建并注册 ''FoliagePlacerType''
  
 <code java> <code java>
Line 303: Line 300:
 </code> </code>
  
-并将旧的''FoliagePlacer''替换成你的新的:+并将旧的 ''FoliagePlacer'' 替换成你的新的:
  
 <code java> <code java>
Line 312: Line 309:
  
 ===== 创建一个 TreeDecorator ===== ===== 创建一个 TreeDecorator =====
-''TreeDecorator'' 允许你添加额外的元素到你的树之中在执行你的 ''TrunkPlacer'' 和 ''FoliagePlacer'' (比如苹果,蜂巢等) //**之后**//。如果你有游戏后台开发经验的话,''TreeDecorator'' 本质上是用于树木的一个后处理器,用于修饰树木的额外信息。+''TreeDecorator'' 允许你添加额外的元素到你的树之中在执行你的 ''TrunkPlacer'' 和 ''FoliagePlacer'' (比如苹果,蜂巢等) //**之后**//。如果你有游戏后台开发经验的话,''TreeDecorator'' 本质上是用于树木的一个后处理器(post-processer),用于修饰树木的额外信息。
  
 ==== 原版的 TreeDecorators ==== ==== 原版的 TreeDecorators ====
Line 318: Line 315:
 和 ''TrunkVineTreeDecorator'' 和 ''TrunkVineTreeDecorator''
  
-虽然这是一件非常繁琐的事情,但是你还是需要创建你自己的 ''TreeDecorator''.+虽然这是一件非常繁琐的事情,但是你还是需要创建你自己的 ''TreeDecorator''
  
 ==== 创建一个 TreeDecoratorType ==== ==== 创建一个 TreeDecoratorType ====
 一个 ''TreeDecoratorType'' 是需要注册到你的 ''TreeDecorator'' 之中的。 一个 ''TreeDecoratorType'' 是需要注册到你的 ''TreeDecorator'' 之中的。
  
-Fabric API 没有提供任何工具用于创建 ''TreeDecoratorType'', 所以我们需要再次使用 mixin 了。+FabricAPI 没有提供任何工具用于创建 ''TreeDecoratorType'', 所以我们需要再次使用 mixin 了。
  
 我们的 mixin 大概会看起来非常像是以下内容,同时不要忘记把他们添加到你自己的 mixin 配置文件当中: 我们的 mixin 大概会看起来非常像是以下内容,同时不要忘记把他们添加到你自己的 mixin 配置文件当中:
Line 337: Line 334:
 </code> </code>
  
-==== Creating the TreeDecorator ==== +==== 创建 TreeDecorator ==== 
-''TreeDecorator'' has an extremely simple structure:+''TreeDecorator'' 有一个特别简单的结构:
  
-  * A codec for serialization, but it's empty by default because the constructor has no arguments. You can always expand it if you want +  * 一个可用于序列化的编码解码器。但默认情况下为空,因为构造函数是没有参数的。如果需要,你可以随时扩展(expand)它。 
-  * A getter for your ''TreeDecoratorType'' +  * 你的 ''TreeDecoratorType'' 的获取器(getter)。 
-  * The ''generate'' method to decorate the tree+  * 为修饰树而存在的 ''generate'' 方法。
  
-Our ''TreeDecorator'' will spawn gold blocks around the trunk of our tree with a 25% chance on a random side of the trunk:+我们的 ''TreeDecorator'' 将在树干周围以 25% 的几率在树干的一侧产生金块(简直不要太爽太炫酷对不对):
  
 <code java> <code java>
 public class RichTreeDecorator extends TreeDecorator { public class RichTreeDecorator extends TreeDecorator {
     public static final RichTreeDecorator INSTANCE = new RichTreeDecorator();     public static final RichTreeDecorator INSTANCE = new RichTreeDecorator();
-    // Our constructor doesn't have any arguments, so we create a unit codec that returns the singleton instance+    // 我们的构造函数没有任何参数,所以我们创建一个单元编解码器,让他返回一个单例对象。
     public static final Codec<RichTreeDecorator> CODEC = Codec.unit(() -> INSTANCE);     public static final Codec<RichTreeDecorator> CODEC = Codec.unit(() -> INSTANCE);
  
Line 359: Line 356:
     @Override     @Override
     public void generate(TestableWorld world, BiConsumer<BlockPos, BlockState> replacer, Random random, List<BlockPos> logPositions, List<BlockPos> leavesPositions) {     public void generate(TestableWorld world, BiConsumer<BlockPos, BlockState> replacer, Random random, List<BlockPos> logPositions, List<BlockPos> leavesPositions) {
-        // Iterate through block positions+        // 遍历方块位置
         for (BlockPos logPosition : logPositions) {         for (BlockPos logPosition : logPositions) {
-            // Pick a value from (inclusive) to (exclusive) and if it'0, continue +            // 选择一个从 0(含)到 4(不含)的值,如果是 0,则继续 
-            // This is the chance for spawning the gold block+            // 这是一个让树生成金块从而让我们走向富裕的机会,太爽了。
             if (random.nextInt(4) == 0) {             if (random.nextInt(4) == 0) {
-                // Pick a random value from to and determine the side where the gold block will be placed using it+                // 选择一个从 到 的随机值,并使用它确定将放置金块到树的一侧
                 int sideRaw = random.nextInt(4);                 int sideRaw = random.nextInt(4);
                 Direction side = switch (sideRaw) {                 Direction side = switch (sideRaw) {
Line 374: Line 371:
                 };                 };
  
-                // Offset the log position by the resulting side+                // 通过结果边偏移树木位置
                 BlockPos targetPosition = logPosition.offset(side, 1);                 BlockPos targetPosition = logPosition.offset(side, 1);
  
-                // Place the gold block using the replacer BiConsumer +                // 使用 BiConsumer replacer 放置金块! 
-                // This is the standard way of placing blocks in TrunkPlacersFoliagePlacers and TreeDecorators+                // 这是在 TrunkPlacersFoliagePlacers 和 TreeDecorators 中放置方块的标准方法。
                 replacer.accept(targetPosition, Blocks.GOLD_BLOCK.getDefaultState());                 replacer.accept(targetPosition, Blocks.GOLD_BLOCK.getDefaultState());
             }             }
Line 386: Line 383:
 </code> </code>
  
-==== Registering and using your TreeDecorator ==== +==== 注册和使用你的 TreeDecorator ==== 
-First, create your ''TreeDecoratorType'' using the invoker:+首先,使用调用器(invoker)创建你的 ''TreeDecoratorType'' 
  
 <code java> <code java>
Line 393: Line 390:
 </code> </code>
  
-Then, between the creation of your ''TreeFeatureConfig.Builder'' and the ''build'' method call, put this:+然后,在创建你的 ''TreeFeatureConfig.Builder'' 和 ''build'' 方法之间调用这个。
  
 <code java> <code java>
Line 401: Line 398:
 </code> </code>
  
-===== Creating an advanced SaplingGenerator ===== +===== 创建一个高级的 SaplingGenerator ===== 
-So, remember how I told you that ''SaplingGenerator''s can actually contain more complex logic? +所以,还记得我告诉过你 ''SaplingGenerator'' 实际上可以包含更复杂的逻辑吗? 
-Here's an example of that we create several vanilla trees instead of the actual trees depending on the chance:+这是一个例子 我们这次来创建几棵原版的树木而不是实际的树:
  
 <code java> <code java>
Line 418: Line 415:
         int chance = random.nextInt(100);         int chance = random.nextInt(100);
                  
-        // Each tree has a 10% chance+        // 每棵树都有 10% 的几率
         if (chance < 10) {         if (chance < 10) {
             return ConfiguredFeatures.OAK;             return ConfiguredFeatures.OAK;
Line 435: Line 432:
         }         }
                  
-        // If none of that happened (the random value was between 70 and 100), create the actual tree+        // 如果这些都没有发生(随机值在 70 到 100 之间),则创建实际的树
         return feature;         return feature;
     }     }
Line 441: Line 438:
 </code> </code>
  
-This isn't a very practical, but it shows what you can achieve using ''SaplingGenerator''s.+其实这没啥练手的,但是他给你展示了 ''SaplingGenerator'' 可以有更复杂的逻辑。
  
-===== Extra settings for your tree ===== +===== 给你的树整点额外逻辑! ===== 
-Using the extra ''TreeFeatureConfig.Builder'' methods, you can add more settings to your tree:+使用额外的 ''TreeFeatureConfig.Builder'' 方法,你可以给你的树添加更多的设定:
  
 ==== dirtProvider ==== ==== dirtProvider ====
-Sets the ''BlockStateProvider'' for the block of dirt generated under the tree.+还记得巨型云杉木下面的灰化土吗,它就是用这个做到的。 
 + 
 +设置一下 ''BlockStateProvider'' ,让你的树在周围生成铁块!简直就是五金树不是吗?
  
-Example:+例子:
 <code java> <code java>
 [...] [...]
Line 457: Line 456:
  
 ==== decorators ==== ==== decorators ====
-Used to add ''TreeDecorator''s to your tree. +用来在你的树上添加 ''TreeDecorator'' 
-This was briefly showcased in the ''TreeDecorator'' section of this tutorial. +本教程的 ''TreeDecorator'' 部分简要的展示了这一点。 
-If you want, you can add multiple ''TreeDecorator''s to the same tree using a convenience method like ''Arrays.asList''.+如果你想,你可以使用像 ''Arrays.asList'' 这样的方法方便的在同一棵树上添加多个 ''TreeDecorator''
  
-Example:+例子
  
 <code java> <code java>
Line 474: Line 473:
  
 ==== ignoreVines ==== ==== ignoreVines ====
-Makes the tree generation ignore vines stuck in the way.+使树生长时无视藤蔓。
  
-Example:+例子
  
 <code java> <code java>
Line 485: Line 484:
  
 ==== forceDirt ==== ==== forceDirt ====
-Forces the ''TreeFeature'' to generate the dirt underneath the tree.+强制 ''TreeFeature'' 在树下生成泥土。
  
-Example:+例子:
  
 <code java> <code java>
Line 495: Line 494:
 </code> </code>
  
-===== Creating a BlockStateProvider ===== +===== 创建一个 BlockStateProvider ===== 
-Coming soon.+敬请期待!
  
zh_cn/tutorial/trees.txt · Last modified: 2022/08/18 03:40 by 127.0.0.1