基础篇小结:来看源码吧~巩固之前的知识,顺便看看创建方块物品之类基本操作的具体做法

经过了前5章的学习,你现在已经可以开始着手制作自己的mod了(所以快加入我的斗罗大坑呸大陆计划中来啊)

但那些毕竟大都是理论上的东西,可能还有些童鞋不太清楚一个具体的mod长啥样,现在咱就来看看:

首先是工程结构树状图:



嘿嘿,我估计直接就有孩子激动了:楼主,尼玛终于肯上真正的图了~~~

是的,毕竟这一节就是为了直观嘛。不过童鞋,不是我对自己的语文功底自信,而是你确实需要学会读文,图虽直观方便,但毕竟不如文字准确。我并不想写一个教小学生一步一步跟着走的教程,我要写的是能让你理解Forge,掌握mod制作的方法并能真正加入到mod制作中来,加入我的斗罗大坑计划的文档!

好,废话不多说,图中圈起来的地方是重点,第一个圈圈住了src,源码的意思,是我们制作mod时主要操作的部分。第二个圈,圈住了src/main下的两个文件夹,java是放Java代码的,resources是存放资源的。所以你要记住,如果我说的是Java源码,那么你就应该去java里面找,当然实际上是java/com.zhengxiaoyao0716.douromod/下面,如果是贴图、模型等资源,就在resources下面找,实际上除了mcmod.info,都在assets.douromod/下面。


对照之前的内容,你会明白,@Mod标识了DouroMod这个class是一个mod的主类。


Proxy还记得不?代理器。下面三个方法preInit();、init();、postInit();是我注册到Forge执行流程中的三个方法,方法名你随便,但参数是关键,三个参数对应了会在游戏开始时被Forge依次执行的三个事件,要用@EventHandlew注册它们,你可以Ctrl + clickL,看看Forge源码中对你应该在哪个事件中做什么事的建议。当然还有别的一些事件,你可以去源码里自己翻翻。三个方法里面,在proxy对象上调用了CommonProxy或ClientProxy的方法,具体是调用到了哪个由运行的端决定。proxy的方法名就更不重要了,你随便起随便用,我这样无非是偷懒。唯一需要注意的就是ClientProxy必须继承CommonProxy,有Java基础的都明白为什么吧。


我记得我没教过大家怎么创建Block、Item,但其实只要你明白了我之前那几篇文章,并且有Java基础,这简直so easy。创建一个Block就是创建一个Block类的实例,然后你在这个实例上set上你的数据就ok,Item同理。对了,把实例作为主类的一个公开域来写,主要是方便各处的调用。


呐,我是建了一个继承自Block的类,用这个类来初始化我的ironEssenceOre实例,在构造器里面完成对这个实例的数据的设定。其实单这么看,意义不大,你完全可以在直接实例化Block赋给你的ironEssenceOre。但这样是有好处的,其一是避免了主类的冗长,其二是方便重写Block类的一些方法。创建简单的Block固然可以直接通过设定实例的数据实现,但一些复杂的功能是需要重写父类的方法的。最后简单描述一下图中几个方法及参数的意义吧,其实你完全可以自己去查源代码来看,一定要记住,Forge的文档非常少,你很难找到一份完美的介绍清楚每一个方法与参数的javadoc,所以多自己去揣摩。

  • 图中super了父类的构造器,传入的参数是石头的材质。你可以Ctrl+鼠标左键,看看Material里面都有哪些预设的材质,你也可以自己定义。至于材质是什么,抱歉,MC里没有很准确的定义,它类似于模型,但涵盖了很多属性,我只能告诉你,空气air与岩石rock肯定是不同的材质,雪ice和火fire肯定也是不同的对吧。具体有什么区别呢?Ctrl+clickL,自己看看源码怎么写就明白了。

  • setUnlocalizedName();,这个方法我前文已经提到过了,字面意思上看,它为这个实例设定了未本地化的名字。什么叫未本地化呢?就是说,这个名字实在语言文件中条目缺失的情况下默认显示的。语言文件就是放在assets/douromod/lang/下面的en_US.lang、zh_CN.lang等等配置文件,前者是默认的英文,后者是中文。其内容类似这样:

    tile.ironEssenceOre.name=铁母矿
    
    item.ironEssence.name=铁母
    item.sleeveBow.name=袖箭

    注意=两边不要有多余的空格,这是配置文件,不是Java。UnlocalizedName实际上会被加上前后缀构成一个新的字符串键,游戏中根据这个键在lang寻找要显示的名字的字符串值。

  • setHardness();是设置挖掘的硬度,经过我的测试,3.0f大概相当于铁矿。这里建议你看看源码,会发现它和blockResistance,抗炸能力是有约束关系的,所以我没有再setResistance();,如果你要设置方块的抗炸能力也请注意这个问题。由此也可见看源码的重要。setHarvestLevel();是设置开采要求的等级,第一个参数是可被开采的工具的类型名字,这里设定为pickaxe(镐),第二个参数是工具的质地等级,具体请Ctrl+clickL。

这就是为什么我不喜欢讲怎么创建方块之类的,明明很简单的事情却要用很大的篇章才能讲清。基本上除了语言文件这点,其它的会Java就能自己搞定。继续向下:


这是CommonProxy的内容,我前面说过,它负责服务端。只看我标红线的行,其它的不在本次讨论范围内。

  • 第一行,调用了刚刚的IronEssenceOre类的构造器,来实例化主类的ironEssenceOre实例。

  • 第二行,注册了这个方块,注册方法原形public static Block registerBlock(Block block, String name);,第二个参数虽然名为name,但你实际要填写的应该是modId:blockId,这个name实际是方块的id,方块在游戏中真正显示的名字是由setUnlocalizedName();指定的。别忘了在方块id前的"modid:"否则别人证明知道这个方块属于你的mod呢。

  • 第三行,可以看到在注册了方块后,我们有给它添加了一个Smelting冶炼,并且,添加冶炼方法写在了init();里,它是在preInit();之后调用的。第一个参数是要冶炼的方块,第二个是一个ItemStack(物品栈)实例,用要生成的方块/物品作为参数创建它。为什么这么做呢?因为你冶炼完成实际得到的并不是一个物体,而是物品栏里的一个它的ItemStack对象。最后一个参数是玩家所应得的经验,这个值在原版MC设定的冶炼中大都非常小,烧一块金子大概是1.0f。

  • 第四行是为一个注册过的物品添加了一份合成表。简单物品的创建与Block差不多,当然物品没有材质,也就不需要super父类,物品也没有开采硬度之类的,总之你在实例后面打个点看看不就知道有哪些没哪些了。物品在语言文件lang中的键是item.[你在setUnlocalizedName();里设定的名字].name。添加合成表也很简单,第一个参数是玩家应该获得的物品,与冶炼产物一样都实际上是这个物品的ItemStack,第二个参数有点奇葩,Object[],基础对象数组。这个数组的写法规则是这样的:先放1~3个字符串,每个字符串1~3个字符,比如"aaa", " b ", " b ",注意后面连个字符串中的b前后有空格。然后,一个字符一个物品的放几组,字符要对应前面的字符串内的,比如'a', Items.xxx, 'b', Item.yyy,注意是字符,单引号。这是什么意思呢?原来,MC会把前面那些字符串里的字符,依次替换成后面的字符后紧跟的物品。也就是说,其实就是用字符代表物品,摆出你设计的合成表,再在后面说明一下,a是什么,b是什么。


这是ClientProxy里面的init方法片段。可以看到,在这里面完成了物品、方块的注册及模型的添加(准确的说是设定,之前讨论过这个add实际上做的是set)。具体请参照前文,这里没啥可说的。

最后,再上一张main文件夹下面的Java、resources展开的结构图,你可以对照前文找找哪些文件都应该在哪儿

是的,还有我的Github:https://github.com/zhengxiaoyao0716/DouroMod

posted @ 2015-10-29 21:41  正逍遥0716  阅读(295)  评论(1编辑  收藏  举报