经过前面两个教程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,ClientOnlyProxyDedicatedServerProxy

  • 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

参考资料

https://github.com/TheGreyGhost/MinecraftByExample

Minecraft Forge编程入门三 “初始化项目结构和逻辑”的更多相关文章

  1. Minecraft Forge编程入门二 “工艺和食谱”

    从现在开始我们就要开始真正写代码了,还没有来得及配置环境的同学可以参考Minecraft Forge编程入门一 "环境搭建"这篇文章来进行环境搭建. 工艺(Craft)和食谱(Re ...

  2. Minecraft Forge编程入门一 “环境搭建”

    什么是Forge Minecraft Forge is a Minecraft application programming interface (API) which allows almost ...

  3. day1(初始化项目结构)

    1.初始化项目结构  └─shiyanlou_project    │  .gitignore    │  README.en.md           # 英文    │  README.md    ...

  4. 脑残式网络编程入门(三):HTTP协议必知必会的一些知识

    本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.前言 无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交 ...

  5. Dubbo 入门之二 ——- 项目结构解析

    本文主要说明点 概述 背景 需求 架构 Dubbo源代码项目结构 概述 分享 Dubbo 的项目结构 ,通过本文可以大致了解到Dubbo整个项目的结构 背景 将一个项目进行拆分, 进行分布式架构. 需 ...

  6. [同步到 MaixPy3 文档] 使用 Python 编程入门开源硬件项目

    本文是给有一点 Python 基础但还想进一步深入的同学,有经验的开发者建议跳过. 前言 在写这篇案例系列的时候 junhuanchen 期望能够引导用户如何成为专业的开发者,不是只会调用代码就好,所 ...

  7. 从零开始Vue项目实战(三)-项目结构

    目录结构 ├── README.md 项目介绍 ├── index.html 入口页面 ├── build 构建脚本目录 │ ├── build-server.js 运行本地构建服务器,可以访问构建后 ...

  8. Kafka.net使用编程入门(三)

    这个世界既不是有钱人的世界,也不是有权人的世界,它是有心人的世界. 一些有用的命令 1.列出主题:kafka-topics.bat --list --zookeeper localhost:2181 ...

  9. C#编程(三十七)----------结构比较

    结构比较 数组和元组都实现接口IStructuralEquatable和IStructuralComparable.这两个接口不仅可以比较引用,还可以比较内容.这些接口都是显示实现的,所以在使用时需要 ...

随机推荐

  1. Linux - 进程控制 代码(C)

    进程控制 代码(C) 本文地址:http://blog.csdn.net/caroline_wendy 输出进程ID.getpid(). 代码: /*By C.L.Wang * Eclipse CDT ...

  2. 常用 cdn

    http://www.bootcdn.cn/ jquery <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.j ...

  3. JS根据时间内容分组代码

    let newArr = []; res.data.data.forEach((address, i) => { let index = -1; let newDates = Date.pars ...

  4. IBATIS中‘$’与‘#’使用

    IBATIS中关于iterate和‘$’与‘#’的应用 一个包含List元素的HashMap参数赋给sqlMap  public int getCountById(String id, String ...

  5. winform播放音乐

    string sound = Application.StartupPath +@"\song\123.wav"; //Application.StartupPath:程序exe所 ...

  6. spring-common.xml

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  7. async and await 简单的入门

    如果有几个Uri,需要获取这些Uri的所有内容的长度之和,你会如何做? 很简单,使用WebClient一个一个的获取uri的内容长度,进行累加. 也就是说如果有5个Uri,请求的时间分别是:1s 2s ...

  8. 海康网络摄像机调用SDK解码Java版

    两个回调函数: FRealDataCallBack 实现预览回调数据 DecCallBack 解码回调函数 在HCNetSDK.java补充相关函数和结构声明 //播放库函数声明,PlayCtrl.d ...

  9. JDK1.5中支持的 for循环的语法

    JDK1.5中支持的 for循环的语法 解答: for(type element : array) { System.out.println(element) } type 集合(不仅仅指Collec ...

  10. 转:Python的这几个技巧,简直屌爆了

    经使用Python编程有多年了,即使今天我仍然惊奇于这种语言所能让代码表现出的整洁和对DRY编程原则的适用.这些年来的经历让我学到了很多的小技巧和知识,大多数是通过阅读很流行的开源软件,如Django ...