Minecraft(我的世界)中文论坛

标题: 利用Forge API开发联机MOD【基础篇】【第三章】

作者: yuxuanchiadm    时间: 2012-7-31 21:53
标题: 利用Forge API开发联机MOD【基础篇】【第三章】
本帖最后由 yuxuanchiadm 于 2013-2-13 04:54 编辑

利用Forge API开发联机MOD【基础篇】【第三章】
建立你的配置文件类
作者:yuxuanchiadm

索引贴地址:http://www.mcbbs.net/thread-38211-1-1.html

请确定你已经阅读完成第二章的内容:
http://www.mcbbs.net/thread-38283-1-1.html
否则不要阅读此贴!

序:
在上一章里,我们已经学会了制作一个简单的MOD,并且制作出了一个。然而,很多MOD都有一个完整的配置文件,而我们的MOD没有:(,不要沮丧,现在我将要教你制作一个配置文件管理类,虽然现在没有什么用,但是以后用得到!

为你的MOD制作一个配置文件管理类:
/**知识点:什么是类和对象
类是OOP编程(面向对象的编程)中的重要元素,什么,你不知道神马是类?好吧,你居然有耐心看到这里,请容我一拜(楼主扯蛋中),如果把类比作蓝图,对象比作汽车,那么类和对象的关系就如同蓝图和汽车一样。一个蓝图可以制作出很多汽车,蓝图的样子决定了汽车的样子,然而汽车也可以换挡,添加装饰品,所以对象不一定要一样,但是一定要有蓝图的样子,否则这就是一个失败品。

**/

首先在myFirstMod包下建立一个新类:myFirstModConfig。这个配置文件管理类我们要实现单实例的功能,也就是只能存在一个myFirstModConfig类的实例,否则多个实例对一个文件进行操作,就可能出现问题。
/**知识点:什么是单实例模式
单实例模式时面向对象编程中一个重要的元素,一般用于需要对一个文件或其他内容操作的场景。顾名思义,单实例模式下的类只能有一个实例,这样就提高了应用程序的安全性。日后在扩展这个程序时,也不容易在此处发生错误。单实例模式的实现,一般是在类的内部创建一个指向这个类本身的某个实例的静态变量,并且让构造函数在外部不可见(Private),然后创建一个静态初始化函数,在运行中第一次使用这个类时对其内部的那个静态变量和其他内容进行初始化。
**/

注意:导入类啥的自行导入就行了,以后就不提醒了。
首先,创建一个私有静态变量,类型为myFirstModConfig,也就是储存这个类的唯一实例的变量。

  1. private static myFirstModConfig instance;
复制代码

然后创建一个私有成员变量,类型为Configuration(Forge提供的基本配置文件管理类)
  1. private Configuration config;
复制代码

然后,添加这个类的私有构造函数,参数列表需要一个File类型的参数,此参数期望传入一个以此MOD配置文件为路径的File对象。

  1. private myFirstModConfig(File configFile)
  2. {
  3.     if(!configFile.exists())
  4.     {
  5.         try
  6.         {
  7.             configFile.createNewFile();
  8.         }
  9.         catch(IOException e)
  10.         {
  11.             System.out.println(e);
  12.             return;
  13.         }
  14.     }
  15.     config = new Configuration(configFile);
  16.     config.load();
  17. }
复制代码

/**知识点:什么是构造函数
构造函数是OOP编程(面向对象的编程)中的重要元素,假设你要把汽车蓝图变成一个实际汽车,那么你需要建造它,构造函数的作用就是建造类的对象,构造函数在类初始化时调用,构造函数调用完成时,你将得到一个完整的类的对象。
**/

然后,创建一个初始化函数,用于在需要使用这个类时初始化它。


  1. public static void InitliazeConfig(File ConfigFile)
  2. {
  3.     if(myFirstModConfig.instance != null)
  4.     {
  5.         return;
  6.     }
  7.     myFirstModConfig.instance = new myFirstModConfig(ConfigFile);
  8. }
复制代码

然后,创建三个获取方块ID、物品ID、和其他配置信息的函数:
  1. public static String GetGeneralProperties(String PropertyName, String DefaultValue) throws Exception
  2. {
  3.     if(myFirstModConfig.instance == null)
  4.     {
  5.         throw new Exception("没有初始化配置文件!");
  6.     }
  7.     return myFirstModConfig.instance.config.get("general", PropertyName, DefaultValue).value;
  8. }
  9. public static int GetItemID(String ItemName, int DefaultValue) throws Exception
  10. {
  11.     if(myFirstModConfig.instance == null)
  12.     {
  13.         throw new Exception("没有初始化配置文件!");
  14.     }
  15.     return myFirstModConfig.instance.config.getItem("item", "ID." + ItemName, DefaultValue).getInt() - 256;
  16.     //为什么要减256呢,这还得从上古时期开始说起。从前有个叫Notch的男人,开发了Minecraft。在制作物品和方块系统时,错误的将物品和方块归为同一类。但方块能使用的ID却在原版只有256,而物品则有很多。后来,Minecraft发现了这个问题,于是将物品在初始化时传入的ID统一加上了256。但治标不治本,方块ID任然只有256个。1万年后,出现了一个可以将方块范围限制提到4096的MOD,万恶(弥天大雾)的Forge迅速将其吸入Forge本身。于是方块和物品的ID又开始冲突了。但物品在初始化时还是只加上256,因为很多物品都使用了4096以下的ID,所以必须将其移到其他范围。但由于目前很多的神作地图等精美的艺术作品都使用的是现在的ID,一旦更改,这些存档(全银河系的Minecraft存档)将报废。最后,就出现了现在的坑爹局面。所以,最好还是在此地减去256,抵消这个副作用,干脆就使用可能会导致冲突的ID范围,也总比卡在半中拦腰强。
  17. }
  18. public static int GetBlockID(String BlockName, int DefaultID) throws Exception
  19. {
  20.     if(myFirstModConfig.instance == null)
  21.     {
  22.         throw new Exception("没有初始化配置文件!");
  23.     }
  24.     return myFirstModConfig.instance.config.getBlock("ID." + BlockName, DefaultID).getInt();
  25. }
复制代码
最后,创建一个储存配置文件的函数:

  1. public static void SaveConfig()
  2. {
  3.     myFirstModConfig.instance.config.save();
  4. }
复制代码

这时,你的代码应该是这样:

  1. package myFirstMod;import net.minecraftforge.common.Configuration;
  2. import java.io.File;
  3. import java.io.IOException;public class myFirstModConfig
  4. {
  5.     private static myFirstModConfig instance;
  6.     private Configuration config;
  7.     public static void InitliazeConfig(File ConfigFile)
  8.     {
  9.         if(myFirstModConfig.instance != null)
  10.         {
  11.             return;
  12.         }
  13.         myFirstModConfig.instance = new myFirstModConfig(ConfigFile);
  14.     }
  15.     private myFirstModConfig(File configFile)
  16.     {
  17.         if(!configFile.exists())
  18.         {
  19.             try
  20.             {
  21.                 configFile.createNewFile();
  22.             }
  23.             catch(IOException e)
  24.             {
  25.                 System.out.println(e);
  26.                 return;
  27.             }
  28.         }
  29.         config = new Configuration(configFile);
  30.         config.load();
  31.     }
  32.     public static void SaveConfig()
  33.     {
  34.         myFirstModConfig.instance.config.save();
  35.     }
  36.     public static String GetGeneralProperties(String PropertyName, String DefaultValue) throws Exception
  37.     {
  38.         if(myFirstModConfig.instance == null)
  39.         {
  40.             throw new Exception("没有初始化配置文件!");
  41.         }
  42.         return myFirstModConfig.instance.config.get("general", PropertyName, DefaultValue).value;
  43.     }
  44.     public static int GetItemID(String ItemName, int DefaultValue) throws Exception
  45.     {
  46.         if(myFirstModConfig.instance == null)
  47.         {
  48.             throw new Exception("没有初始化配置文件!");
  49.         }
  50.         return myFirstModConfig.instance.config.getItem("item", "ID." + ItemName, DefaultValue).getInt();
  51.     }
  52.     public static int GetBlockID(String BlockName, int DefaultID) throws Exception
  53.     {
  54.         if(myFirstModConfig.instance == null)
  55.         {
  56.             throw new Exception("没有初始化配置文件!");
  57.         }
  58.         return myFirstModConfig.instance.config.getBlock("ID." + BlockName, DefaultID).getInt();
  59.     }
  60. }
复制代码

总结:
你已经制作出了一个配置文件管理类,为自己干上一杯吧:),虽然现在没什么用,但是你已经迈出了制作更高级MOD的第一步!如果你有较好的JAVA基础,你可以在mod_myFirstMod类里自己玩玩你的配置文件管理类。

作者: outsidero    时间: 2012-7-31 21:57
前排支持!!
作者: 1212012    时间: 2012-7-31 22:21
不错但是我压根看不懂
作者: a919298641    时间: 2012-7-31 23:48
整合包呢。。。。
作者: a919298641    时间: 2012-8-1 00:00
好吧。。。。我想要的是整合包。。。
作者: strawmaine    时间: 2012-8-14 10:45
知识点萌动了~
作者: zheung14    时间: 2013-3-15 19:28
return myFirstModConfig.instance.config.get("general", PropertyName, DefaultValue).value;


最后的.value报错,找不到该函数成员

~很可能是我用了新版Forge(1.5的7.7)造成的...

于是我对比查了一下javadoc,好像是把value从公有变成私有了...改用getString()来获得value的值

但是我不肯定,这样做对不对...不知道大大是否有时间帮我确认一下呢?
作者: yuxuanchiadm    时间: 2013-3-15 23:53
本帖最后由 yuxuanchiadm 于 2013-3-15 23:55 编辑
zheung14 发表于 2013-3-15 19:28
return myFirstModConfig.instance.config.get("general", PropertyName, DefaultValue).value;

确实改成私有的了,Forge提供了getString方法来直接获取value的值,使用
return myFirstModConfig.instance.config.get("general", PropertyName, DefaultValue).getString();
替换。

追加:
完全可以放心这样做

作者: zheung14    时间: 2013-3-16 00:05
yuxuanchiadm 发表于 2013-3-15 23:53
确实改成私有的了,Forge提供了getString方法来直接获取value的值,使用
return myFirstModConfig.insta ...

感谢万分~~
作者: qq1693129601    时间: 2013-3-22 14:24
42行value是私有的啊
作者: yuxuanchiadm    时间: 2013-3-22 15:29
qq1693129601 发表于 2013-3-22 14:24
42行value是私有的啊

谁叫你用新版本的?
新版本Forge用getString()
作者: kuafuzhuguang    时间: 2013-8-4 18:26
签名,先顶后看
作者: mkonhy    时间: 2013-8-10 23:07
这一章看上去觉得不明不白的……头都晕了……
作者: TheTd    时间: 2013-8-11 02:31
java的习惯好像是'{'在定义方法的时候就加在哪一行后面,不是换一行再写'{' ,所以楼主一定不是专攻java的:)
作者: yuxuanchiadm    时间: 2013-8-11 05:20
TheTd 发表于 2013-8-11 02:31
java的习惯好像是'{'在定义方法的时候就加在哪一行后面,不是换一行再写'{' ,所以楼主一定不是专攻java的: ...

你在酒吧(贴吧、网吧、K吧)当着一大堆程序猿说这事,回答肯定不止一个,估计喷人的答案居多。
java的习惯好像是不用换行,不用空格,不用缩进,所以14楼一定不是专攻java的:)
作者: Precursors    时间: 2014-8-2 16:50
为什么我的eclipse显示没有为类型 Configuration 定义方法 getBlock(String, int)和没有为类型 Configuration 定义方法 getItem(String, int)
作者: SilverMing    时间: 2014-8-17 20:15
Precursors 发表于 2014-8-2 16:50
为什么我的eclipse显示没有为类型 Configuration 定义方法 getBlock(String, int)和没有为类型 Configura ...

因为Configuration.class里沒有这兩个方法
似乎是1.7.2的问题
作者: T7-xin    时间: 2016-12-17 09:39
lin212 发表于 2014-8-17 20:15
因为Configuration.class里沒有这兩个方法
似乎是1.7.2的问题

那应该改成什么呢?现在卡在这里了...
作者: yujm4623    时间: 2019-5-4 12:20
虽然感觉很不错但是看不懂耶
作者: Treason666    时间: 2019-7-12 18:46
支持一下
作者: 我是叶辉    时间: 2019-7-13 14:19
感谢楼主的分享