User Tools

Site Tools


zh_cn:tutorial:blockstate

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:blockstate [2019/12/19 02:58] lightcolourzh_cn:tutorial:blockstate [2023/11/18 08:13] (current) – [为方块状态添加模型] update wiki link solidblock
Line 1: Line 1:
-===== 给一个方块状态 ====== +====== 赋予方块状态 ======= 
-Minecraft中的每种类型的块都由一个单独的“区块”实例表示。 +Minecraft 中的每种类型的块都由一个单独的 ''Block'' 实例表示。这样就无法仅通过更改 ''Block'' 实例的状态来更改特定块的状态,因为该类型的其他所有块都会受到影响!但是,如果您想给出一个单一的块状态,以便它可以根据某些条件改变,该怎么办? 
-这样就无法仅通过更改“块”实例的状态来更改特定块的状态, + 
-因为该类型的其他所有块都会受到影响! +这就是 ''BlockState'' 的目的。假设我们希望一个方充能后能够召唤闪电
-但是,如果您想给出一个单一的块状态,以便它可以根据某些条件改变,该怎么办? +
-这就是''BlockState''的目的。 +
-假设我们希望块的硬度通常为''0.5'',但是如果我们尝试破坏它之前右键单击它, +
-它会变得更硬并获得“ 2”的硬度+
      
-首先,我们定义块的boolean属性-是否很难(小心不要导入错误的BooleanProperty+首先,我们定义块的布尔值属性——是否充能(小心不要导入错误的 ''BooleanProperty'',并在模组初始化的地方将其注册。(如果你直接在 ''ChargeableBlock'' 类的静态字段中注册,模组初始化器可能会忽略它,如果这个类没有被初始化的话。) 
 + 
 +事实上你也可以使用原版已有的属性,可以在 ''Properties''(''net.minecraft.state.property.Properties'')中找到。如果你需要定义其他类型的属性,可以使用 ''IntProperty'' 或 ''EnumProperty''
 <code java> <code java>
-public class MyBlock extends Block { +public class ChargeableBlock extends Block { 
-    public static final BooleanProperty HARDENED = BooleanProperty.of("hardened");+    public static final BooleanProperty CHARGED = BooleanProperty.of("charged"); 
 +  
 +    // 方块实例。可以放在任何地方。确保这个类已经初始化。 
 +    public static final ChargeableBlock CHARGEABLE_BLOCK = new ChargeableBlock(FabricBlockSettings.copyOf(Blocks.STONE));
 } }
 </code> </code>
-然后,我们需要通过Override''appendProperties''来注册属性: 
 <code java> <code java>
-public class MyBlock extends Block {+public class ExampleMod implements ModInitializer { 
 +    @Override 
 +    public void onInitialize() { 
 +        Registry.register(Registries.BLOCK, new Identifier("tutorial", "chargeable_block"), ChargeableBlock.CHARGEABLE_BLOCK); 
 +        Registry.register(Registries.ITEM, new Identifier("tutorial", "chargeable_block"), new BlockItem(ChargeableBlock.CHARGEABLE_BLOCK, new FabricItemSettings()); 
 +    } 
 +
 +</code> 
 + 
 +然后,我们需要通过覆盖 ''appendProperties'' 并加入 ''CHARGED'' 以注册属性: 
 + 
 +<code java> 
 +public class ChargeableBlock extends Block {
     [...]     [...]
     @Override     @Override
-    protected void appendProperties(StateManager.Builder<Block, BlockState> stateManager) { +    protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { 
-        stateManager.add(HARDENED);+        builder.add(CHARGED);
     }     }
-    + 
 } }
 </code> </code>
-然后,我们需要在块构造函数中设置属性的默认状态:+然后,我们需要在块构造中设置属性的默认状态(要设置多个属性,请通过调用 ''with()'' 来连接)
 <code java> <code java>
-public class MyBlock extends Block {+public class ChargeableBlock extends Block {
     [...]     [...]
-    public MyBlock(Settings settings) {+    public ChargeableBlock(Settings settings) {
         super(settings);         super(settings);
-        setDefaultState(getStateManager().getDefaultState().with(HARDENED, false));+        setDefaultState(getDefaultState().with(CHARGED, false));
     }     }
-    + 
 } }
 </code> </code>
-(要设置多个属性,请链接“ with()”调用) 
  
-现在,要设置属性,我们需要调用''world.setBlockState()'': +现在,我们需要能够通过 ''onUse'' 方法充能方块,在该方法中调用 ''world.setBlockState()''这个 ''playSound'' 是可循的,只是让我们知道方块充能了。 
-      +
-用块的实例替换''MyBlocks.MY_BLOCK_INSTANCE''+
 <code java> <code java>
-public class MyBlock extends Block {+public class ChargeableBlock extends Block {
     [...]     [...]
     @Override     @Override
-    public boolean activate(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult blockHitResult) { +    public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { 
-        world.setBlockState(pos, MyBlocks.MY_BLOCK_INSTANCE.getDefaultState().with(HARDENED, true)); +        player.playSound(SoundEvents.BLOCK_RESPAWN_ANCHOR_CHARGE, 1, 1); 
-        return true;+        world.setBlockState(pos, state.with(CHARGED, true)); 
 +        return ActionResult.SUCCESS;
     }     }
 } }
 </code> </code>
-使用属性,我们称为''blockState.get(<我们的属性名称>)''+ 
 +最后,要使用 ''CHARGED'' 属性,我们调用 ''onSteppedOn'',并在里面使用 ''world.getBlockState(pos).get(CHARGED)''
 <code java> <code java>
-public class MyBlock extends Block {+public class ChargeableBlock extends Block {
     [...]     [...]
     @Override     @Override
-    public float getHardness(BlockState blockState, BlockView blockView, BlockPos pos) { +    public void onSteppedOn(World world, BlockPos pos, BlockState state, Entity entity) { 
-        boolean hardened = blockState.get(HARDENED); +        if (world.getBlockState(pos).get(CHARGED)){ 
-        if(hardenedreturn 2.0f+            // 在方块的位置召唤闪电 
-        else return 0.5f;+            LightningEntity lightningEntity = (LightningEntity) EntityType.LIGHTNING_BOLT.create(world); 
 +            lightningEntity.refreshPositionAfterTeleport(Vec3d.ofBottomCenter(pos)); 
 +            world.spawnEntity(lightningEntity)
 +        
 +  
 +        world.setBlockState(pos, state.with(CHARGED, false)); 
 +        super.onSteppedOn(world, pos, state, entity);
     }     }
 } }
Line 66: Line 84:
 ==== 为方块状态添加模型 ==== ==== 为方块状态添加模型 ====
  
-您还以根据状态更改块的纹理和模型。 这是通过称为Blockstate JSON的JSON文件完成的。 所有块都需要一个块状态JSON,无论它是否有多个状态,但是JSON的内容可以根据您的喜好简单复杂。 如果要基于状态块的纹理,则将需要多个模型。+能还需要使得纹理和模型能够根据状态来改变,这是通过一个叫做“方块状态 JSON的 JSON 完成的。所有的方块都需要一个块状态 JSON,无论它是否有多个方块状态,但内容可以简单也可以复杂。如果根据方块状态纹理,我们需要添加多个模型。
  
-假设您将''MyBlock''的实例注册ID''mymod:my_block''。 Minecraft将在``src/main/resources/assets/mymod/blockstates/ my_block.json''位置查找文件以加载状态。如果希望状态之间更改模型,块状态JSON可非常简单。它看起来像这样:+比如说,你为 ''ChargeableBlock'' 注册了 ID 为 ''tutorial:chargeable_block''。Minecraft 会加载地址 ''src/main/resources/assets/tutorial/blockstates/chargeable_block.json'' 并从中加载方块状态。如果需要让方根据状态更改模型,块状态 JSON 可非常简单,就像这样:
  
-<code JavaScript resources/assets/mymod/blockstates/my_block.json>+<code JavaScript resources/assets/tutorial/blockstates/chargeable_block.json>
 { {
-    "variants":+    
-        "": { "model": "mymod:block/my_block" }+        "variants":
 +            "": { "model": "tutorial:block/chargeable_block
 +        }
     }     }
 +
 } }
 </code> </code>
 +让我们分解一下这个简单的例子。JSON 有几个重要的部分:
  
-Let's break this simple example downThere are a couple important parts to this JSON:+''"variants"'' 定义了每个方块状态应该使用什么模型。我们将稍作探讨。 
 +- 名为 ''""'' 的变种将应用于//每个//方块状态。如果你有 ''""'' 变种,则 JSON 中不应包含任何其他变种,否则 Minecraft 会出问题。 
 +- 分配给 ''""'' 变种的对象可以添加各种属性,例如旋转或纹理操作。请查看下面的链接的“模型”页面,以获取有关可以添加哪些属性的更多文档。所有变种都//必须//包含 ''"model"''属性。 
 +- ''"model"'' 属性总是传递模型的 ID。在这个例子中,游戏将查看位置 ''src/main/resources/assets/tutorial/models/block/chargeable_block.json''。这里的ID可以是任何东西,//不需要//与方块的ID相同,但是如果只有一个变种,则应当要相同。方块模型具有自己的设置,在下面链接的 Minecraft Wiki 页面上有很好的记录。您可以手动编写 JSON,也可以使用[[https://blockbench.net|Blockbench]]之类的程序更轻松地生成它。
  
-- The ''"variants"'' block will be where all possible variations for your blockstate go. We'll explore variants more in a little. +如果//确实//想要为每个方块状态使用不同的模型,则需要添加多个变种。对于我们上面使用的同一个 ''src/main/resources/assets/tutorial/blockstates/chargeable_block.json'' 位置,你可能需要这样子:
-- A variant named ''""'' will apply to //every// permutation of a blockstate. If you have a ''""'' variant, you shouldn't have any other variants in the JSON, or Minecraft will get upset. +
-- The object assigned to the ''""'' variant can have various properties added to it like rotation or texture manipulation. Check out the linked Model page below for more documentation on what properties can be added. All variants //must// contain a ''"model"'' property. +
-- The ''"model"'' property is always passed an ID of a model. In this case, the game will look at the location ''src/main/resources/assets/mymod/models/block/my_block.json''. The ID here can be anything. It doesn't //need// to be the same as your block's ID, but if you only have one variant, it probably should. Block models have their own setup, which is documented very well on the Minecraft wiki page linked below. You can either write the JSON by hand or use a program like [[https://blockbench.net|Blockbench]] to generate it more easily.+
  
-If you //do// want to have different models for each blockstate, you'd want to add multiple variants. For the same ''src/main/resources/assets/mymod/blockstates/my_block.json'' location we used above, your could would probably look like such: +<code JavaScript resources/assets/tutorial/blockstates/chargeable_block.json> 
- +    
-<code JavaScript resources/assets/mymod/blockstates/my_block.json> +        "variants":
-+            "charged=false": { "model": "tutorial:block/chargeable_block" }, 
-    "variants":+            "charged=true": { "model": "tutorial:block/chargeable_block_charged
-        "hardened=false": { "model": "mymod:block/my_block" }, +        }
-        "hardened=true": { "model": "mymod:block/my_block_hardened" }+
     }     }
-} 
 </code> </code>
  
-In this JSON, there are two variants, one for each possibility of the ''HARDENED'' property we defined above. Since we gave the property the string name of ''hardened'' in the Java, that's what we use here. Booleans only have two states, but if you use properties based on integers or enums, you'll have more variants+在此 JSON中,有两个变种,一种针对我们上面定义的 ''CHARGED'' 属性的每种可能性。由于我们在 Java 中为属性指定了字符串 ''charged'',因此我们在这里使用它。布尔值只有两种状态,但是如果您使用基于整数或枚举的属性,则会有更多的变种。 
 + 
 +变种基于添加到方块中的属性的可能排列。如果需要,可以在方块状态 JSON 中完全忽略某个属性,例如在第一个方块状态 JSON 中我们忽略了 ''charged'' 属性,但如果要在一个变种中包含属性,则必须将其包含在//所有//变种。如果 ''tutorial:chargeable_block'' 还具有一个称为 ''glowing'' 的布尔属性,并且您想根据模型是否发光以及是否经过充能来更改模型,则需要四个变种:充能发光,充能不发光,不充能但发光,不充能不发光。如果需要,可以将同一模型分配给多个变种。 
 + 
 +这只是对方块状态 JSON 的简单介绍。[[https://zh.minecraft.wiki/模型|Minecraft Wiki]]中记录了有关方块状态和模型 JSON 的所有技巧,以及在原版游戏中使用这些功能的示例。祝你好运! 
 + 
 +==== 关于性能的注意事项 ====
  
-Variants are based on possible permutations of the properties added to your block. A property can be totally ignored in the blockstate JSON if you want, like in the first blockstate JSON where we ignored the ''hardened'' property, but if you want to include a property in one variant, it must be included in //all// variants. If ''mymod:my_block'' also had a boolean property called ''glowing'', and you wanted to change the model based on whether it was glowing and based on whether it was hardened, you would need four variantshardened off and glowing off, hardened on and glowing off, hardened off and glowing on, and hardened on and glowing on. The same model can be assigned to multiple variants if you need it to be.+游戏开始时会注册方块的所有可能状态。这意味着,如果具有14个布尔属性,则该方块具有2 ^ 14 = 16384个不同的状态,并且会注册这2 ^ 14个状态。因此,方块不应包含太多的方块状态属性。相反,方块状态应主要保留用于视觉效果,需要使用更高级的状态应使用[[zh_cn:tutorial:blockentity|方块实体]]。
  
-This is only a simple introduction to blockstate JSONs. All of the tricks you can do with blockstate and model JSONs are documented on the [[https://minecraft.gamepedia.com/Model|Minecraft wiki]]along with examples of how the features are used in vanilla. Best of luck! +由于所有的可能的方块状态都已经构建好了,因此相等的方块状态是同一个对象,''with'' 方法会返回一个存在的对象,而不是创建一个新对象——例如,''CHARGEABLE_BLOCK.getDefaultState().with(CHARGEDtrue) == CHARGEABLE_BLOCK.getDefaultState().with(CHARGEDtrue)'' 会返回 ''true''
-==== A note about performance ==== +
-Every possible state of a block is registered at the start of the gameThis means that if you have 14 boolean properties, the block has 2^14 = 16384 different states and 2^14 states are registeredFor this reason blocks should not contain too many blockstate properties. Ratherblockstates should be mostly reserved for visuals, and [[tutorial:blockentity|Block Entities]] should be used for more advanced state.+
zh_cn/tutorial/blockstate.1576724326.txt.gz · Last modified: 2019/12/19 02:58 by lightcolour