メタデータを持つブロックの追加(1.7.10)

1.7.10の開発講座を修正中です。このページには誤りや古い情報が含まれる可能性があります。

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

ソースコード

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");
	}

}
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;
	}

}
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+|

使用例

オファレンブロックを追加している部分。

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();
/*略*/
	}

/*略*/

}
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");
/*略*/
	}

}
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;
	}

}
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();
	}

}

過去の質問

  • かまどのような、向きが変わるブロックはどうやったら作れますか?
    • onBlockPlacedByをオーバーライドし、置いたプレイヤーの向きによって、メタデータを設定します。
      バニラのBlockFurnaceや、オファレンMODのBlockSmeltingMachineなどが参考になるかと思います。
  • メタデータによって上面のテクスチャだけを変えるにはどうすればいいですか?
    • IIconをあらかじめ用意しておき、getIconでsideとmetadataの判定をして返すIIconを変えればよいです。
  • Optifineのように隣り合ったガラスの縁を消すのにはメタデータの違うブロックを置き換えればよいですか?
    • BFOのフチなしガラスでは、メタデータは使わず、getIcon(IBlockAccess,int,int,int,int)で判定を行い、IIconを返しています。

メタデータを持つブロックの追加(1.7.10)” への2件のフィードバック

  1. メタデータを使用した複数の半ブロックを作るにはどのようにすればよろしいでしょうか?

    1. 返信が遅くなり申し訳ありません。
      実装したことがないため詳しく解説することはできませんが、私のわかる範囲で説明させていただきます。
      誤りがあるかもしれませんので、その際はお知らせください。

      基本的には、BlockSlab・BlockStoneSlab・ItemSlabなどのクラスが参考になるかと思います。
      BlockSlabを継承してBlockStoneSlabと同じようにメソッドをオーバーライドし、このページの内容と比較しながら不足分の実装などをすればよいと思います。
      Blocks.stone_slabを呼び出しているBlockSlab.getItem(World, int, int, int)とBlockSlab.shouldSideBeRendered(…)はオーバーライドする必要があるかもしれません。

      GameRegistryへの登録時にregisterBlock(Block block, Class<? extends ItemBlock> itemclass, String name, Object… itemCtorArgs)を利用すればItemSlabのコンストラクタに第二引数以降を渡すことができます。
      これについてはItem.javaの343行目周辺もご参照ください。

コメントはこちら。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

[最終更新日]2017/11/21 20:00