Minecraft(我的世界)中文论坛

 找回密码
 注册(register)

!header_login!

只需一步,立刻登录

查看: 9402|回复: 20

[Mod开发讨论] 利用Forge API开发联机MOD【基础篇】【第三章】

[复制链接]
yuxuanchiadm 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
6160
钻石
性别
保密
注册时间
2011-8-6
查看详细资料
发表于 2012-7-31 21:53:14 | 显示全部楼层 |阅读模式

您尚未登录,立即登录享受更好的浏览体验!

您需要 登录 才可以下载或查看,没有帐号?注册(register)

x
本帖最后由 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类里自己玩玩你的配置文件管理类。

评分

参与人数 3人气 +8 金粒 +28 收起 理由
路邊電燈泡 + 3 + 28 很棒的作品!
outsidero + 2 20
geludan + 3 Mcbbs有你更精彩~

查看全部评分

outsidero 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
6280
钻石
性别
保密
注册时间
2010-10-30
查看详细资料
发表于 2012-7-31 21:57:47 | 显示全部楼层
前排支持!!
回复

使用道具 举报

1212012 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
1197
钻石
性别
保密
注册时间
2011-8-18
查看详细资料
发表于 2012-7-31 22:21:29 | 显示全部楼层
不错但是我压根看不懂
回复

使用道具 举报

a919298641 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
7420
钻石
性别
保密
注册时间
2011-6-18
查看详细资料
发表于 2012-7-31 23:48:37 | 显示全部楼层
整合包呢。。。。
回复

使用道具 举报

a919298641 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
7420
钻石
性别
保密
注册时间
2011-6-18
查看详细资料
发表于 2012-8-1 00:00:50 | 显示全部楼层
好吧。。。。我想要的是整合包。。。
回复

使用道具 举报

strawmaine 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
14451
钻石
性别
保密
注册时间
2011-10-30
查看详细资料
发表于 2012-8-14 10:45:16 | 显示全部楼层
知识点萌动了~
回复

使用道具 举报

zheung14 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
755
钻石
性别
保密
注册时间
2012-3-10
查看详细资料
发表于 2013-3-15 19:28:23 | 显示全部楼层
return myFirstModConfig.instance.config.get("general", PropertyName, DefaultValue).value;


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

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

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

但是我不肯定,这样做对不对...不知道大大是否有时间帮我确认一下呢?
回复

使用道具 举报

yuxuanchiadm 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
6160
钻石
性别
保密
注册时间
2011-8-6
查看详细资料
 楼主| 发表于 2013-3-15 23:53:31 | 显示全部楼层
本帖最后由 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 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
755
钻石
性别
保密
注册时间
2012-3-10
查看详细资料
发表于 2013-3-16 00:05:20 | 显示全部楼层
yuxuanchiadm 发表于 2013-3-15 23:53
确实改成私有的了,Forge提供了getString方法来直接获取value的值,使用
return myFirstModConfig.insta ...

感谢万分~~
回复

使用道具 举报

qq1693129601 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
52
钻石
性别
保密
注册时间
2011-12-22
查看详细资料
发表于 2013-3-22 14:24:18 | 显示全部楼层
42行value是私有的啊
回复

使用道具 举报

yuxuanchiadm 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
6160
钻石
性别
保密
注册时间
2011-8-6
查看详细资料
 楼主| 发表于 2013-3-22 15:29:51 | 显示全部楼层
qq1693129601 发表于 2013-3-22 14:24
42行value是私有的啊

谁叫你用新版本的?
新版本Forge用getString()
回复

使用道具 举报

kuafuzhuguang 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
106
钻石
性别
保密
注册时间
2012-3-17
查看详细资料
发表于 2013-8-4 18:26:43 | 显示全部楼层
签名,先顶后看
回复

使用道具 举报

mkonhy 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
658
钻石
性别
保密
注册时间
2012-9-30
查看详细资料
发表于 2013-8-10 23:07:28 | 显示全部楼层
这一章看上去觉得不明不白的……头都晕了……
回复

使用道具 举报

TheTd 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
1614
钻石
性别
保密
注册时间
2012-12-19
查看详细资料
发表于 2013-8-11 02:31:37 | 显示全部楼层
java的习惯好像是'{'在定义方法的时候就加在哪一行后面,不是换一行再写'{' ,所以楼主一定不是专攻java的:)
回复

使用道具 举报

yuxuanchiadm 当前离线
帖子
主题
精华
贡献
最后登录
1970-1-1
爱心
积分
6160
钻石
性别
保密
注册时间
2011-8-6
查看详细资料
 楼主| 发表于 2013-8-11 05:20:55 | 显示全部楼层
TheTd 发表于 2013-8-11 02:31
java的习惯好像是'{'在定义方法的时候就加在哪一行后面,不是换一行再写'{' ,所以楼主一定不是专攻java的: ...

你在酒吧(贴吧、网吧、K吧)当着一大堆程序猿说这事,回答肯定不止一个,估计喷人的答案居多。
java的习惯好像是不用换行,不用空格,不用缩进,所以14楼一定不是专攻java的:)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册(register)

本版积分规则

Archiver|小黑屋|Mcbbs.net ( 京ICP备15023768号-1 ) | 京公网安备 11010502037624号 | 手机版

GMT+8, 2020-1-24 13:24 , Processed in 0.046770 second(s), Total 24, Slave 22 queries, Release: Build.2020.01.19.1840, Gzip On, MemCached On.

"Minecraft"以及"我的世界"为Mojang Synergies AB的商标 本站与Mojang以及微软公司没有从属关系

© 2010-2020 我的世界中文论坛 版权所有 本站原创图文内容版权属于原创作者,未经许可不得转载

快速回复 返回顶部 返回列表