2.5日目 ブロックのカスタマイズ
今回は、前回作ったブロックをもう少し細かく設定していこうと思います。
主に次の4つをやっていこうと思います。
1.各面のテクスチャを個別に設定
2.ドロップアイテムの設定
3.硬さや明るさの設定
4.当たり判定の設定
1.各面のテクスチャを個別に設定
前回作ったトマトブロックなんですけど、ちょっと考えるとテクスチャがおかしいですね。
前回は一枚の画像を前面のテクスチャに指定していたので、6面すべてに実とヘタが見えています。
今回は6面すべてのテクスチャを個別に設定してみようと思います。
もう少しだけトマトらしく見せるために上面、側面、下面でそれぞれ異なる画像を用意しました。
block_tomato_top.png
block_tomato_side.png
block_tomato_down.png
これらをすべてassets.testmod.textures.blocksに入れます。
こんな感じですね。
次は、jsonファイルの中身を書き換えていきます。前回3つのjsonファイルを作りましたが、今回はそのうちの1つを編集します。
assets.testmod.models.blockの中のblock_tomato.jsonを次のように書き換えました。
assets.testmod.models.block.block_tomato.json
{ "parent": "block/cube", "textures": { "up": "testmod:blocks/block_tomato_top", "down": "testmod:blocks/block_tomato_down", "north": "testmod:blocks/block_tomato_side", "east": "testmod:blocks/block_tomato_side", "south": "testmod:blocks/block_tomato_side", "west": "testmod:blocks/block_tomato_side" } }
こうすることで、6面にそれぞれ異なる画像を割り当てることができます。
今回のトマトの場合では東西南北はすべて同じ画像を使っています。
この状態でマインクラフトを起動します。
前回よりもトマトらしさが増したような気がしますね。
2.ドロップアイテムの設定
これはこのブロックを壊したときに、このブロック以外のものをドロップするように設定できます。たとえば、バニラの本棚なんかと同じですね。本棚を壊すと本を3つドロップします。
なのでまず、本棚のコードを参照にします。
パッケージエクスプローラーの参照ライブラリからforgeSrc-1.12.2-14.23.5.2768.jar.net.minecraftを開くと色々なバニラのコードを見ることができます。
また、netと同じディレクトリーにあるassetsの中にはバニラのjsonファイルなどが入っているのでそれも参考にできます。さて、本棚のコードはblockの中のBlockBookShell.classに書かれています。ここから次の2つのメソッドを利用します。
public int quantityDropped(Random random) { return 3; }
public Item getItemDropped(IBlockState state, Random rand, int fortune) { return Items.BOOK; }
quantityDroppedがドロップ数、getItemDroppedがアイテムの種類のようですね。これらのメソッドを新たにBlockTomatoに書き加えます。
BlockTomato.java
package testmod; import java.util.Random; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; public class BlockTomato extends Block{ public BlockTomato() { super(Material.IRON); this.setCreativeTab(CreativeTabs.BUILDING_BLOCKS); this.setUnlocalizedName("block_tomato"); this.setRegistryName("block_tomato"); } public int quantityDropped(Random random) { return 1+random.nextInt(8); } public Item getItemDropped(IBlockState state, Random rand, int fortune) { return testmod.Tomato; } }
20行目から28行目が追加した部分です。
ドロップ数の引数のrandomを利用することで1~9個のトマトをドロップするようにしました。
3.硬さや明るさの設定
次は、硬度、爆発耐性、明るさを設定します。
package testmod; import java.util.Random; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; public class BlockTomato extends Block{ public BlockTomato() { super(Material.PLANTS); this.setCreativeTab(CreativeTabs.BUILDING_BLOCKS); this.setUnlocalizedName("block_tomato"); this.setRegistryName("block_tomato"); this.setHardness(3.0F); this.setResistance(10F); this.setLightLevel(1.0F); } public int quantityDropped(Random random) { return 1+random.nextInt(8); } public Item getItemDropped(IBlockState state, Random rand, int fortune) { return testmod.Tomato; } }
19行目から21行目にthis.set~~を追加しました。
Hardnessは硬さでこれが大きいと、壊すまでにかかる時間が増えます。
Resistanceはおそらく爆発耐性だと思います。
LightLevelが明るさですね。
数字の後ろの大文字のFはfloat型の数字であることを表しています。
double型の場合は1.0Dのようになります。
ライブラリーのBlock.classで色んなブロックについてこれらの値を見ることができて、参考までに
黒曜石、Hardness 50.0F、Resistance 2000.0F
石 Hardness 1.5F、Resistance 10.0F
土 Hardness 0.5F、Resistance 未設定
グロウストーン Hardness 0.3F、Resistance 未設定、LightLevel 1.0F
松明 Hardness 0.0F、 Rsistance 未設定、 LightLevel 0.9375F
おそらく設定していない箇所はデフォルトでなにかしらの値が入るんだと思います。
あと明るさは1.0以上に設定しても変化が見られなかったので、おそらく1.0Fが最大でゲーム内で15の明るさになるんだと思います。
また、試していませんがset~~でほかのパラメーターなんかも設定できるような気がします。
4.当たり判定の設定
最後に当たり判定をざっくり設定します。
細かい設定は難しくてまだ手を出せなかったので、当たり判定のありなしだけを設定しました。
当たり判定をなくすために次のように記述します。
public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { return NULL_AABB; }
これをBlockTomatoに書き加えると当たり判定がなくなり、
こんな感じになります。
使うかわからないですけど、条件付きで当たり判定をなくしたい場合などもできました。
次のコードは上が空気の場合のみ当たり判定をなくす処理をしています。
public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos) { BlockPos nextBlock = new BlockPos(pos.getX(),pos.getY()+1,pos.getZ()); if(world.getBlockState(nextBlock).getBlock()==Blocks.AIR) return NULL_AABB; else return FULL_BLOCK_AABB; }
おそらく、返り値のAABBを細かく設定することで、ハーフブロックやクォーターブロックなども作れると思うのですが、
調べてみても分からなかったので今回は手を出していません。
次回はレシピの追加を使用と思います。