本帖最后由 SPE__HaiKuo 于 2015-7-1 13:18 编辑 
前言:
Gui这个万年坑脱了好久,最近有空余时间也重新研究了,困难重重啊,和几位仙贝也讨论了好久,1.8真是变化太大了,让人无时无刻想着我*他Forge!我*他Mojang!我*他Notch!看着论坛的Gui教程就只要当风(过时)的教程了,这里就分享一下自己的经验吧。
本篇先介绍一些基础的备用知识,做一个基本的界面出来,请各位刚学Java的小白点击右上角,毕竟下面的内容直接代码轰炸可能会很难理解
正篇:
这里示例做一个方块,取名为TestGui,因为测试的时候用的是小组在开发的Mod我也懒得单独提取出来了,主类为infstudio.exoticpower.ExoticPower
如果要做一个Gui将会有以下几个文件:BlockTestGui、GuiTestGui、ContainerTestGui、TileEntityTestGui、GuiHandler、GuiID(可有可无)
因为Gui制作非常复杂,传统主类可能做着做着就晕了,所以我们新建一个类proxy,里面创建CommonProxy和ClientProxy
主类ExoticPower代码:
复制代码
注意:@Instance里的内容必须与modid一致,否则制作Gui会崩溃
CommonProxy代码:
复制代码
ClientProxy代码:
复制代码
准备好这些基础后我们在创建block包并在包下创建BlockTestGui.java继承BlockContainer
复制代码
创建gui.inventory包并在包下创建GuiTestGui.java继承GuiContainer
复制代码
这里就提供给大家一张图(其实就是当风的图):

创建tileentity包并在包下创建TileEntityTestGui.java继承TileEntity实现IUpdatePlayerListBox和IInventory
复制代码
创建inventory包并在包下创建ContainerTestGui.java
复制代码
在主类创建GuiID类,存取Gui的ID
复制代码
这时我们再在BlockTestGui增加createNewTileEntity和onBlockActivated方法
复制代码
再创建util包和GuiHandler类继承IGuiHandler类
复制代码
至此基础已经准备就绪,最后再在CommonProxy注册
复制代码
所有准备已经就绪,现在打开游戏试试吧!

后序:
不过这个Gui现在什么用都没有,我们要通过更改TileEntity来创建他的功能,具体操作下一个Part会讲,有兴趣的可以先看看当风过时的教程,其实Gui就是不断魔改熔炉等带Gui的方块,只要理解了每个方法的含义就能轻而易举地创造出属于自己的Gui_(:з」∠)_
*如果有什么好的意见可以提出来哦qwq
*小唠叨:为何格式那么奇怪啊!调了好久啊!
*求人气求金粒_(:з」∠)_
来自群组: InfinityStudio
前言:
Gui这个万年坑脱了好久,最近有空余时间也重新研究了,困难重重啊,和几位仙贝也讨论了好久,1.8真是变化太大了,让人无时无刻想着
本篇先介绍一些基础的备用知识,做一个基本的界面出来,请各位刚学Java的小白点击右上角,毕竟下面的内容直接代码轰炸可能会很难理解
正篇:
这里示例做一个方块,取名为TestGui,因为测试的时候用的是小组在开发的Mod我也懒得单独提取出来了,主类为infstudio.exoticpower.ExoticPower
如果要做一个Gui将会有以下几个文件:BlockTestGui、GuiTestGui、ContainerTestGui、TileEntityTestGui、GuiHandler、GuiID(可有可无)
因为Gui制作非常复杂,传统主类可能做着做着就晕了,所以我们新建一个类proxy,里面创建CommonProxy和ClientProxy
主类ExoticPower代码:
- package infstudio.exoticpower;
 
 
- import infstudio.exoticpower.proxy.CommonProxy;
 
- import net.minecraftforge.fml.common.Mod;
 
- import net.minecraftforge.fml.common.Mod.EventHandler;
 
- import net.minecraftforge.fml.common.Mod.Instance;
 
- import net.minecraftforge.fml.common.SidedProxy;
 
- import net.minecraftforge.fml.common.event.FMLInitializationEvent;
 
- import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
 
- import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
 
 
- @Mod(modid = "ExoticPower", name="ExoticPower" ,version= "1.0.0")
 
- public class ExoticPower {
 
 
-         @SidedProxy(clientSide = "infstudio.exoticpower.proxy.ClientProxy", serverSide = "infstudio.exoticpower.proxy.CommonProxy")
 
-         public static CommonProxy proxy;
 
 
-         @Instance("ExoticPower")
 
-         public static ExoticPower instance;
 
-         
 
-         @EventHandler
 
-         public void preInit(FMLPreInitializationEvent event) {
 
-                 proxy.preInit(event);
 
-         }
 
-  
 
-         @EventHandler
 
-         public void init(FMLInitializationEvent event) {
 
-                 proxy.init(event);
 
-         }
 
-  
 
-         @EventHandler
 
-         public void postInit(FMLPostInitializationEvent event) {
 
-             proxy.postInit(event);
 
-         }
 
-     
 
- }
注意:@Instance里的内容必须与modid一致,否则制作Gui会崩溃
CommonProxy代码:
- package infstudio.exoticpower.proxy;
 
 
- import net.minecraftforge.fml.common.event.FMLInitializationEvent;
 
- import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
 
- import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
 
 
- public class CommonProxy {
 
 
-         public void preInit(FMLPreInitializationEvent event) {
 
-             
 
-         }
 
-          
 
-         public void init(FMLInitializationEvent event) {
 
-                 //注册方块、物品、Gui等
 
-         }
 
-          
 
-         public void postInit(FMLPostInitializationEvent event) {
 
-             
 
-         }
 
-         
 
- }
ClientProxy代码:
- package infstudio.exoticpower.proxy;
 
 
- import net.minecraftforge.fml.common.event.FMLInitializationEvent;
 
- import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
 
- import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
 
 
- public class ClientProxy extends CommonProxy {
 
 
-         public void preInit(FMLPreInitializationEvent event) {
 
-         
 
-         }
 
-  
 
-         public void init(FMLInitializationEvent event) {
 
-                 super.init(event);
 
-                 为物品和方块添加材质
 
-         }
 
-  
 
-         public void postInit(FMLPostInitializationEvent event) {
 
-         
 
-         }
 
-     
 
- }
准备好这些基础后我们在创建block包并在包下创建BlockTestGui.java继承BlockContainer
- package infstudio.exoticpower.block;
 
 
- import net.minecraft.block.BlockContainer;
 
 
- public class BlockTestGui extends BlockContainer {
 
 
-         protected BlockTestGui() {
 
-                 super(Material.rock);
 
-         }
 
-         
 
- }
创建gui.inventory包并在包下创建GuiTestGui.java继承GuiContainer
- package infstudio.exoticpower.gui.inventory;
 
 
- import infstudio.exoticpower.inventory.ContainerTestGui;
 
- import infstudio.exoticpower.tileentity.TileEntityTestGui;
 
- import net.minecraft.client.gui.inventory.GuiContainer;
 
- import net.minecraft.client.renderer.GlStateManager;
 
- import net.minecraft.client.resources.I18n;
 
- import net.minecraft.entity.player.InventoryPlayer;
 
- import net.minecraft.inventory.Container;
 
- import net.minecraft.tileentity.TileEntityFurnace;
 
- import net.minecraft.util.ResourceLocation;
 
- import net.minecraft.util.StatCollector;
 
 
- public class GuiTestGui extends GuiContainer {
 
 
-         private TileEntityTestGui tile;
 
-         
 
-         public GuiTestGui(InventoryPlayer playerInv, TileEntityTestGui tileEntity) {
 
-                 super(new ContainerTestGui(playerInv, tileEntity));
 
-                 // TODO Auto-generated constructor stub
 
-                 this.tile = tileEntity;
 
-                 this.doesGuiPauseGame();
 
-         }
 
 
-         @Override
 
-         protected void drawGuiContainerForegroundLayer(int par1, int par2) {
 
-                 String s = StatCollector.translateToLocal("TitleTestGui");    //设置Gui标题
 
-                 this.fontRendererObj.drawString(s, this.xSize / 2 - this.fontRendererObj.getStringWidth(s) / 2, 6, 4210752);
 
-                 this.fontRendererObj.drawString(I18n.format("container.inventory", new Object[0]), 8, this.ySize - 96 + 2, 4210752);
 
-         }
 
-         
 
-         @Override
 
-         protected void drawGuiContainerBackgroundLayer(float var1, int var2, int var3) {
 
-                 // TODO Auto-generated method stub
 
-                 GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
 
-                 this.mc.getTextureManager().bindTexture(new ResourceLocation("exoticpower", "textures/gui/container/testgui.png"));
 
-                 //gui贴图存储地址
 
-                 int k = (this.width - this.xSize) / 2;
 
-                 int l = (this.height - this.ySize) / 2;
 
-                 this.drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize);
 
-         }
 
-         
 
- }
这里就提供给大家一张图(其实就是当风的图):

创建tileentity包并在包下创建TileEntityTestGui.java继承TileEntity实现IUpdatePlayerListBox和IInventory
- package infstudio.exoticpower.tileentity;
 
 
- import net.minecraft.entity.player.EntityPlayer;
 
- import net.minecraft.inventory.IInventory;
 
- import net.minecraft.item.ItemStack;
 
- import net.minecraft.server.gui.IUpdatePlayerListBox;
 
- import net.minecraft.tileentity.TileEntity;
 
- import net.minecraft.util.IChatComponent;
 
 
- public class TileEntityTestGui extends TileEntity implements IUpdatePlayerListBox, IInventory{
 
 
-         private ItemStack tstack[] = new ItemStack[3];    //数量与Gui中库存(槽)个数有关
 
-         
 
-         public void update() {
 
-                 //此方法必须加
 
-         }
 
 
-         @Override
 
-         public String getName() {
 
-                 // TODO Auto-generated method stub
 
-                 return null;
 
-         }
 
 
-         @Override
 
-         public boolean hasCustomName() {
 
-                 // TODO Auto-generated method stub
 
-                 return false;
 
-         }
 
 
-         @Override
 
-         public IChatComponent getDisplayName() {
 
-                 // TODO Auto-generated method stub
 
-                 return null;
 
-         }
 
 
-         @Override
 
-         public int getSizeInventory() {
 
-                 // TODO Auto-generated method stub
 
-                 return tstack.length;
 
-         }    //获得最大库存
 
 
-         @Override
 
-         public ItemStack getStackInSlot(int index) {
 
-                 // TODO Auto-generated method stub
 
-                 return tstack[index];
 
-         }    //获得库存中的物品栈
 
 
-         @Override
 
-         public ItemStack decrStackSize(int index, int count) {
 
-                 if (this.tstack[index] != null)
 
-                 {
 
-                             ItemStack itemstack;
 
 
-                             if (this.tstack[index].stackSize <= count)
 
-                             {
 
-                                 itemstack = this.tstack[index];
 
-                                 this.tstack[index] = null;
 
-                                 return itemstack;
 
-                             }
 
-                             else
 
-                             {
 
-                                 itemstack = this.tstack[index].splitStack(count);
 
 
-                                 if (this.tstack[index].stackSize == 0)
 
-                                 {
 
-                                             this.tstack[index] = null;
 
-                                 }
 
 
-                                 return itemstack;
 
-                             }
 
-                 }
 
-                 else
 
-                        {
 
-                             return null;
 
-                 }
 
-         }    //复制原版熔炉代码
 
 
-         @Override
 
-         public ItemStack getStackInSlotOnClosing(int index) {
 
-                 // TODO Auto-generated method stub
 
-                 return null;
 
-         }    //关闭Gui时触发的事件
 
 
-         @Override
 
-         public void setInventorySlotContents(int index, ItemStack stack) {
 
-                 // TODO Auto-generated method stub
 
-                 this.tstack[index] = stack;
 
-                 if (stack != null && stack.stackSize > this.getInventoryStackLimit())
 
-                 {
 
-                             stack.stackSize = this.getInventoryStackLimit();
 
-                 }
 
-         }    //复制原版熔炉代码
 
 
-         @Override
 
-         public int getInventoryStackLimit() {
 
-                 // TODO Auto-generated method stub
 
-                 return 64;
 
-         }    //单个物品栈最大容量
 
 
-         @Override
 
-         public boolean isUseableByPlayer(EntityPlayer player) {
 
-                 // TODO Auto-generated method stub
 
-                 return true;
 
-         }    //是否任何人都能使用Gui
 
 
-         @Override
 
-         public void openInventory(EntityPlayer player) {
 
-                 // TODO Auto-generated method stub
 
-                 
 
-         }
 
 
-         @Override
 
-         public void closeInventory(EntityPlayer player) {
 
-                 // TODO Auto-generated method stub
 
-                 
 
-         }
 
 
-         @Override
 
-         public boolean isItemValidForSlot(int index, ItemStack stack) {
 
-                 // TODO Auto-generated method stub
 
-                 return false;
 
-         }
 
 
-         @Override
 
-         public int getField(int id) {
 
-                 // TODO Auto-generated method stub
 
-                 return 0;
 
-         }
 
 
-         @Override
 
-         public void setField(int id, int value) {
 
-                 // TODO Auto-generated method stub
 
-                 
 
-         }
 
 
-         @Override
 
-         public int getFieldCount() {
 
-                 // TODO Auto-generated method stub
 
-                 return 0;
 
-         }
 
 
-         @Override
 
-         public void clear() {
 
-                 // TODO Auto-generated method stub
 
-                 
 
-         }
 
-         
 
- }
创建inventory包并在包下创建ContainerTestGui.java
- package infstudio.exoticpower.inventory;
 
 
- import infstudio.exoticpower.tileentity.TileEntityTestGui;
 
- import net.minecraft.entity.player.EntityPlayer;
 
- import net.minecraft.entity.player.InventoryPlayer;
 
- import net.minecraft.inventory.Container;
 
- import net.minecraft.inventory.Slot;
 
 
- public class ContainerTestGui extends Container{
 
 
-         private TileEntityTestGui tile;
 
-         
 
-         public ContainerTestGui(InventoryPlayer par1InventoryPlayer, TileEntityTestGui tileEntity) {
 
-                 this.tile = tileEntity;
 
-                 this.addSlotToContainer(new Slot(tileEntity, 0, 49, 19));
 
-                 this.addSlotToContainer(new Slot(tileEntity, 1, 112, 19));
 
-                 this.addSlotToContainer(new Slot(tileEntity, 2, 80, 54));    //设置物品栏的槽
 
-                 int var3;
 
-                 for (var3 = 0; var3 < 3; ++var3)
 
-                 {
 
-                             for (int var4 = 0; var4 < 9; ++var4)
 
-                             {
 
-                                 this.addSlotToContainer(new Slot(par1InventoryPlayer, var4 + var3 * 9 + 9, 8 + var4 * 18, 84 + var3 * 18));
 
-                             }
 
-                 }
 
 
-                 for (var3 = 0; var3 < 9; ++var3)
 
-                 {
 
-                             this.addSlotToContainer(new Slot(par1InventoryPlayer, var3, 8 + var3 * 18, 142));
 
-                 }    //设置Gui的槽
 
-                 //第一个参数是IInventory,第二个参数是ID,对应第一个参数,即取得第一个参数对应ID的内容,第三个参数是显示的X坐标,第四个是参数是显示的Y坐标
 
-         }
 
-         
 
-         @Override
 
-         public boolean canInteractWith(EntityPlayer playerIn) {
 
-                 // TODO Auto-generated method stub
 
-                 return true;
 
-                 //能否打开Gui
 
-         }
 
 
- }
在主类创建GuiID类,存取Gui的ID
- package infstudio.exoticpower;
 
 
- public class GuiID {
 
 
-         public static final int GUI_TG = 0;
 
-         
 
- }
这时我们再在BlockTestGui增加createNewTileEntity和onBlockActivated方法
- @Override
 
-         public TileEntity createNewTileEntity(World worldIn, int meta) {
 
-                 return new TileEntityTestGui();
 
-         }
 
-         
 
-         @Override
 
-         public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumFacing side, float hitX, float hitY, float hitZ)
 
-         {
 
-                 ItemStack stack = playerIn.inventory.mainInventory[playerIn.inventory.currentItem];
 
-                 playerIn.openGui(ExoticPower.instance, GuiID.GUI_TG, worldIn, pos.getX(), pos.getY(), pos.getZ());
 
-         return true;
 
- }
再创建util包和GuiHandler类继承IGuiHandler类
- package infstudio.exoticpower.util;
 
 
- import infstudio.exoticpower.gui.inventory.GuiTestGui;
 
- import infstudio.exoticpower.inventory.ContainerTestGui;
 
- import infstudio.exoticpower.tileentity.TileEntityTestGui;
 
- import infstudio.exoticpower.GuiID;
 
- import net.minecraft.entity.player.EntityPlayer;
 
- import net.minecraft.util.BlockPos;
 
- import net.minecraft.world.World;
 
- import net.minecraftforge.fml.common.network.IGuiHandler;
 
 
- public class GuiHandler implements IGuiHandler{
 
 
-         @Override
 
-         public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
 
-                 // TODO Auto-generated method stub
 
-                 BlockPos bp = new BlockPos(x, y, z);
 
-                 switch(ID)
 
-                 {
 
-                 case GuiID.GUI_TG:
 
-                         return new ContainerTestGui(player.inventory, (TileEntityTestGui)world.getTileEntity(bp));
 
-                 }
 
-                 return null;
 
-         }
 
 
-         @Override
 
-         public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
 
-                 // TODO Auto-generated method stub
 
-                 BlockPos bp = new BlockPos(x, y, z);
 
-                 switch(ID)
 
-                 {
 
-                 case GuiID.GUI_TG:
 
-                         return new GuiTestGui(player.inventory, (TileEntityTestGui) world.getTileEntity(bp));
 
-                 }
 
-                 return null;
 
-         }
 
 
- }
至此基础已经准备就绪,最后再在CommonProxy注册
 
-         public static Block testgui = new BlockTestGui();
 
 
-         public void init(FMLInitializationEvent event) {
 
-                     GameRegistry.registerBlock(testgui, "testgui");
 
-                 GameRegistry.registerTileEntity(TileEntityTestGui.class, "TileEntityTestGui");
 
-                 NetworkRegistry.INSTANCE.registerGuiHandler(ExoticPower.instance, new GuiHandler());
 
- }
所有准备已经就绪,现在打开游戏试试吧!

后序:
不过这个Gui现在什么用都没有,我们要通过更改TileEntity来创建他的功能,具体操作下一个Part会讲,有兴趣的可以先看看当风过时的教程,其实Gui就是不断魔改熔炉等带Gui的方块,只要理解了每个方法的含义就能轻而易举地创造出属于自己的Gui_(:з」∠)_
*如果有什么好的意见可以提出来哦qwq
*小唠叨:为何格式那么奇怪啊!调了好久啊!
*求人气求金粒_(:з」∠)_
来自群组: InfinityStudio
真.前排围观大触
學java學到一半就想放棄了......這麼多內容學不完啊{:10_524:}
大力出奇迹{:10_501:}
然而我至今都做不了一个方块 下面的问题没人回答
群里来支持
我看看,感觉代码号难== 
这个gui看上去就是烧制嘛....
支持,这是中国第一张的1.8gui教程,不错不错
mcjava 发表于 2015-7-1 21:35
然而ExoticPower快点开发出来!
支持,这是中国第一张的1.8gui教程,不错不错 ...
Java代码死记中
黑暗空间 发表于 2015-7-2 20:45
Java代码死记中
也是醉了
字好少...感觉代码要比字多得多...
求教,我每次一右击我的新方块就shutting down internal server了。。
我是按照Anvil来改的,就是没有对应的entity了。
就算是跳过这些,直接在onBlockActivated方法里
Minecraft.getMinecraft().displayGuiScreen(new GuiExchange(player.inventory, w, x, y, z));
这样的话也是闪退。(我的Gui是GuiExchange)
而相反的,如果直接
Minecraft.getMinecraft().displayGuiScreen(new GuiRepair(player.inventory, w, x, y, z));
的话至少能看到页面(虽然会鬼畜)。。
是我的Gui里面出错了吗?(可是我自我感觉还是没有改掉Anvil的关键东西的。。)
跪求解答。。
我是按照Anvil来改的,就是没有对应的entity了。
就算是跳过这些,直接在onBlockActivated方法里
Minecraft.getMinecraft().displayGuiScreen(new GuiExchange(player.inventory, w, x, y, z));
这样的话也是闪退。(我的Gui是GuiExchange)
而相反的,如果直接
Minecraft.getMinecraft().displayGuiScreen(new GuiRepair(player.inventory, w, x, y, z));
的话至少能看到页面(虽然会鬼畜)。。
是我的Gui里面出错了吗?(可是我自我感觉还是没有改掉Anvil的关键东西的。。)
跪求解答。。
哎呦不错哦
exoticpower,被这个mod惊呆了
MC的GUI一直无力吐槽.....(要是能用Swing 该多好OTZ)
支持一下,写了那么大篇幅。不过我已经被楼主的代码绕晕了。
这样的方法能用在1.7.10么 =。= 找不到1.7.10的gui教程哎
请问一下 在1.7.10中 blockpos 这个类是用什么代替的?