Minecraft(我的世界)中文论坛

标题: MCP的Mod制作教程(2) - 建立一个使用ModLoader的Mod

作者: szszss    时间: 2012-3-3 22:56
标题: MCP的Mod制作教程(2) - 建立一个使用ModLoader的Mod
本帖最后由 szszss 于 2012-4-13 20:15 编辑

MCPMod制作教程(2)
建立一个使用ModLoaderMod
作者:szszss

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


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

7个功能基本涵盖了基础mod开发的全部,我计划分为三个部分,(1)(2)(3)作为第一部分,(4)(5)作为第二部分,(6)(7)mod的编译发布作为第三部分.

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

注:本文最初基于MCP5.6和ModLoader1.1.0编写的.
MCP6.2和ModLoader1.2.4更新了大量方法的名字,导致我的教程几乎报废一半...
不管怎么说,我用了一个晚上的时间还是修正了教程的文字部分,使其和最新版的MCP与ModLoader接轨.但图片部分我实在是无力修改了...大家将就着看吧.



使用ModLoader建立一个新Mod

首先你要在net.minecraft.src包内创建一个新的类(Class,假设你已经有基本的Java知识了,如果没有请自行学习...)文件.右键net.minecraft.src,选择New - Class.
之后要设定类的名字,Java的开发规范是类的首字母大写,MCP的开发规范是首字母小写,我们采用MCP的规范,将类命名为mod_Diracon


知识点:mod主类的命名
使用ModLoadermod必须有一个叫做mod_XXX(XXXmod)的类文件,并且与ModLoader类放在同一目录

点击Finish开始创建,创建完后我们便有了一个空荡荡的文件,我们要让它与ModLoader建立链接,方法是让mod_Diracon继承BaseMod.
public class mod_Diracon后面({的前面)输入extends BaseMod

输入完之后静等2,你的Eclipse就开始报错了...因为你继承了BaseMod,但没有重写(Override)BaseMod内的两个抽象(Abstract)方法.
解决的办法是在mod_Diracon类内加入这两个方法.

  1. public String getVersion()
  2. {
  3.      return "1.0.0";
  4. }
  5. public void load()
  6. {

  7. }
复制代码

之后你的程序应该是这个样子



知识点:继承BaseMod后必要的2个重写
getVersion和load是2个抽象功能,必须被mod文件重写,getVersion是在ModLoader查询版本时反馈版本号,MCP官方推荐的格式是"主版本号.副版本号.工程版本号"(1.1.5)
loadmod在载入时会执行的方法,它具有相当于构造函数的功能.

连接官方的Javadoc
注:在MCP6.1以后,MCP会自动在本地代码上加上注释,所以这一步不重要了.你完全可以跳过这一步.
MCP6.0,MCP组提供了一套Javadoc.可以理解为对代码的注释手册.
要在Eclipse中建立同在线Javadoc的链接,首先右键项目,选择Properties,在新弹出的窗口的左侧列表中选择Javadoc Location,在文本框中输入:
http://mcp.ocean-labs.de/files/jd123/client/
之后点击Apply,然后点击OK.这样你就完成配置了.

关于本文术语的约定俗成

这个章节实际上是在我写完全部基础教程后才加上的,我在这里解释一下今后教程中将使用的术语.


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

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

下一篇:创建新的砖块,物品和冶炼
http://www.mcbbs.net/thread-18940-1-1.html


作者: szszss    时间: 2012-3-3 23:00
本帖最后由 szszss 于 2012-3-4 00:15 编辑

排版完毕....哦液湿

作者: DR.MC.ztz    时间: 2012-3-3 23:03
Mcp的MOD?求回答
作者: geludan    时间: 2012-3-4 00:06
你说我每一贴都回会不会被LZ抽死呢?
作者: 292312038    时间: 2012-3-29 11:10
lz辛苦,支持,最近想自己做MOD。
作者: 铭刻时间的墓碑    时间: 2012-4-12 22:29
java语言要学到什么状况才能做MOD

作者: szszss    时间: 2012-4-12 23:04
本帖最后由 szszss 于 2012-4-12 23:07 编辑
铭刻时间的墓碑 发表于 2012-4-12 22:29
java语言要学到什么状况才能做MOD


呃- -个人认为除了掌握最基本的语法(赋值,if分支,for/while循环,方法的调用..等等..)以外,还要理解类的概念(我以前花了很久才理解类的概念...捂脸)和使用(类的实例化,类的继承..等等..),字段或方法的访问级(这倒不是很重要,最懒的方法是让所有的访问级都是public)和参数的形参/实参(最简单的理解:实参是传递一个实实在在的数值,形参是传递一个使用权,具体的讲解在网上有...)
通常来说,掌握这些就足够了,但倘若要更深层的制作Mod,最重要的不是提高编程技巧(但编程思维一定要提高)而是...读他人代码的毅力...如果你要给MC编写Mod,那么势必需要理解它的机制,纵使是约翰卡马克,冷不丁交给他Minecraft源码并让他编写一个Mod,他也会苦于对程序机制不了解而一时抓耳挠腮,对不?我一再在教程中对2位编写教程的前辈道谢,正是因为我是以他们的教程作为对MC"源码"研究的切入点,一点一点理解MC的运行机制.好吧我说的有些太恐怖了(笑),很大程度上我努力研究MC的"源码"是因为编写教程和受人询问的压力,就像我的初中英语老师吐槽他工作后学习压力反而更大了一样(我到底扯到哪去了啊...)如果你只想当MODer的话,理解最常用最关键的几个部分就行了.
作者: yyq90    时间: 2012-6-9 10:38
本帖最后由 yyq90 于 2012-6-11 16:57 编辑

-------------
作者: zhj6690260    时间: 2012-7-17 12:37
package net.minecraft.src;

public class mod_Crystal extends BaseMod {
    public void oreCrystal(int id, int textureIndex, Material mat){
        super(id, textureIndex, mat);
        super.setHardness(2.5f);
        super.setBlockName("oreCrystal");
        super.setStepSound(soundStoneFootstep);
}
}
public class mod_Crystal extends BaseMod{
public static Block oreCrystal;
public String getVersion()
{
    return "1.0.0";
}
public void load()
{
oreCrystal= new dcOreCrystal(176, ModLoader.addOverride("/terrain.png", "/newblock.png"), Material.rock);
ModLoader.registerBlock(oreCrystal);
ModLoader.addName(oreCrystal, "Crystal Ore");
ModLoader.addRecipe(new ItemStack(oreCrystal, 1), new Object[]
                {
                         " D ",
                         "DSD",
                         " D ",
                         Character.valueOf('D'), Item.redstone,
                         Character.valueOf('S'), Item.diamond
                });
}
}

}

这样出错,然后不解释
作者: szszss    时间: 2012-7-18 01:43
zhj6690260 发表于 2012-7-17 12:37
package net.minecraft.src;

public class mod_Crystal extends BaseMod {

.....我认为你想写的其实是这个
  1. package net.minecraft.src;

  2. public class BlockCrystal extends Block {
  3.     public BlockCrystal(int id, int textureIndex, Material mat){
  4.         super(id, textureIndex, mat);
  5.         super.setHardness(2.5f);
  6.         super.setBlockName("oreCrystal");
  7.         super.setStepSound(soundStoneFootstep);
  8.     }
  9. }
复制代码
  1. package net.minecraft.src;

  2. public class mod_Crystal extends BaseMod{
  3.     public static Block oreCrystal;
  4.     public String getVersion()
  5.     {
  6.         return "1.0.0";
  7.     }
  8.     public void load()
  9.     {
  10.         oreCrystal= new BlockCrystal(176, ModLoader.addOverride("/terrain.png", "/newblock.png"), Material.rock);
  11.         ModLoader.registerBlock(oreCrystal);
  12.         ModLoader.addName(oreCrystal, "Crystal Ore");
  13.         ModLoader.addRecipe(new ItemStack(oreCrystal, 1), new Object[]
  14.                 {
  15.                          " D ",
  16.                          "DSD",
  17.                          " D ",
  18.                          Character.valueOf('D'), Item.redstone,
  19.                          Character.valueOf('S'), Item.diamond
  20.                 });
  21.     }
  22. }
复制代码

作者: zhj6690260    时间: 2012-7-18 09:14
szszss 发表于 2012-7-18 01:43
.....我认为你想写的其实是这个

好吧,不过你能不能+我的QQ?
作者: zhj6690260    时间: 2012-7-18 09:26
szszss 发表于 2012-7-18 01:43
.....我认为你想写的其实是这个

我顺便问一下:联机Mod怎么做?
作者: zhj6690260    时间: 2012-7-18 09:30
zhj6690260 发表于 2012-7-18 09:26
我顺便问一下:联机Mod怎么做?

还有五种类型的常用工具
作者: zhj6690260    时间: 2012-7-18 09:36
zhj6690260 发表于 2012-7-18 09:30
还有五种类型的常用工具

以及如何修改方块的抗爆能力
作者: zhj6690260    时间: 2012-7-22 10:39
  1. package net.minecraft.src;

  2. public class mod_Crystal extends BaseMod{
  3.     public static Block oreCrystal;
  4.     public String getVersion()
  5.     {
  6.         return "1.0.0";
  7.     }
  8.     public void load()
  9.     {

  10.            
  11.             ItemCrystal = new ItemCrystal (21000).setItemName("ItemCrystal");
  12.             ItemCrystal.iconIndex = ModLoader.addOverride("/gui/items.png", "/ItemCrystal.png");
  13.             ModLoader.addName(ItemCrystal, "Crystal");
  14.         oreCrystal= new BlockCrystal(176, ModLoader.addOverride("/terrain.png", "/oreCrystal.png"), Material.rock);
  15.         ModLoader.registerBlock(oreCrystal);
  16.         ModLoader.addName(oreCrystal, "Crystal Ore");
  17.         ModLoader.addRecipe(new ItemStack(oreCrystal, 1), new Object[]
  18.                 {
  19.                          "FDF",
  20.                          "DSD",
  21.                          "FDF",
  22.                          Character.valueOf('F'), Block.cobblestone,
  23.                          Character.valueOf('D'), Item.redstone,
  24.                          Character.valueOf('S'), Item.diamond
  25.                 });
  26.         ModLoader.addRecipe(new ItemStack(ItemCrystal, 1), new Object[]
  27.                 {
  28.                          " F ",
  29.                          "FSF",
  30.                          " F ",
  31.                          Character.valueOf('F'), oreCrystal,
  32.                          Character.valueOf('S'), Item.diamond
  33.                         
  34.                 });
  35.         ModLoader.addRecipe(new ItemStack(Block.grass, 1), new Object[]
  36.                 {
  37.                          "   ",
  38.                          " S ",
  39.                          " F ",
  40.                          Character.valueOf('F'), Block.dirt,
  41.                          Character.valueOf('S'), Item.seeds
  42.                         
  43.                 });
  44.         ModLoader.addRecipe(new ItemStack(Item.ingotGold, 1), new Object[]
  45.                 {
  46.                          "FFF",
  47.                          "F F",
  48.                          "FFF",
  49.                          Character.valueOf('F'), Item.ingotIron
  50.                         
  51.                 });
  52.         ModLoader.addRecipe(new ItemStack(Item.diamond, 1), new Object[]
  53.                 {
  54.                          "   ",
  55.                          "FF ",
  56.                          "FF ",
  57.                          Character.valueOf('F'), Item.ingotGold
  58.                         
  59.                 });
  60.     }
  61.     public static Item ItemCrystal;
  62.    
  63. }
复制代码
这样,然后出错了
作者: zhj6690260    时间: 2012-7-25 11:15
zhj6690260 发表于 2012-7-22 10:39
这样,然后出错了

Eclipse没有报错,就是运行测试游戏时那个控制台窗口报错的
作者: wangshijie527    时间: 2012-8-21 07:05
不错,顶顶顶顶顶顶顶顶顶顶顶顶
作者: 红石研究家    时间: 2019-12-14 19:37
提示: 作者被禁止或删除 内容自动屏蔽
作者: dawn2329    时间: 2019-12-15 08:34
MCBBS有你更精彩