カスタムモデル付きブロックの追加(1.7.10)

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

特殊な形のブロックを追加する。
今回は、アルミ製の金床を追加する。
(……としたいのだが、金床のGUIに関しては、実装していない。悪しからず。)

この内容はとても難解なものを含んでいるうえ、汎用性に乏しい。
そのため、更に汎用性の高いものを作る場合は、net.minecraft.client.rendererのRenderBlocksを参照。

ソースコード


package aluminiummod.common;
import net.minecraft.block.Block;
import net.minecraft.creativetab.CreativeTabs;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;

/** * * @author Akasata Nahama & Tom Kate & YOU!! * */ @Mod(modid = "AluminiumMod", name = "Aluminium Mod") public class AluminiumMod {

//追加するブロックの定義 /*public static Block * ;*/ public static Block AnvilAluminium;

//レンダーIDの取得 public static int RenderID;

@EventHandler public void perInit(FMLPreInitializationEvent event) {

/*ブロックの実装。詳細割愛。*/ AnvilAluminium = new AnvilAluminium();

AnvilAluminium.setCreativeTab(CreativeTabs.tabBlock);

AnvilAluminium.setBlockName("blockAluminium");

AnvilAluminium.setBlockTextureName("aluminiummod:aluminium_anvil");

GameRegistry.registerBlock(AnvilAluminium, "AnvilAluminium");

}

@EventHandler public void init (FMLInitializationEvent event) { /*FMLCommonHandler.instance().getSide() で、クライアントサイドでのみの動作としている。*/ if(FMLCommonHandler.instance().getSide() == Side.CLIENT) { /*レンダーIDの設定。 * RenderingRegistry.getNextAvailableRenderId() で、未使用のレンダーIDを取得する。*/ this.RenderID = RenderingRegistry.getNextAvailableRenderId();

/*ブロックのレンダラ―を設定する。 *RenderingRegistry.registerBlockHandler(ISimpleBlockRenderingHandler); */ RenderingRegistry.registerBlockHandler(new RenderAnvilAluminium());

} }


package aluminiummod.common;

import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.world.IBlockAccess; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly;

public class AnvilAluminium extends Block{

public AnvilAluminium() { super(Material.rock); }

/**レンダーIDを返す。**/ @Override public int getRenderType() { return AluminiumMod.RenderID; }

/**ブロックが透けるか否かを返す。**/ @SideOnly(Side.CLIENT) public boolean shouldSideBeRendered(IBlockAccess p_149646_1_, int p_149646_2_, int p_149646_3_, int p_149646_4_, int p_149646_5_) { return true; }

/**通常のブロックでないかを返す。*/ public boolean renderAsNormalBlock() { return false; }

/**ブロックが透明か否かを返す。*/ public boolean isOpaqueCube() { return false; } }


package aluminiummod.common;

import net.minecraft.block.Block; import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.client.renderer.Tessellator; import net.minecraft.world.IBlockAccess;

import org.lwjgl.opengl.GL11;

import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;

public class RenderAnvilAluminium implements ISimpleBlockRenderingHandler { /**インベントリ内でブロックをレンダリングするメソッド。もしshouldRender3DInInventoryがfalseなら空でもいいかも。**/ @Override public void renderInventoryBlock(Block block, int metadata, int modelId, RenderBlocks renderer) { if (modelId == this.getRenderId()) { float f = 0; f = this.renderAlumiAnvil(block, renderer, metadata, f, 0.75F, 0.25F, 0.75F ,false); f = this.renderAlumiAnvil(block, renderer, metadata, f, 0.5F, 0.0625F, 0.625F ,false); f = this.renderAlumiAnvil(block, renderer, metadata, f, 0.25F, 0.3125F, 0.5F ,false); this.renderAlumiAnvil(block, renderer, metadata, f, 0.625F, 0.375F, 1.0F ,false);

} }

/**ワールド内でブロックをレンダリングするメソッド**/ @Override public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) { if (modelId == this.getRenderId()) { /*レンダリングする立方体のサイズを決めるメソッド。 * setRenderBounds(始点X, 始点Y, 始点Z, 終点X, 終点Y, 終点Z)*/ renderer.setRenderBounds(0.1D, 0.0D, 0.1D, 0.9D, 0.2D, 0.9D); /*レンダリングするメソッド。 * renderStandardBlock(block, x, y, z);*/ renderer.renderStandardBlock(block, x, y, z); renderer.setRenderBounds(0.25D, 0.2D, 0.25D, 0.75D, 0.3D, 0.75D); renderer.renderStandardBlock(block, x, y, z); renderer.setRenderBounds(0.3D, 0.3D, 0.2D, 0.7D, 0.6D, 0.8D); renderer.renderStandardBlock(block, x, y, z); renderer.setRenderBounds(0.2D, 0.6D, 0.0D, 0.8D, 1.0D, 1.0D); renderer.renderStandardBlock(block, x, y, z);

return true; } return false; }

@Override /**インベントリ内で3Dレンダリングするか否かを返すメソッド**/ public boolean shouldRender3DInInventory(int modelId) { return true; }

/**自身のレンダーIDを返すメソッド**/ @Override public int getRenderId() {

return AluminiumMod.RenderID; }

protected float renderAlumiAnvil(Block block , RenderBlocks renderer , int metadata , float sides1 , float sides2 , float sides3 , float sides4 , boolean flg) { /**詳しい説明はカット。ここは難しいため、基本的にはshouldRender3DInInventoryをfalseにすることをお勧めする。**/ if(flg) { float f = sides2; sides2 = sides4; sides4 =f; } sides2 /= 2.0F; sides4 /= 2.0F; renderer.setRenderBounds((double)(0.5F - sides2), (double)sides1, (double)(0.5F - sides4), (double)(0.5F + sides2), (double)(sides1 + sides3), (double)(0.5F + sides4));           /*これより下は、ブロックを各面ごとにレンダリングしている。*/ Tessellator tessellator = Tessellator.instance; GL11.glTranslatef(-0.5F, -0.5F, -0.5F); tessellator.startDrawingQuads(); tessellator.setNormal(0.0F, -1.0F, 0.0F); renderer.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 0, metadata)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(0.0F, 1.0F, 0.0F); renderer.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 1, metadata)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(0.0F, 0.0F, -1.0F); renderer.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 2, metadata)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(0.0F, 0.0F, 1.0F); renderer.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 3, metadata)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(-1.0F, 0.0F, 0.0F); renderer.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 4, metadata)); tessellator.draw(); tessellator.startDrawingQuads(); tessellator.setNormal(1.0F, 0.0F, 0.0F); renderer.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, renderer.getBlockIconFromSideAndMetadata(block, 5, metadata)); tessellator.draw(); GL11.glTranslatef(0.5F, 0.5F, 0.5F); renderer.setRenderBounds(0.0D, 0.0D, 0.0D, 1.0D, 1.0D, 1.0D); return sides1 + sides3; }

}

解説

RenderAnvilAluminium

この中では、インベントリ内でのレンダリングが一番難しいはずである。
もし大変ならば、shouldRender3DInInventoryをfalseにすればインベントリにはテクスチャのみが表示されるため、作業が楽になる。

2件のコメント

  1. Tom Kate

    クラッシュレポートをtomkate☆tntmodders.com (☆を@に変えてください)に送っていただけますでしょうか。
    よろしくおねがいします。

  2. おがちゃん

    マルチで使用するとクラッシュするのですが

コメントはこちらです。(スパム対策の為コメントは手動承認になっています。未承認のコメントは表示されないので連投はお控え下さい。)

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