提供: Minecraft Modding Wiki
この記事は"Minecraft Forge4.3x"を前提MODとしています。 |
目次
SpriteID無限化(独自のterrain.png, gui/items.pngの利用)
今までのサンプルではバニラのテクスチャを参照していた. ブロックはterrain.png, アイテムはgui/items.pngだった. ModLoaderにおけるaddOverrideというメソッドはこれらの空き領域に対し16*16のテクスチャを上書きし, そのテクスチャのインデックスを返すものだったため, 空き領域が埋まるとMinecraftがクラッシュしてしまう. この問題を解決するためにforgeではブロックやアイテムが参照するテクスチャを切り替える機構が用意された. なおこのサンプルからプロキシシステムを利用する. また, 独自のterrain.png, items.pngにも名前の制限はない. しかしテクスチャのサイズは256ドット×256ドットである. これは16ドット×16ドットのテクスチャが16×16個まとまっているものである.
フォルダ構造
ソースコード
- mcroot/src/common/mods/spritesample
- SpriteSampleCore.java
- BlockSpriteSample.java
- ItemSpriteSample.java
- CommonProxy.java
- /client
- ClientProxy
テクスチャ
- mcroot/bin/minecraft/mods/sprites
- blocks.png
- items.png
ソースコード
- SpriteSampleCore
package mods.spritesample; import java.util.logging.Level; import net.minecraft.src.*; import net.minecraftforge.common.Configuration; import net.minecraftforge.common.Property; import cpw.mods.fml.common.SidedProxy; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.network.NetworkMod; 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.common.registry.LanguageRegistry; @Mod( modid = "SpriteSampleMod", name = "Sprite Sample Mod", version = "1.0.0" ) @NetworkMod( clientSideRequired = true, serverSideRequired = false ) public class SpriteSampleCore { @SidedProxy(clientSide = "mods.spritesample.client.ClientProxy", serverSide = "mods.spritesample.CommonProxy") public static CommonProxy proxy; public static Block blockSpriteSample; public static Item itemSpriteSample; public int blockIdSpriteSample; public int itemIdSpriteSample; @Mod.PreInit public void preInit(FMLPreInitializationEvent event) { Configuration cfg = new Configuration(event.getSuggestedConfigurationFile()); try { cfg.load(); Property blockProp = cfg.getBlock("SpriteSampleBlock", 1302); Property itemProp = cfg.getItem("SpriteSampleItem", 4002); blockProp.comment = "This comment is Block Property"; itemProp.comment = "This comment is Item Property"; blockIdSpriteSample = blockProp.getInt(); itemIdSpriteSample = itemProp.getInt(); } catch (Exception e) { FMLLog.log(Level.SEVERE, e, "Error Message"); } finally { cfg.save(); } } @Mod.Init public void init(FMLInitializationEvent event) { blockSpriteSample = (new BlockSpriteSample(blockIdSpriteSample, 0)).setBlockName("spritesampleblock").setCreativeTab(CreativeTabs.tabBlock); itemSpriteSample = (new ItemSpriteSample(itemIdSpriteSample)).setIconCoord(0, 0).setItemName("spritesampleitem").setCreativeTab(CreativeTabs.tabMaterials); GameRegistry.registerBlock(blockSpriteSample); LanguageRegistry.addName(blockSpriteSample, "Sprite Sample Block"); LanguageRegistry.instance().addNameForObject(blockSpriteSample, "ja_JP", "スプライトサンプルブロック"); LanguageRegistry.addName(itemSpriteSample, "Sprite Sample Item"); LanguageRegistry.instance().addNameForObject(itemSpriteSample, "ja_JP", "スプライトサンプルアイテム"); GameRegistry.addShapelessRecipe( new ItemStack(itemSpriteSample, 1), new Object[] { Block.stone }); GameRegistry.addShapelessRecipe( new ItemStack(blockSpriteSample, 1), new Object[] { Block.stone, Block.stone }); proxy.registerTextures(); } }
- BlockSpriteSample
package mods.spritesample; import net.minecraft.src.*; public class BlockSpriteSample extends Block { public BlockSpriteSample(int blockId, int terrainId) { super(blockId, terrainId, Material.wood); } @Override public String getTextureFile() { return "/mods/sprites/blocks.png"; } }
- ItemSpriteSample
package mods.spritesample; import net.minecraft.src.*; public class ItemSpriteSample extends Item { public ItemSpriteSample(int itemId) { super(itemId); } @Override public String getTextureFile() { return "/mods/sprites/items.png"; } }
- CommonProxy
package mods.spritesample; import net.minecraft.src.*; public class CommonProxy { public void registerTextures() { //何もしない } }
- ClientProxy
package mods.spritesample.client; import net.minecraft.src.*; import net.minecraftforge.client.MinecraftForgeClient; import cpw.mods.fml.common.Side; import cpw.mods.fml.common.asm.SideOnly; import mods.spritesample.CommonProxy; @SideOnly(Side.CLIENT) public class ClientProxy extends CommonProxy { @Override public void registerTextures() { MinecraftForgeClient.preloadTexture("/mods/sprites/blocks.png"); MinecraftForgeClient.preloadTexture("/mods/sprites/items.png"); } }
解説
Forge式コンフィグファイルの利用同様, 既に解説した箇所の解説は省略する.
SpriteSampleCore
import cpw.mods.fml.common.SidedProxy;
- プロキシシステムを使うためのアノテーション.
@SidedProxy(clientSide = "mods.spritesample.client.ClientProxy", serverSide = "mods.spritesample.CommonProxy") public static CommonProxy proxy;
- @SidedProxyの引数でクライアント側とサーバー側のクラスを指定する. この指定はフルパスでなければならない.
proxy.registerTextures();
- プロキシのインスタンスを通してテクスチャの登録を行う. この1行はクライアント側でもサーバー側でも実行されるが, それぞれの実装はClientProxy, CommonProxyで異なる.
BlockSpriteSample
public String getTextureFile() { return "/mods/sprites/blocks.png"; }
- 参照したいテクスチャファイルのパスを返す. この時テクスチャ自体はmcroot/bin/minecraft/mods/spritesフォルダにあることになる.
ItemSpriteSample
public String getTextureFile() { return "/mods/sprites/items.png"; }
- ブロックの場合と同様. アイテムのテクスチャファイルのパスを返す.
CommonProxy
public void registerTextures() { //何もしない }
- サーバー側, CommonProxyでは何もしないが, ClientProxyでオーバーライドして使うために空のメソッドを定義している.
ClientProxy
package mods.spritesample.client;
- クライアント専用のクラスは全てmods/spritesample/clientフォルダに入れることで, どのクラスがクライアント専用なのかをはっきりさせる. 必要ないなら同じパッケージでよい.
<soruce lang = "java"> import net.minecraftforge.client.MinecraftForgeClient; </source>
- MinecraftForgeAPIのうちクライアント側のみの機能を提供するクラス.
import cpw.mods.fml.common.Side; import cpw.mods.fml.common.asm.SideOnly;
- 新しいコーディング記法とUniversal Moddingで触れたアノテーション. 共通でない(≒クライアント専用, サーバー専用)クラスやメソッドにつける.
import mods.spritesample.CommonProxy;
- CommonProxyとはパッケージが異なるのでインポートしておく.
@SideOnly(Side.CLIENT) public class ClientProxy extends CommonProxy
- ClientProxyに@SideOnlyアノテーションを付与している. またClientProxyはCommonProxyを継承している.
@Override public void registerTextures() { MinecraftForgeClient.preloadTexture("/mods/sprites/blocks.png"); MinecraftForgeClient.preloadTexture("/mods/sprites/items.png"); }
- CommonProxyで定義したメソッドをオーバーライドする. preloadTextureは引数のパスで指定した画像ファイルをキャッシュに読み込むメソッド. ここで指定する引数は上記のBlockSpriteSampleクラスとItemSpriteSampleクラスで記述したファイルパスと同じにする.
実際の挙動
今回の挙動も今までのサンプルとは大差ない. しかし, blocks.pngやitems.pngの左上の16*16のテクスチャを変更したり, コード内のterrainIdやsetIconCoordを変更するとそれに応じてテクスチャも変更される.