本帖最后由 当风过时 于 2016-2-16 22:08 编辑
1.8.9的教程:http://www.windworkshop.cn/?p=889
1.7.10的教程:http://www.windworkshop.cn/?p=36
复制代码
目前这只是一个没有任何功能的方块。先来做TileEntity,新建一个类,名称为rtTileEntityRepairTable,继承TileEntity重写updateEntity(),updateEntity是更新TileEntity的函数,想让TileEntity工作全部都得依赖于它。在updateEntity中写上个输出语句吧。
复制代码
然后给Block里的createNewTileEntity方法返回一个TileEntity,返回刚在写好的rtTileEntityRepairTable
复制代码
这个步骤完成后还需要在mod文件中注册各种东西(因为这个是直接更换过来的,过程没有重新做,这个地方如果出现bug的话就以最终的那个为准)要引用IGuiHandler,这个接口是打开GUI的制定接口,根据接口所需的函数就能打开GUI复制代码
我暂时先用砖块的贴图来代替吧- -
放置方块后你会看见调试窗里出现了刚才写的输出语句。
updateEntity会在每个tick里调用一次,每调用一次就相当于刷新一次数据,至于刷新什么数据,这些都是由你自己定的了,一般就是燃烧时间之类的。基本的功能方块就构成了。不过这个方块还没有窗口,只具备了基本的刷新数据的功能,接下来就该做GUI了。
新建一个类,名字为rtGuiRepairTable,继承GuiContainer,eclipse修正一下。复制代码这是一个没有任何东西的基本的GUI。然后再新建一个类,名字为rtContainerRepairTable,继承Container。
复制代码canInteractWith返回的是是否打开GUI,设定为true。
在gui中覆写drawGuiContainerForegroundLayer(描绘前景文字),以及在drawGuiContainerBackgroundLayer中描绘背景,最后修改一下构造函数:
复制代码
附上描绘用的GUI窗口
doesGuiPauseGame是是否在打开gui的时候停止游戏。构造函数那里需要返回一个Container。为啥要返回我也不清楚- -我觉得在某些方面有些多余。
接下来就是接口部分了(这个地方很多得重新做啊。。。)
在mod文件中注册IGuiHandler,注册后就能在回调函数getClientGuiElement和getServerGuiElement分别获得Gui和Container,至于这两个函数怎么用,待会解释。
复制代码重写mod中的getClientGuiElement
复制代码重写mod中的getServerGuiElement
复制代码接着是重写block的onBlockActivated复制代码现在就可以来解释一下GUI的打开流程了:右键激活方块,方块调用EntityPlayer.openGui来打开回调相应端的GUI组件,第一个参数是相应mod的实例,第二个参数是gui的ID,第三个是World实例,第四个到第六个是三个数字,怎么填随你喜欢,一般是给出方块的坐标,方便通过world来查找到对应的TileEntity,由于在1.4中,服务端和客户端是整合在一块的,所以需要两个函数来管理,就是之前在mod文件中的getClientGuiElement和getServerGuiElement,通过这两个函数共同协助才能构建一个GUI,只有经过这条路径来打开的GUI才是能使用的GUI,用Modloader.openGUI来打开的GUI无法更新,只能作为提示窗口来用(基本也没什么提示作用- -)。 完成上述步骤后,你应该就能看到久违的窗口了。
完成这个步骤后得到的代码:
mod_RepairTable.java
rtBlockRepairTable.java
rtGuiRepairTable.java
rtContainerRepairTable.java
rtTileEntityRepairTable.java
貌似有些地方跳过了- -跟着工程的代码凑合一下吧(我觉得我真心不适合教书- -)。。。第一篇就先做到这里,后面还有很多东西要说。。。
预定的内容:自定义TileEntity的行为
进度条的描绘
数据的同步
一些注意事项
或者还有些什么突然想起的东西- -
看这篇教程需要一定的mod制作基础,没有什么基础的话请先去看看基础教程,把基础打好再说。
1.8.9的教程:http://www.windworkshop.cn/?p=889
1.7.10的教程:http://www.windworkshop.cn/?p=36
第二篇,自定义TileEntity的行为:http://www.mcbbs.net/thread-76005-1-1.html
第三篇,同步客户端与服务端的数据:http://www.mcbbs.net/thread-78145-1-1.html
说起GUI,是我心中难以磨灭的阴影。。。当初在学的时候各种坑,刚爬出来就到另外一个坑,方块GUI可以说是minecraft里面很麻烦的东西,源代码里没用可供参考的东西(那些源码中的各种displayGUI纯粹是坑爹- -),全部都得靠modloader或者forge提供的调用函数才能打开。。。如果事先没有仔细研究教程,中间漏了哪步都不行。不废话了,直接开始吧。
首先创建mod文件,这个教程就以制作一个修复台为目标吧。
mod文件就叫做mod_RepairTable.java吧。现在先解释一下要显示右键方块的gui需要什么东西,需要Block,Container,Gui,TileEntity,他们的职责分别是:提供方块的基本操作,GUI的内容管理,GUI的绘制,方块的数据管理。
先来做Block,Block需要继承BlockContainer,BlockContainer需要返回对应的TileEntity,Block命名为rtBlockRepairTable(谨遵szszss触的教诲,开头写上mod的缩写可以大大的减少寻找文件的时间)经过eclipse的修正后如下:
- package net.minecraft.src;
-
- public class rtBlockRepairTable extends BlockContainer{
-
- protected rtBlockRepairTable(int par1, int par2, Material par3Material) {
- super(par1, par2, par3Material);
- // TODO Auto-generated constructor stub
- }
-
- @Override
- public TileEntity createNewTileEntity(World var1) {
- // TODO Auto-generated method stub
- return null;
- }
-
- }
目前这只是一个没有任何功能的方块。先来做TileEntity,新建一个类,名称为rtTileEntityRepairTable,继承TileEntity重写updateEntity(),updateEntity是更新TileEntity的函数,想让TileEntity工作全部都得依赖于它。在updateEntity中写上个输出语句吧。
- package net.minecraft.src;
-
- public class rtTileEntityRepairTable extends TileEntity{
-
- @Override
- public void updateEntity() {
- // TODO Auto-generated method stub
- super.updateEntity();
- System.out.println("Hello GUI");
- }
-
- }
然后给Block里的createNewTileEntity方法返回一个TileEntity,返回刚在写好的rtTileEntityRepairTable
- @Override
- public TileEntity createNewTileEntity(World var1) {
- // TODO Auto-generated method stub
- return new rtTileEntityRepairTable();
- }
这个步骤完成后还需要在mod文件中注册各种东西(因为这个是直接更换过来的,过程没有重新做,这个地方如果出现bug的话就以最终的那个为准)要引用IGuiHandler,这个接口是打开GUI的制定接口,根据接口所需的函数就能打开GUI
- package net.minecraft.src;
- import cpw.mods.fml.common.Mod;
- import cpw.mods.fml.common.event.FMLInitializationEvent;
- import cpw.mods.fml.common.network.IGuiHandler;
- import cpw.mods.fml.common.network.NetworkMod;
- import cpw.mods.fml.common.network.NetworkRegistry;
- import cpw.mods.fml.common.registry.GameRegistry;
- import cpw.mods.fml.common.registry.LanguageRegistry;
- @Mod(modid = "RepairTable", name = "Repair Table", version="1.0.0")
- @NetworkMod(channels = { "RepairTable" }, versionBounds = "1.4.5", clientSideRequired = true, serverSideRequired = false)
- public class mod_RepairTable implements IGuiHandler{
- public Block repairTable;
- @Mod.Instance("RepairTable")
- public static mod_RepairTable instance;
-
- @Mod.Init
- public void load(FMLInitializationEvent evt) {
- // TODO Auto-generated method stub
- repairTable = new rtBlockRepairTable(187, Block.brick.blockIndexInTexture, Material.rock)
- .setBlockName("RepairTable").setCreativeTab(CreativeTabs.tabBlock);
- GameRegistry.registerBlock(repairTable);
- LanguageRegistry.addName(repairTable, "RepairTable");
- GameRegistry.registerTileEntity(rtTileEntityRepairTable.class, "TileEntityRepairTable");
- instance = this;
- }
- @Override
- public Object getClientGuiElement(int ID, EntityPlayer player, World world,
- int x, int y, int z) {
- // TODO Auto-generated method stub
- return null;
- }
- @Override
- public Object getServerGuiElement(int ID, EntityPlayer player, World world,
- int x, int y, int z) {
- // TODO Auto-generated method stub
- return null;
- }
-
- }
我暂时先用砖块的贴图来代替吧- -

放置方块后你会看见调试窗里出现了刚才写的输出语句。

updateEntity会在每个tick里调用一次,每调用一次就相当于刷新一次数据,至于刷新什么数据,这些都是由你自己定的了,一般就是燃烧时间之类的。基本的功能方块就构成了。不过这个方块还没有窗口,只具备了基本的刷新数据的功能,接下来就该做GUI了。
新建一个类,名字为rtGuiRepairTable,继承GuiContainer,eclipse修正一下。
- package net.minecraft.src;
-
- public class rtGuiRepairTable extends GuiContainer{
-
- public rtGuiRepairTable(Container par1Container) {
- super(par1Container);
- // TODO Auto-generated constructor stub
- }
-
- @Override
- protected void drawGuiContainerBackgroundLayer(float var1, int var2,
- int var3) {
- // TODO Auto-generated method stub
-
- }
-
- }
- package net.minecraft.src;
-
- public class rtContainerRepairTable extends Container{
-
- @Override
- public boolean canInteractWith(EntityPlayer var1) {
- // TODO Auto-generated method stub
- return true;
- }
-
- }
在gui中覆写drawGuiContainerForegroundLayer(描绘前景文字),以及在drawGuiContainerBackgroundLayer中描绘背景,最后修改一下构造函数:
- package net.minecraft.src;
-
- import org.lwjgl.opengl.GL11;
-
- public class rtGuiRepairTable extends GuiContainer{
-
- private rtTileEntityRepairTable tile;
- public rtGuiRepairTable(rtContainerRepairTable par1Container, rtTileEntityRepairTable tileEntity) {
- super(par1Container);
- // TODO Auto-generated constructor stub
- this.tile = tileEntity;
- this.doesGuiPauseGame();
- }
-
- @Override
附上描绘用的GUI窗口

doesGuiPauseGame是是否在打开gui的时候停止游戏。构造函数那里需要返回一个Container。为啥要返回我也不清楚- -我觉得在某些方面有些多余。
接下来就是接口部分了(这个地方很多得重新做啊。。。)
在mod文件中注册IGuiHandler,注册后就能在回调函数getClientGuiElement和getServerGuiElement分别获得Gui和Container,至于这两个函数怎么用,待会解释。
- NetworkRegistry.instance().registerGuiHandler(this, this);
- @Override
- public Object getClientGuiElement(int ID, EntityPlayer player, World world,
- int x, int y, int z) {
- // TODO Auto-generated method stub
- switch(ID)
- {
- case 10:
- return new rtGuiRepairTable(player.inventory, (rtTileEntityRepairTable)player.worldObj.getBlockTileEntity(x, y, z));
- }
- return null;
- }
- @Override
- public Object getServerGuiElement(int ID, EntityPlayer player, World world,
- int x, int y, int z) {
- // TODO Auto-generated method stub
- switch(ID)
- {
- case 10:
- return new rtContainerRepairTable(player.inventory, (rtTileEntityRepairTable)player.worldObj.getBlockTileEntity(x, y, z));
- }
- return null;
- }
- @Override
- public boolean onBlockActivated(World par1World, int par2, int par3,
- int par4, EntityPlayer par5EntityPlayer, int par6, float par7,
- float par8, float par9) {
- // TODO Auto-generated method stub
- par5EntityPlayer.openGui(mod_RepairTable.instance, 10, par1World, par2, par3, par4);
- return true;
- }

完成这个步骤后得到的代码:
mod_RepairTable.java
rtBlockRepairTable.java
rtGuiRepairTable.java
rtContainerRepairTable.java
rtTileEntityRepairTable.java
貌似有些地方跳过了- -跟着工程的代码凑合一下吧(我觉得我真心不适合教书- -)。。。第一篇就先做到这里,后面还有很多东西要说。。。
预定的内容:自定义TileEntity的行为
进度条的描绘
数据的同步
一些注意事项
或者还有些什么突然想起的东西- -
不会MOD的路过围观

速度拿下SF
强大啊1.4已出

前排支持{:10_512:} GUI和Entity 都是蛋疼的东西。。。
好屌,我要看看