企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 更复杂的Mod 恭喜,你进入了进阶篇。此时你应该已经编写了大量的代码,并打算实现更复杂的逻辑和探索更底层的API了。 ## 代码规范 如果你在之前的开发中很少/没有注意代码的干净整洁的话,此时你的项目中的代码可能已经变得十分混乱。此时我们有必要再次讲一下Java中的命名规范与代码格式了。 ### **1. 大括号位于首行末尾** ### **2. 运算符和操作符两边应有空格** ### **3. 类的命名应使用大写驼峰式(每个单词首字母大写,没有下划线)** ### **4. 变量/字段/方法命名应使用小写驼峰式(第一个单词首字母小写,后面每个单词首字母大写,没有下划线)** ### **5. 静态常量命名全部大写,用下划线分词** (以下为Minecraft与Forge中的特殊约定) ### **6. 所有资源文件名称都为全小写,用下划线分词** ### **7.注册名应该全小写,用下划线分词** 最后,所有编程语言都要遵循一个约定: # **不 要 压 行** 反面例子: ~~~ // 什么? 你发现了不符合常理的new BlockState()? 不要怀疑人生,这段代码是1.14.4的...... player.world.setBlockState(new BlockPos(pos.getX(), pos.getY() + 1, pos.getZ()), new BlockState(Blocks.ENDER_CHEST, ImmutableMap<IProperty, Comparable>builder().put(EnderChestBlock.FACING, (player.getHorizontalFacing().getIndex() <= 1) ? Direction.byIndex((int)Math.random() * 4 + 1) : player.getHorizontalFacing()).build()).with(EnderChestBlock.WATERLOGGED, false)); ~~~ 同时如果你是写系统内核或者资深OI玩家出身的,请切记**不要把你的高级编译器原理知识运用到团队开发中**! 反面例子:**(A+B Problem)** ~~~ main(n){gets(&n);printf("%d",n%85-43);} ~~~ 另外,不要忘了**使用包(Package)来分类存放你的类**。 以下为遵循了格式约定的示例代码: ~~~ package com.github.zi_jing.test; abstract class Parent { private static final String str = "hello"; public static String getStr() { return str; } public abstract int getId(); } interface TestInterface { boolean someMethod(int a); } public class TestClass extends Parent implements TestInterface { /** * xxx的尺寸属性 */ public static enum Size { SMALL, MEDIUM, LARGE } private static int nextId = 0; private int id; private Size size; /** * 构造函数描述 * @param size 尺寸 */ public TestClass(Size size) { this.size = size; this.id = getNextId(); } private static int getNextId() { return nextId++; } public Size getSize() { return this.size; } @Override public int getId() { return this.id; } @Override public boolean someMethod(int a) { return false; } } ~~~ ## 游戏逻辑 ### 关于延时 切记:在**任何事件订阅,update方法,或者GUI的绘制方法以及与网络有关的代码**中,不要试图直接编写“延时”代码,这么做会导致**整个游戏逻辑的停止或者客户端挂起**,可能会导致严重后果。 如果你确实需要在游戏逻辑中编写延时,请使用`Timer`(`java.util.Timer`)等库来进行多线程操作。 **注意:在其他线程中操作客户端/服务端游戏对象需要使用`scheduleTask()`方法(这一点和网络线程一样)。** ### 关于tick内游戏逻辑 尽量不要在单个tick中进行大量运算或者与游戏对象频繁交互,这样做会**大幅降低TPS**。 如果确实需要偶尔进行大量运算,可以考虑**把它放到单独的线程**。 ## 基础篇一些零碎的问题 ### 关于日志输出 众所周知,我们只需要获取模组的`Logger`实例,然后调用它的`info`、`debug`、`warn`、`error`方法就行了。 但是如果我们想输出格式化后的文本应该怎么写呢?我们用默认的文本格式化标记(%s,%d等)并没有起作用,这是因为`Logger`的格式化标识符是`{}`,且不需要指定类型。 例子: ~~~ logger.info("Loading page {} of {}, the title is \"{}\"", cur, total, title); ~~~ 如果你只想使用普通的文本格式化符号的话,就只能这样了: ~~~ logger.info(String.format("Loading page %d of %d, the title is \"%s\"", cur, total, title)); ~~~ 当然这种方法也不是不行,只是稍微麻烦了一点?(雾) ### 待补全