MOD製作チュートリアル > メタデータを持つブロックの追加

概要

メタデータを使用し、一つのIDで複数のブロックを追加したり、向きを持つブロックを追加したりする。

ソースコード

  • AluminiumMod.java
package tutorial.aluminiummod;
 
import net.minecraft.block.Block;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.registry.GameRegistry;
 
@Mod(modid = AluminiumMod.MODID, name = AluminiumMod.MODNAME, version = AluminiumMod.VERSION)
public class AluminiumMod {
 
	public static final String MODID = "AluminiumMod";
	public static final String MODNAME = "Aluminium Mod";
	public static final String VERSION = "1.0.0";
 
	public static Block blockAluminiumColored;
 
	@EventHandler
	public void perInit(FMLPreInitializationEvent event) {
		//ここは通常のブロックと同様。
		blockAluminiumColored = new ColoredAluminiumBlock()
		.setBlockName("blockAluminiumColored")
		.setBlockTextureName("aluminiummod:colored_aluminium_block");
		GameRegistry.registerBlock(blockAluminiumColored, ItemColoredAluminiumBlock.class, "blockAluminiumColored");
	}
 
}
 

  • ColoredAluminiumBlock.java
package tutorial.aluminiummod;
 
import java.util.List;
 
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
 
public class ColoredAluminiumBlock extends Block {
 
	private IIcon[] iicon = new IIcon[16];
 
	protected ColoredAluminiumBlock() {
		super(Material.rock);
		this.setCreativeTab(CreativeTabs.tabBlock);
		this.setHardness(5.0F);
		this.setResistance(10.0F);
		this.setStepSound(Block.soundTypeMetal);
		this.setHarvestLevel("pickaxe", 2);
		this.setLightLevel(0.0F);
	}
 
	@Override
	@SideOnly(Side.CLIENT)
	public void registerBlockIcons(IIconRegister register) {
		for (int i = 0; i < 16; i ++) {
			this.iicon[i] = register.registerIcon(this.getTextureName() + "-" + i);
		}
	}
 
	@Override
	@SideOnly(Side.CLIENT)
	public IIcon getIcon(int side, int meta) {
		return iicon[meta];
	}
 
	@Override
	@SideOnly(Side.CLIENT)
	public void getSubBlocks(Item item, CreativeTabs creativeTab, List list) {
		for (int i = 0; i < 16; i ++) {
			list.add(new ItemStack(item, 1, i));
		}
	}
 
	@Override
	public int damageDropped(int meta) {
		return meta;
	}
 
}
 

  • ItemColoredAluminiumBlock.java
package tutorial.aluminiummod;
 
import net.minecraft.block.Block;
import net.minecraft.item.ItemBlockWithMetadata;
import net.minecraft.item.ItemStack;
 
public class ItemColoredAluminiumBlock extends ItemBlockWithMetadata {
 
	public ItemColoredAluminiumBlock(Block block) {
		super(block, block);
	}
 
	@Override
	public String getUnlocalizedName(ItemStack itemStack) {
		return this.getUnlocalizedName() + "." + itemStack.getItemDamage();
	}
 
}
 

解説

GameRegistry

Block registerBlock(Block block, Class<? extends ItemBlock> itemclass, String name)

GameRegistryに追加ブロックを登録するメソッド。
対応するItemBlockを指定できる。
デフォルトではItemBlockを指定している。

Block

void registerBlockIcons(IIconRegister register)

ブロックのテクスチャを指定するメソッド。
Itemと同じ。

IIcon getIcon(int side, int meta)

描画時に呼ばれる。
第一引数では面を、第二引数ではメタデータを取得できる。
このメソッドを使えば面によって違うテクスチャを返したり、かまどのように向きを変えたりできる。
第一引数については下の「sideについて」で。

void getSubBlocks(Item item, CreativeTabs creativeTab, List list)

クリエイティブタブに登録するメソッド。
Itemと同じ。

int damageDropped(int meta)

ドロップアイテムのダメージを指定するメソッド。
Blockでは常に0を返しているのでオーバーライドする。

ItemBlockWithMetadata

ItemBlockのサブクラスで、メタデータを使用するブロック用のクラス。

コンストラクタ(Block block, Block localBlock)

第一引数はスーパークラスのコンストラクタに渡し、第二引数はこのクラスで保持する。

String getUnlocalizedName(ItemStack itemStack)

アイテムと同じ。

sideについて

getIconの第一引数などのintは、面の方角を表している。
向きと座標の関係は、net.minecraft.util.FacingのoffsetsXForSide/offsetsYForSide/offsetsZForSideを使えばわかる
side 向き 座標
0 y-
1 y+
2 z-
3 z+
4 西 x-
5 x+

使用例

オファレンブロックを追加している部分。
+ オファレンMOD
  • OfalenModCore.java
package nahama.ofalenmod;
 
/*略*/
 
/**@author Akasata Nahama*/
@Mod(modid = OfalenModCore.MODID, name = OfalenModCore.MODNAME, version = OfalenModCore.VERSION)
public class OfalenModCore {
 
	public static final String MODID = "OfalenMod";
	public static final String MODNAME = "Ofalen Mod";
	public static final String VERSION = "[1.7.10]1.0.0";
 
/*略*/
 
	/**最初に行われる処理。アイテム・ブロックの追加などを行う*/
	@EventHandler
	public void preInit(FMLPreInitializationEvent event) {
/*略*/
		//ブロックを設定するメソッドを実行
		OfalenModBlockCore.registerBlock();
/*略*/
	}
 
/*略*/
 
}
 

  • OfalenModBlockCore.java
package nahama.ofalenmod.core;
 
/*略*/
 
public class OfalenModBlockCore {
**/
	public static Block blockOfalen;
/*略*/
 
	/**ブロックを設定する*/
	public static void registerBlock () {
/*略*/
		blockOfalen = new OfalenBlock()
		.setBlockName("blockOfalen")
		.setBlockTextureName("ofalenmod:ofalen_block-");
		GameRegistry.registerBlock(blockOfalen, ItemOfalenBlock.class, "blockOfalen");
/*略*/
	}
 
}
 

  • OfalenBlock.java
package nahama.ofalenmod.block;
 
import java.util.List;
 
import nahama.ofalenmod.OfalenModCore;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
 
public class OfalenBlock extends Block {
 
	private IIcon[] iicon = new IIcon[4];
 
	public OfalenBlock() {
		super(Material.rock);
		this.setCreativeTab(OfalenModCore.tabOfalen);
		this.setHardness(7.5F);
		this.setResistance(15.0F);
		this.setStepSound(Block.soundTypeMetal);
		this.setLightLevel(1.0F);
		this.setHarvestLevel("pickaxe", 3);
	}
 
	/**メタデータ違いのテクスチャを登録する*/
	@Override
	@SideOnly(Side.CLIENT)
	public void registerBlockIcons(IIconRegister register) {
		for (int i = 0; i < 4; i ++) {
			this.iicon[i] = register.registerIcon(this.getTextureName() + i);
		}
	}
 
	/**メタデータにより返すIIconを変える*/
	@Override
	@SideOnly(Side.CLIENT)
	public IIcon getIcon(int side, int meta) {
		return iicon[meta & 3];
	}
 
	/**メタデータ違いのブロックを登録する*/
	@Override
	@SideOnly(Side.CLIENT)
	public void getSubBlocks(Item item, CreativeTabs creativeTab, List list) {
		for (int i = 0; i < 4; i ++) {
			list.add(new ItemStack(item, 1, i));
		}
	}
 
	/**メタデータによりドロップ品を変える*/
	@Override
	public int damageDropped(int meta) {
		return meta & 3;
	}
 
}
 

  • ItemOfalenBlock.java
package nahama.ofalenmod.itemblock;
 
import net.minecraft.block.Block;
import net.minecraft.item.ItemBlockWithMetadata;
import net.minecraft.item.ItemStack;
 
public class ItemOfalenBlock extends ItemBlockWithMetadata {
 
	public ItemOfalenBlock(Block block) {
		super(block, block);
	}
 
	/**メタデータにより内部名を変える*/
	@Override
	public String getUnlocalizedName(ItemStack itemStack) {
		return this.getUnlocalizedName() + "." + itemStack.getItemDamage();
	}
 
}
 

コメント

この項目に関する質問などをどうぞ。
  • かまどみたいに置く向きによって変わるのってどうして作るんですか? - 名無しさん 2015-10-12 21:07:02
    • onBlockPlacedByをオーバーライドし、置いたプレイヤーの向きによって、メタデータを設定します。
      バニラのBlockFurnaceや、オファレンMODのBlockSmeltingMachineなどが参考になるかと思います。 - 赤砂蛇凪浜 2015-10-13 08:36:08
  • メタデータによって上面のテクスチャだけを変えるにはどうすればいいですか? - 名無しさん 2016-06-10 23:03:47
    • IIconをあらかじめ用意しておき、getIconでsideとmetadataの判定をして返すIIconをかえればよいです。 - 赤砂蛇凪浜 2016-06-11 06:52:52
  • Optifineのように隣り合ったガラスの縁を消すのにはメタデータの違うブロックを置き換えればよいですか? - 名無しさん 2016-06-12 00:31:06
    • BFOのフチなしガラスでは、getIcon(IBlockAccess,int,int,int,int)で判定を行い、IIconを返しています。メタデータを使う必要はありません。 - 赤砂蛇凪浜 2016-06-12 06:59:29
  • 通常のブロック追加では一つ画像のみでいくらブロックをおいても同じ柄ですが、8×8の64枚の画像をrepeatの形で適応させるにはどう作れば良いのですか?? - 名無しさん 2016-06-14 17:45:47
    • 返答遅くなりまして申し訳ありません。
      アニメーションさせたい場合は、まず、アニメーションさせたいブロックのテクスチャを、アニメーション順に縦に並べてください。
      次に、ブロックのテクスチャと同じ階層に[ブロック名].png.mcmeta というファイルを作って、以下のように記述してください。
      {
      "animation": {
      "frametime": 2
      }
      }
      アニメーションの速度が速ければ、"frametime"の数値を上げてください。
      バニラのリソースでは、火や溶岩が参考になるかと思います。- Tom Kate 2016-06-25 11:36:47
  • メタ付の半ブロックを追加するにはどうすればいいのでしょうか? - 名無しさん 2017-04-20 19:50:42
    • 返信が遅くなってしまい申し訳ありません。
      コメントを別のページから移動させて頂きました。ご了承ください。
      単純なものであれば、BlockStoneSlabやBlockWoodSlabをコピペし、各メソッド内でインスタンスの呼び出しをしている部分を置き換えればよいです。
      ただし、BlockSlabの一部メソッドやItemなど他のクラスでもインスタンスを呼び出しているので、それらも考慮する必要があると思われます。
      今後、ハーフブロックの追加に関するチュートリアルを作成する予定です。
  • こちらはマイクラバージョン1.10や1.11などでも使えるのでしょうか...? - 名無しさん 2017-06-08 23:17:07
    • ver1.8以降はBlockStateと言うものを利用いたしますのでこのチュートリアルは使用できません。 - Tom Kate 2017-06-09 19:13:51
  • かまどではなく、原木や柱状クオーツのように横から置くとtopの部分が横を向くようにするには、どうすればよいでしょうか? - 名無しさん 2017-06-21 21:22:17
    • 返信が遅くなってしまい申し訳ありません。
      単純なものでしたら、BlockRotatedPillarを継承し、BlockHayを参考にgetSideIconとregisterBlockIconsをオーバーライドすればできます。
      継承関係があり少々複雑ですが、原木のクラス(BlockLog, BlockOldLog, BlockNewLog)を見れば一つのIDで四種類まで追加できるかと思います。
      BlockRotatedPillarでは、getRenderTypeで柱状のレンダーを指定し、横向き設置時にテクスチャを回転させています。
      また、onBlockPlacedで設置する支えとなったブロックの面によりメタデータで向きを設定し、getIconでメタデータにより断面のテクスチャの向きを変更しています。 - 赤砂蛇凪浜 2017-07-08 18:06:57
最終更新:2015年07月23日 13:33