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
zh_cn:tutorial:trees [2021/07/14 17:07] – [Creating a TreeDecoratorType] breakicezh_cn:tutorial:trees [2022/08/18 03:40] (current) – external edit 127.0.0.1
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.1626282446.txt.gz · Last modified: 2021/07/14 17:07 by breakice