您尚未登录,请登录后浏览更多内容! 登录 | 加入最MC

QQ登录

只需一步,快速开始

 找回密码
 加入最MC

QQ登录

只需一步,快速开始

查看: 7294|回复: 2
打印 上一主题 下一主题

[其他] [码农世界专题]利用Forge API开发MOD第二期

[复制链接]
  • TA的每日心情
    开心
    2016-7-1 20:14
  • 签到天数: 282 天

    [LV.8]以坛为家I

    跳转到指定楼层
    楼主
    发表于 2014-7-26 10:01:07 | 只看该作者 |0人打赏回帖奖励 |倒序浏览 |阅读模式
    本帖最后由 笔记本 于 2014-9-27 16:14 编辑

    原帖:http://www.hakugyokurou.net/wordpress/?p=134


    我决定以一个开发实例作为教程,我们要使用Forge来创建一个叫做Diracon的mod,它将具有如下功能.
    (1)一个新的矿物(砖块):Diracium
    (2)一个新的矿锭(物品):Diracium Ingot
    (3)一个新的物品:Dirac Wand
    (4)一种新的Mob:Dirac Pig
    (5)添加新的功能,使Dirac Wand具有瞬间转移箱子内的物品的能力
    (6)修改地形生成器,使新矿物可以生成
    (7)一个以土块为燃料的新炉子Unthinkable Furnace
    (8)支持多人游戏!

    这8个功能基本涵盖了基础mod开发的全部,我计划分为三个部分,(1)(2)(3)作为第一部分,(4)(5)作为第二部分,(6)(7)和mod的编译发布作为第三部分.而(8)会作为贯穿全篇的一个目标,自始至终都在进行.

    这里说明一下本教程中不同颜色的字体所代表的含义.
    蓝色:一个章节
    红色:知识点,相当于一个章节所讲内容的概括
    灰色:原理,想深入学习MCP和Forge的人可以读读,普通MODer可以无视了.

    再统一一下今后教程中将使用的术语.

    从上往下看.
    红1:这个类所处的包(Package).
    蓝1:导入的包.
    绿1:类,类的概念我实在难以解释,熟悉Java的人应该都知道吧…
    紫1:继承,派生.正规的说法是一个基类派生出子类,子类继承自基类.然后我们并不在乎这上面的文字游戏,汉语本来就是个不规范的语言呢…我们说子类从基类派生而来,或子类继承自基类不也一样吗…所以本文不会太注重派生/继承的用词.但我保证会留下足够的逻辑线索让你一眼看出我所表达的意思.
    青1:基于XXX接口创建类.
    红2:类的空位,即方法与方法间的空位,如果我说”在XX类中添加这些代码”就是指在这些位置添加代码.
    蓝2:构造函数.如果一个方法的名字和类相同,那么它就是构造函数.它会在类实例化时执行.
    绿2:方法/函数,我习惯叫它方法.这个是最准确最规范的叫法.
    紫2:返回值.
    青2:参数.

    最后再向新手程序员解释一下何为重写,重写(Override)是让子类的方法覆盖父类的方法,重写的办法是让子类方法的名字和父类方法一致.唯一特例是构造函数,它的名字依然和子类名字保持一致,但必须调用父类的构造函数(使用super).

    创建一个Package(包)
    过去我们直接将代码放在net.minecraft.src这个package内,但在Forge中这并不推荐,我们最好新建自己的Package.这样方便管理代码.
    Package的命名很随意,Forge建议的命名规范是”作者名.mod名”,Java建议的Package命名规范是Package的制作公司的网站的域名的倒写,例如”com.sun”,”com.google”等…
    比如:
    fanhua.minelogin
    net.mcbbs.multicraft
    net.areazero.tohoskyarena
    总之不必在这个的命名上费太多脑筋.
    首先你要为服务器端与客户端的公用代码创建一个package,右键项目中的minecraft,选择New->Package


    然后输入Package的名字.

    创建完毕后,这个Package今后将用于放置你的代码.

    创建一个Mod主类
    Mod主类是负责进行Mod的初始化,并且可以被Forge所识别的一个类(Class).
    关于Mod主类的命名,在ModLoader时代,它的名字必须以”mod_”开头,但在Forge中它叫什么都可以.所以我将其命名为Diracon.
    在你的package中创建一个类.(右键你的package,选择New->Class)

    点击Finish开始创建,创建完后我们便有了一个空荡荡的文件,我们要让它能被Forge找到,方法是为类添加一段Annotation

    什么是Annotation?
    Annotation是Java的一种增强型注释,它和普通注释(双斜杠)的区别是,普通注释在编译阶段就会被删除,而Annotation会保留下,Annotation能储存数据,能在程序运行阶段通过某些方法(如反射)被读取.

    在public class Diracon的上一行添加:
    1. @Mod(modid="diracon", name="Diracon", version="1.0.0")
    2. @NetworkMod(clientSideRequired=true, serverSideRequired=false)
    复制代码
    知识点:@Mod与@NetworkMod
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
    (modid是MOD的名字,name是MOD在游戏里面的名字,Version是MOD的版本,可自行修改)
    @Mod必须标注在类的上方,它的含义是告诉Forge”这是一个Mod主类”.
    @NetworkMod必须标注在类的上方,它的含义是告诉Forge”这个Mod对客户端和服务器端来说是否是必备的”.
    它有多个参数值,其中必备的,也是最常用的,是2个布尔值类型参数,clientSideRequired代表此Mod在客户端是否必备,true为必备,serverSideRequired代表服务器端是否必备.
    根据排列组合,可以有这4种情况
    CSR=false SSR=false
    对哪一方而言装不装都无所谓
    情况:客户端安装 服务器端安装-正常进入
    客户端安装 服务器端未安装-正常进入
    客户端未安装 服务器端安装-正常进入
    适用:图像/声音效果增强Mod,GUI Mod,总之是一切不影响游戏实际数据的Mod.
    CSR=true SSR=false
    客户端必须安装
    情况:客户端安装 服务器端安装-正常进入
    客户端安装 服务器端未安装-正常进入
    客户端未安装 服务器端安装-链接拒绝,缺失Mod
    适用:增加新物品,新砖块,新怪物等,或者是对游戏进行了数据修改但未涉及Minecraft固有文件(即只使用API编程,不改原本的代码)的Mod.
    CSR=false SSR=true
    服务器端”应当”安装
    情况:客户端安装 服务器端安装-正常进入
    客户端安装 服务器端未安装-尚未确定的情况,Forge制作组仍在讨论如何处理这种情况,目前的措施是单纯地给出一个警示信息,但不会中断连接
    客户端未安装 服务器端安装-正常进入
    适用:服务器服务Mod,装了能提供更好的服务,没装也不影响游戏.
    CSR=true SSR=true
    客户端必须安装,服务器端”应当”安装
    情况:客户端安装 服务器端安装-正常进入
    客户端安装 服务器端未安装-尚未确定的情况,Forge制作组仍在讨论如何处理这种情况,目前的措施是单纯地给出一个警示信息,但不会中断连接
    客户端未安装 服务器端安装-链接拒绝,缺失Mod
    适用:高度修改的Mod,对Minecraft内核进行了修改,双方不同时具备此Mod将导致数据不同步发生严重错误的Mod.由此看来,Forge对服务器端Mod缺失的处理不够强硬.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
    file:///c:/users/ADMINI~1.MIN/appdata/roaming/360se6/USERDA~1/Temp/B5.jpg  

    之后静等两秒,你的Eclipse就开始报错了…因为你没有导入相关的package,将鼠标移到红波浪线上,等提示框出来后选择”Import …”来自动导入相关package.

    此时你的mod大概是这样子.

    之后我们要添加用于初始化Mod的方法(Method,不理解的自行补Java…)在ModLoader时代,我们通过重写(Override)基类的方法来实现,现在没有基类了,所以我们使用Annotation来实现.


    在你的类中添加这些代码.
    1. @EventHandler
    2. public void preLoad(FMLPreInitializationEvent event)
    3. {
    4. }

    5. @EventHandler
    6. public void load(FMLInitializationEvent event)
    7. {
    8. }

    9. @EventHandler
    10. public void postLoad(FMLPostInitializationEvent event)
    11. {
    12. }
    复制代码

    知识点:@EventHandler与历史的伤痕
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
    看上去这个标题很严肃…事实上是我为了搞笑故意起的…
    如果你是个老Modder(MC1.6版以前就开始做Mod)那么你应该记得那时Forge没有@EventHandler这个注解,取而代之的是@Init,@PreInit和@PostInit这三个分工详细的注解.
    在最初的ModLoader时代,所有的Mod主类都通过重写load方法来实现初始化,到了ForgeModLoader后,Forge(最初)通过带有@Init的方法来实现初始化,同时它还提供了@PreInit(初始化前)和@PostInit(初始化后)两个方法来为初始化扫清障碍或收尾.
    然而现在FML使用@EventHandler来泛指所有参与Mod初始化工作的方法,区分这些方法的唯一方式是它们的参数,根据他们的参数的类型,FML会利用事件系统在不同的时段调用他们.

    FMLPreInitializationEvent 预初始化
    CPW建议开发者在预初始化时进行读取配置,创建物品砖块,以及注册相关信息等操作,另外你还能在这时候获得FML给你传来的配置文件.(Configuration,但是我并不太愿意在基础篇讲这个东西…)
    其实老Modder都知道,在初始化的任何一个阶段都是可以创建砖块的…不必非在与初始化阶段创建.
    FMLInitializationEvent 初始化
    配置Mod设置,添加合成表…另外CPW建议Mod间通讯(通过FMLInterModComms类完成)应当在此时进行.
    FMLPostInitializationEvent 初始化后
    CPW认为初始化后是供Mod间相互交互的时候,此时该载入的Mod都已经载入了,因此开发者们可以在此时为实现Mod间联动的操作做准备.顺便一提,FMLPostInitializationEvent事件的buildSoftDependProxy方法可以获取一个类的实例,它会先判断你要求的mod是否存在,如果存在则返还给你你要求的类的实例.
    IMCEvent 接收Mod间通讯
    这个事件会排在FMLInitializationEvent之后,它会附带一个保存着其他Mod发来的信息的列表.

    此外,还有几个服务器事件,但这个就不在基础篇的范围内了…(其实是我急着去玩Civ5懒得继续码字了)以后我会单开一个篇幅讲.
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////

    然后导入相关的包,你的第一个Mod就已经能运行了…保存,在MCP目录中找到recompile.bat,运行它,静等编译完毕.然后运行startclient.bar开启单人客户端测试.



    于是就是这样…你的第一个Mod已经能被载入了,虽然它还什么都没有,但千里之行始于足下,你已经走出了第一步,不是吗?
    再次为自己撒花吧(\撒花/)
    打赏

    0

    收藏

    0

    支持

    0

    反对

    0

    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
  • TA的每日心情
    难过
    2018-1-13 21:09
  • 签到天数: 489 天

    [LV.9]以坛为家II

    沙发
    发表于 2015-3-29 21:54:08 | 只看该作者
    图片全挂
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
  • TA的每日心情
    开心
    2017-8-8 13:40
  • 签到天数: 19 天

    [LV.4]偶尔看看III

    板凳
    发表于 2015-6-27 06:03:26 来自手机 | 只看该作者
    图片挂了
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    您需要登录后才可以回帖 登录 | 加入最MC

    本版积分规则