User Tools

Site Tools


zh_cn:tutorial:features

Differences

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

Link to this comparison view

Both sides previous revisionPrevious revision
zh_cn:tutorial:features [2021/07/12 01:17] – [向生物群落添加Feature] solidblockzh_cn:tutorial:features [2022/08/18 03:37] (current) solidblock
Line 1: Line 1:
-===== 添加地形特征 [1.17=====+FIXME 本页有一段时间没有更新了,可能在未来版本不可用。请参考[[tutorial:features|英文页面]]进行更新。
  
-岩石、树木、矿石、池塘都是形特征的例子,是对世界的简单补充生成,并根据配置的方式生成。本教程中,我们将研究如何随机生成简单的石头螺旋地形。+===== 添加物 [1.17] =====
  
-物群系中添加地形特征需要3个步骤。 +岩石、树木、矿石、池塘都是地物的例子,是对世界的简单补充成,并根据配置的方式成。本教程中,我们将研究如何随机成简单的石头螺旋地物。
-  * 创建地形特征 +
-  * 配置地形特征 +
-  * 使用[[https://github.com/FabricMC/fabric/pull/1097|Fabric API中的生物群系修改API]]以往生物群系中添加地形特征+
  
-注意生物群系修改API标记为实验性如果API不起作用,考虑使用[[?rev=1599388928|mixin版本]]。+生物群系中地物特征需要3个步骤 
 +  * 创建地物 
 +  * 配置地物 
 +  * 使用 [[https://github.com/FabricMC/fabric/pull/1097|Fabric API 中的 Biome Modification API]] 以往生物群系中添加地物
  
-==== 创建地形特征 ==== +注意 Biome Modification API 标记为实验性。如果 API 不起作用,考虑使用[[?rev=1599388928|mixin版本]]。 
-一个简单的地形特征如下所示:+ 
 +==== 创建地物 ==== 
 +一个简单的地如下所示:
 <code java> <code java>
 public class StoneSpiralFeature extends Feature<DefaultFeatureConfig> { public class StoneSpiralFeature extends Feature<DefaultFeatureConfig> {
-  public StoneSpiralFeature(Codec<DefaultFeatureConfig> config) { +  public StoneSpiralFeature(Codec<DefaultFeatureConfig> configCodec) { 
-    super(config);+    super(configCodec);
   }   }
 + 
   @Override   @Override
-  public boolean generate(StructureWorldAccess world, ChunkGenerator generator, Random random, BlockPos pos, +  public boolean generate(FeatureContext<DefaultFeatureConfig> context) { 
-      DefaultFeatureConfig config) { +    BlockPos topPos = context.getWorld().getTopPosition(Heightmap.Type.OCEAN_FLOOR_WGcontext.getOrigin());
-    BlockPos topPos = world.getTopPosition(Heightmap.Type.WORLD_SURFACEpos);+
     Direction offset = Direction.NORTH;     Direction offset = Direction.NORTH;
- +  
-    for (int y = 1; y <15; y++) {+    for (int y = 0; y < 15; y++) {
       offset = offset.rotateYClockwise();       offset = offset.rotateYClockwise();
-      world.setBlockState(topPos.up(y).offset(offset), Blocks.STONE.getDefaultState(), 3);+      context.getWorld().setBlockState(topPos.up(y).offset(offset), Blocks.STONE.getDefaultState(), 3);
     }     }
 + 
     return true;     return true;
   }   }
Line 34: Line 35:
 </code> </code>
  
-''Feature<DefaultFeatureConfig>''构造器采用''Codec<DefaultFeatureConfig>''。你可以直接在构造器的超级调用中或者实例化特性时为默认的配置特性传入''DefaultFeatureConfig.CODEC'' 
- 
-区块决定生成地形特征时调用''generate''。如果地形特征配置为在每个区块生成,则每个区块被生成时都会调用一次。在特征被配置为以每个生物群系特定的概率生成的情况下,''generate''只会在世界想要生成结构的实例中调用。 
  
 在我们的实现中,我们从世界最高位置的方块构建一个简单的15个方块高的岩石螺旋。 在我们的实现中,我们从世界最高位置的方块构建一个简单的15个方块高的岩石螺旋。
  
-地形特征可以像游戏其他内容注册你不需要担心没有特定的构建器(builder)和机制(mechanic)+''Feature<DefaultFeatureConfig>'' 构造器需要一个 ''Codec<DefaultFeatureConfig>''。你可以通过直接在构造器的 super 调用中或者在实例化地物时传入 ''DefaultFeatureConfig.CODEC''。 
 + 
 +区块决定生成地物时会调用 ''generate''。如果地物配置为在每个区块生成,则每个区块被生成时都会调用次。如果地物配置为在每个生物群系以特定的概率生成,''generate'' 只会在世界需要生成结构的实例中调用。 
 + 
 +我们的地物目前使用 ''DefaultFeatureConfig'',这意味着暂时还不能配置。但是,你一般都应该尝试让你的地物可以配置,以允许我们为同的东西使用它,同时也可以在需要时通过数据包去改变我们的地物的简单的配置如下所示:
  
 <code java> <code java>
-public class ExampleMod implements ModInitializer +public record SpiralFeatureConfig(IntProvider height, BlockStateProvider block) implements FeatureConfig 
-  private static final Feature<DefaultFeatureConfigSTONE_SPIRAL new StoneSpiralFeature(DefaultFeatureConfig.CODEC);+  public static final Codec<SpiralFeatureConfigCODEC RecordCodecBuilder.create(instance -> instance.group( 
 +    IntProvider.VALUE_CODEC.fieldOf("height").forGetter(SpiralFeatureConfig::height), 
 +    BlockStateProvider.TYPE_CODEC.fieldOf("block").forGetter(SpiralFeatureConfig::block) 
 +  ).apply(instance, instance.stable(SpiralFeatureConfig::new))); 
 +
 +</code>
  
 +注意我们为高度使用了 ''IntProvider'',并为方块使用了 ''BlockStateProvider'',而不是直接使用一个 ''int'' 或 ''BlockState''。这是因为前者更加强大。比如说,你可以配置地物使用 ''UniformIntProvider'',这样其高度可以变化。
 +
 +现在,让我们的地物使用 ''SpiralFeatureConfig''(类名也改变了,因为地物现在不总是替换石头):
 +<code java>
 +public class SpiralFeature extends Feature<SpiralFeatureConfig> {
 +  public SpiralFeature(Codec<SpiralFeatureConfig> configCodec) {
 +    super(configCodec);
 +  }
 + 
 +  @Override
 +  public boolean generate(FeatureContext<SpiralFeatureConfig> context) {
 +    BlockPos pos = context.getOrigin();
 +    SpiralFeatureConfig config = context.getConfig();
 + 
 +    Direction offset = Direction.NORTH;
 +    int height = config.height().get(context.getRandom());
 + 
 +    for (int y = 0; y < height; y++) {
 +      offset = offset.rotateYClockwise();
 +      BlockPos blockPos = pos.up(y).offset(offset);
 + 
 +      context.getWorld().setBlockState(blockPos, config.block().getBlockState(context.getRandom(), blockPos), 3);
 +    }
 + 
 +    return true;
 +  }
 +}
 +</code>
 +和游戏内的许多其他内容一样,地物也可以注册,并且也没有你需要担心的特别地构建器或机制。
 +<code java>
 +public class ExampleMod implements ModInitializer {
 +  private static final Feature<SpiralFeatureConfig> SPIRAL = new SpiralFeature(SpiralFeatureConfig.CODEC);
 + 
   @Override   @Override
   public void onInitialize() {   public void onInitialize() {
-    Registry.register(Registry.FEATURE, new Identifier("tutorial", "stone_spiral"), STONE_SPIRAL);+    Registry.register(Registry.FEATURE, new Identifier("tutorial", "spiral"), SPIRAL);
   }   }
 } }
 </code> </code>
  
-==== 配置地形特征 ==== + 
-我们需要为地形特征提供配置。确保注册配置的地形特征和形特征+==== 配置地物 ==== 
 +在将地物添加到生物群系之前,我们需要为地提供配置。确保配置的地物像物一样都已经注册
  
 <code java> <code java>
 public class ExampleMod implements ModInitializer { public class ExampleMod implements ModInitializer {
-  public static final ConfiguredFeature<?, ?> STONE_SPIRAL_CONFIGURED = STONE_SPIRAL.configure(FeatureConfig.DEFAULT+  public static final ConfiguredFeature<?, ?> STONE_SPIRAL = SPIRAL.configure(new SpiralFeatureConfig(ConstantIntProvider.create(15), new SimpleBlockStateProvider(Blocks.STONE.getDefaultState()))
-      .decorate(Decorator.CHANCE.configure(new ChanceDecoratorConfig(5))); +      .decorate(Decorator.HEIGHTMAP.configure(new HeightmapDecoratorConfig(Heightmap.Type.OCEAN_FLOOR_WG))
 +      .spreadHorizontally() 
 +      .applyChance(5); 
 + 
   @Override   @Override
   public void onInitialize() {   public void onInitialize() {
     [...]     [...]
-    + 
     RegistryKey<ConfiguredFeature<?, ?>> stoneSpiral = RegistryKey.of(Registry.CONFIGURED_FEATURE_KEY,     RegistryKey<ConfiguredFeature<?, ?>> stoneSpiral = RegistryKey.of(Registry.CONFIGURED_FEATURE_KEY,
         new Identifier("tutorial", "stone_spiral"));         new Identifier("tutorial", "stone_spiral"));
-    Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, stoneSpiral.getValue(), STONE_SPIRAL_CONFIGURED);+    Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, stoneSpiral.getValue(), STONE_SPIRAL);
   }   }
 } }
 </code> </code>
  
-Decorator表示世界如何选择放置该特征。要选择正确的Decorator,检查原版的地形特征,你自己的应该要类似。装饰器配置是从这个分支出来的,在''CHANCE''的情况下,你应该传入''ChanceDecoratorConfig''的实例。 +注意,螺旋的高度(15 个方块)和需要放置的方块(石头)现在已经可以配置。 
 + 
 +装饰器(由 ''decorate'' 添加,或者像 ''spreadHorizontally'' 和 ''applyChange'' 那样的辅助方法)负责如何放置以及何处放置你的地物。要选择正确的装饰器,检查原版的类似物以及你自己的。
  
-==== 生物群系添加特征地形 ==== +==== 将地物添加到生物群系 ==== 
-我们使用生物群系修改API。+我们使用 Biome Modification API。
  
 <code java> <code java>
Line 89: Line 134:
 </code> </code>
  
-''addFeature''的第一个参数确定结构生成在什么生物群系中。+''addFeature'' 的第一个参数确定结构生成在什么生物群系中。
  
-第二个参数帮助你确定结构何时生成。对于地上的房子,可以用''SURFACE_STRUCTURES'',对于洞穴,可以用''RAW_GENERATION''+第二个参数帮助你确定结构何时生成。对于地上的房子,可以用 ''SURFACE_STRUCTURES'',对于洞穴,可以用 ''RAW_GENERATION''
  
 === 结果 === === 结果 ===
 {{https://i.imgur.com/Kr59o0B.png}} {{https://i.imgur.com/Kr59o0B.png}}
zh_cn/tutorial/features.1626052629.txt.gz · Last modified: 2021/07/12 01:17 by solidblock