经过前面两个教程Minecraft Forge编程入门一 “环境搭建”和Minecraft Forge编程入门二 “工艺和食谱”,我们大体知道了如何自定义合成配方,主要是在
Mod类的init方法中进行注册,但可想而之随着项目的进行需要注册的内容会越来越多,全部写在init中会显得Mod类很臃肿。作为一个优秀的程序员可定不能容忍这种事情发生,那么接下来我们对我们的工程进行一下重构。
看一下重构后的代码结构:
源码包的处理
在我的工程中,我的包名时com.zql.mc.zmod
,这个大家可以自己定义。
我们先看一下ZMod.java这个类:
package com.zql.mc.zmod;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
/**
*
*告诉FML我们的Mod的相关信息,这里我的modid为ZMod,版本号是1.0,名字是ZMod
*/
@Mod(modid = ZMod.MOD_ID, version = ZMod.VERSION, name = ZMod.MOD_NAME)
public class ZMod {
public static final String MOD_ID = "ZMod";
public static final String VERSION = "1.0";
public static final String MOD_NAME = "ZMod";
//让FML为我们初始化
@Mod.Instance(value = ZMod.MOD_ID)
public static ZMod instance;
//告诉FML,对于本地和服务端,proxy分别用ClientOnlyProxy和DedicatedServerProxy进行初始化。
@SidedProxy(clientSide = "com.zql.mc.zmod.ClientOnlyProxy", serverSide = "com.zql.mc.zmod.DedicatedServerProxy")
public static CommonProxy proxy;
//在我们的mod被加载的时候会按preInit,init和postInit的顺序执行这三个方法。
//preInit主要用于读取本地配置,创建方块,物品等并注册他们。
@EventHandler
public void preInit(FMLPreInitializationEvent event) {
proxy.preInit();
}
//init主要用于构建一些我们自定义的数据类型,注册自定义合成方法,和其它一些操作。
@EventHandler
public void init(FMLInitializationEvent event) {
proxy.init();
}
//与其它mod进行交互,完成我们mod最后的处理
@EventHandler
public void postInit(FMLPostInitializationEvent event) {
proxy.postInit();
}
}
对代码的解释我都写在相应位置,请仔细阅读。
接着介绍三个类:CommonProxy
,ClientOnlyProxy
和DedicatedServerProxy
。
- CommonProxy:用于初始化mod,并使它能够正常运行。CommonProxy的代码同时在本地和服务端运行。
其中preInit,init和postInit分别对应Mod中的三个方法。
package com.zql.mc.zmod;
import net.minecraft.entity.player.EntityPlayer;
public abstract class CommonProxy {
public void preInit() {
}
public void init() {
}
public void postInit() {
}
abstract public boolean playerIsInCreativeMode(EntityPlayer player);
}
- ClientOnlyProxy:继承CommonProxy,在它的基础上做一些只有client端需要处理的事情如方块的渲染工作等。
package com.zql.mc.zmod;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
public class ClientOnlyProxy extends CommonProxy {
public void preInit() {
super.preInit();
}
public void init() {
super.init();
}
public void postInit() {
super.postInit();
}
@Override
public boolean playerIsInCreativeMode(EntityPlayer player) {
if (player instanceof EntityPlayerMP) {
EntityPlayerMP entityPlayerMP = (EntityPlayerMP) player;
return entityPlayerMP.theItemInWorldManager.isCreative();
} else if (player instanceof EntityPlayerSP) {
return Minecraft.getMinecraft().playerController.isInCreativeMode();
}
return false;
}
}
- DedicatedServerProxy:继承CommonProxy,在它的基础上做一些只有server端需要处理的事情。但大部分时间不需要扩展,只要完成CommonProxy的工作就行了。
package com.zql.mc.zmod;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
public class DedicatedServerProxy extends CommonProxy {
public void preInit() {
super.preInit();
}
public void init() {
super.init();
}
public void postInit() {
super.postInit();
}
@Override
public boolean playerIsInCreativeMode(EntityPlayer player) {
if (player instanceof EntityPlayerMP) {
EntityPlayerMP entityPlayerMP = (EntityPlayerMP) player;
return entityPlayerMP.theItemInWorldManager.isCreative();
}
return false;
}
}
目前读者如果上面的代码有疑惑是正常的,等后面结合例子看的时候就明朗了。下面来看资源目录的初始化:
在src/main/resources下新建一下几个包:
- assets.zmod.blockstates:用于自定义方块状态的json文件存储。
- assets.zmod.lang:用于自定义物品和方块等的名称。
- assets.zmod.models.block:用于自定义方块模型的json文件存储。
- assets.zmod.models.item:用于自定义物品模型的json文件存储。
- assets.zmod.textures.blocks:用于自定义方块的纹理图片的存储。
- assets.zmod.textures.items:用于自定义物品的纹理图片的存储。
以上文件夹名字是固定的,不能有任何偏差。
以上就是我们要做的准备工作,所谓工欲善其事,必先利其器。现在我们的利器已经准备完毕,接下来就可以开始我们物品和方块的自定义之旅了。
文章中涉及的代码均在我的github中:
Minecraft-Forge-Sample