提供: Minecraft Modding Wiki
2016年7月2日 (土) 13:45時点における124.241.52.191 (トーク)による版 (誤字の修正)
移動先: 案内検索

この記事は"Minecraft Forge Universal 10.12.0.xxx~"を前提MODとしています。

Wood pickaxe.png
初心者向けのチュートリアルです。


GUIの追加

ブロックやアイテムにGUIを追加する

ソースコード

SampleMod.java

package mods.sampleMod;

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.FMLPostInitializationEvent;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.block.Block;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.item.Item;

//FMLのパケットシステムはForge 10.12.1.1090以降でないと動作しないので、使う予定があるならdependenciesでそれ以降を指定すること。
@Mod(modid = "SampleMod", name = "SampleMod", version = "1.0", dependencies = "required-after:Forge@[10.12.1.1090,)", useMetadata = true)
public class SampleMod {

    @Mod.Instance("SampleMod")
    public static SampleMod INSTANCE;
    public static Block sampleGuiBlock;
    public static Item sampleGuiItem;

    public static final int GUI_ID = 0;

    @EventHandler
    public void preInit(FMLPostInitializationEvent event) {
        sampleGuiBlock = new SampleGuiBlock().setBlockTextureName("stone").setBlockName("sampleGuiBlock").setCreativeTab(CreativeTabs.tabBlock);
        GameRegistry.registerBlock(sampleGuiBlock, "sample_guiGlock");
        sampleGuiItem = new SampleGuiItem().setTextureName("arrow").setUnlocalizedName("sampleGuiItem").setCreativeTab(CreativeTabs.tabMisc);
        GameRegistry.registerItem(sampleGuiItem, "sample_GuiItem");
    }

    @EventHandler
    public void init(FMLInitializationEvent event) {
        NetworkRegistry.INSTANCE.registerGuiHandler(this, new GuiHandler());
    }
}

GuiHandler.java

package mods.sampleMod;

import cpw.mods.fml.common.network.IGuiHandler;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;

public class GuiHandler implements IGuiHandler {
    /*サーバー側の処理*/
    @Override
    public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
        if (ID == SampleMod.GUI_ID) {
            return new SampleContainer(x, y, z);
        }
        return null;
    }

    /*クライアント側の処理*/
    @Override
    public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
        if (ID == SampleMod.GUI_ID) {
            return new SampleGuiContainer(x, y, z);
        }
        return null;
    }
}

SampleGuiBlock.java

package mods.sampleMod;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;

public class SampleGuiBlock extends Block {
    public SampleGuiBlock() {
        super(Material.wood);
    }

    @Override
    public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
        player.openGui(SampleMod.INSTANCE, SampleMod.GUI_ID, world, x, y, z);
        return true;
    }
}

SampleGuiItem.java

package mods.sampleMod;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;

public class SampleGuiItem extends Item {
    @Override
    public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player) {
        player.openGui(SampleMod.INSTANCE, SampleMod.GUI_ID, world, MathHelper.ceiling_double_int(player.posX), MathHelper.ceiling_double_int(player.posY), MathHelper.ceiling_double_int(player.posZ));
        return itemStack;
    }
}

SampleContainer.java

package ak.sampleMod;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;

public class SampleContainer extends Container {
    //座標でGUIを開くか判定するためのもの。
    int xCoord, yCoord, zCoord;
    public SampleContainer(int x, int y, int z) {
        this.xCoord = x;
        this.yCoord = y;
        this.zCoord = z;
    }

    @Override
    public boolean canInteractWith(EntityPlayer player) {
        //もし、ブロックとの位置関係でGUI制御したいなら、こちらを使う
//        return player.getDistanceSq(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCoord + 0.5D) <= 64D;
        return true;
    }
}

SampleGuiContainer.java

package ak.sampleMod;

import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.util.ResourceLocation;

public class SampleGuiContainer extends GuiContainer {
    private static final ResourceLocation TEXTURE = new ResourceLocation("<DomainName>", "textures/gui/gui_texture.png");
    public SampleGuiContainer(int x, int y, int z) {
        super(new SampleContainer(x, y, z));
    }

    /*GUIの文字等の描画処理*/
    @Override
    protected void drawGuiContainerForegroundLayer(int mouseX, int mouseZ) {
        super.drawGuiContainerForegroundLayer(mouseX, mouseZ);
    }

    /*GUIの背景の描画処理*/
    @Override
    protected void drawGuiContainerBackgroundLayer(float partialTick, int mouseX, int mouseZ) {
        this.mc.renderEngine.bindTexture(TEXTURE);
        this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, xSize, ySize);
    }

    /*GUIが開いている時にゲームの処理を止めるかどうか。*/
    @Override
    public boolean doesGuiPauseGame() {
        return false;
    }
}

解説

SampleModクラス

public static final int GUI_ID = 0;

開くGUIのID。MOD内で分けられていればよい。

NetworkRegistry.INSTANCE.registerGuiHandler(this, new GuiHandler());

IGuiHandlerを実装しているクラスを登録する処理。

GuiHandlerクラス

public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
    if (ID == SampleMod.GUI_ID) {
        return new SampleContainer(x, y, z);
    }
    return null;
}

サーバー側の処理。IDで判定して、Containerクラスを生成し返している。

public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
    if (ID == SampleMod.GUI_ID) {
        return new SampleGuiContainer(x, y, z);
    }
    return null;
}

クライアント側の処理。IDで判定して、GuiContainerクラスを生成し返している。

SampleGuiBlockクラス、SampleGuiItemクラス

public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
    player.openGui(SampleMod.INSTANCE, SampleMod.GUI_ID, world, x, y, z);
    return true;
}

ブロックを右クリックした際にGUIを開く。

public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player) {
    player.openGui(SampleMod.INSTANCE, SampleMod.GUI_ID, world, MathHelper.ceiling_double_int(player.posX), MathHelper.ceiling_double_int(player.posY), MathHelper.ceiling_double_int(player.posZ));
    return itemStack;
}

アイテムを右クリックした際にGUIを開く。プレイヤーの位置情報を渡しているが、アイテムの場合は無くてもよい。

SampleContainerクラス

public boolean canInteractWith(EntityPlayer player) {
    //もし、ブロックとの位置関係でGUI制御したいなら、こちらを使う
//    return player.getDistanceSq(this.xCoord + 0.5D, this.yCoord + 0.5D, this.zCorrd + 0.5D) <= 64D;
    return true;
}

GUIを開くかどうかを判定するメソッド。trueで開く。プレイヤーの位置情報や、TileEntityで判定してもよい。

SampleGuiContainerクラス

private static final ResourceLocation TEXTURE = new ResourceLocation("<DomainName>", "textures/gui/gui_texture.png");

GUIの背景画像の情報を保持させている。texturesフォルダ以下ならguiフォルダに置く必要はない。

protected void drawGuiContainerForegroundLayer(int mouseX, int mouseZ) {
    super.drawGuiContainerForegroundLayer(mouseX, mouseZ);
}

文字やアイテムの描画処理を行う。

protected void drawGuiContainerBackgroundLayer(float partialTick, int mouseX, int mouseZ) {
    this.mc.renderEngine.bindTexture(TEXTURE);
    this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, xSize, ySize);
}

GUIの背景や、かまどの炎、矢印の処理を行う。

public boolean doesGuiPauseGame() {
    return false;
}

GUIを開いている時にTick処理を続けるかどうか。trueで止める。