概述
本文介绍如何在Forge Mod中响应Block激活消息。
运行环境
Java 1.8 JDK
Minecraft Java Edition 1.12.2
Forge and MDK 1.12.2
设置Mod项目
在MDK目录下, 运行gradlew setupDecompWorkspace
命令以创建如下Mod项目结构
mdk/
├── build/
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── src/
│ ├── main/
│ ├── java/
│ └── resources/
│ ├── mcmod.info
│ └── pack.mcmeta
├── build.gradle
├── gradlew
└── gradlew.bat
设置Gradle build文件
编辑build.gradle
并修改version
, group
和archivesBaseName
version = "1.0.0"
group= "minecraftfun"
archivesBaseName = "clock-block-mod"
修改 mcmod.info
编辑 mcmod.info
以修改modid
, name
和description
.
"modid": "clockblockmod",
"name": "Clock Block Mod",
"description": "A Clock block",
提示: modid
只能使用小写字母.
创建block Java类
src/main/java/minecraftfun/ClockBlock.java
package minecraftfun;
import java.util.Date;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class ClockBlock extends Block {
public static final String NAME = "clock";
private static final String UNLOCALIZED_NAME = "clock_block";
private static final String REGISTRY_NAME = "clock_block_registry";
public ClockBlock() {
super(Material.ROCK);
this.setCreativeTab(CreativeTabs.BUILDING_BLOCKS);
this.setUnlocalizedName(UNLOCALIZED_NAME);
this.setRegistryName(REGISTRY_NAME);
}
@SideOnly(Side.CLIENT)
public BlockRenderLayer getBlockLayer() {
return BlockRenderLayer.SOLID;
}
public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state,
EntityPlayer playerIn, EnumHand hand,
EnumFacing facing, float hitX, float hitY, float hitZ) {
if (!worldIn.isRemote){
return false;
}
playerIn.sendMessage(
new TextComponentString("Time now is " + new Date()));
return true;
}
}
当Block被激活时, Forge会调用onBlockActivated
方法, 以上代码向玩家显示当前的时间. worldIn.isRemote
的逻辑判断用于防止该方法被重复调用.
创建mod Java类
src/main/java/minecraftfun/ClockBlockMod.java
package minecraftfun;
import org.apache.logging.log4j.Logger;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.ItemBlock;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
@Mod(modid = ClockBlockMod.MODID, name = ClockBlockMod.NAME, version = ClockBlockMod.VERSION)
public class ClockBlockMod {
public static final String MODID = "clockblockmod";
public static final String NAME = "Clock Block Mod";
public static final String VERSION = "1.0.0";
public static final String RESOURCE_INVENTORY = "inventory";
public static ClockBlock clockBlock;
public static ItemBlock itemClockBlock;
private static Logger logger;
@EventHandler
public void preInit(FMLPreInitializationEvent event)
{
logger = event.getModLog();
preInitBlock();
}
@EventHandler
public void init(FMLInitializationEvent event)
{
logger.info("Mod initlialised :" + NAME);
}
private void preInitBlock() {
clockBlock = new ClockBlock();
ForgeRegistries.BLOCKS.register(clockBlock);
itemClockBlock = new ItemBlock(clockBlock);
itemClockBlock.setRegistryName(clockBlock.getRegistryName());
ForgeRegistries.ITEMS.register(itemClockBlock);
ModelResourceLocation chinaModelResourceLocation = new ModelResourceLocation(
MODID + ":" + ClockBlock.NAME, RESOURCE_INVENTORY);
final int DEFAULT_ITEM_SUBTYPE = 0;
ModelLoader.setCustomModelResourceLocation(itemClockBlock, DEFAULT_ITEM_SUBTYPE, chinaModelResourceLocation);
}
}
设置resource目录结构
在src/main/resources
目录下, 创建如下目录和文件, 将MODID
替换为ClockBlockMod.MODID
, BLOCK_REGISTRY_NAME
替换为ClockBlock.REGISTRY_NAME
, BLOCK_UNLOCALIZED_NAME
替换为ClockBlock.UNLOCALIZED_NAME
,BLOCK_NAME
替换为ClockBlock.NAME
.
src/main/resources/
└── <MODID>/
├── blockstates/
│ └── <BLOCK_REGISTRY_NAME>.json
├── lang/
│ └── en_us.lang
├── models/
│ ├── block/
│ │ └── <BLOCK_UNLOCALIZED_NAME>_model.json
│ └── item/
│ └── <BLOCK_NAME>.json
└── textures/
└── blocks/
修改 block states文件
src/main/resources/ClockBlockMod/blockstates/target_block_registry.json
{
"variants": {
"normal": { "model": "<MODID>:<BLOCK_UNLOCALIZED_NAME>_model" }
}
}
将MODID
替换为ClockBlockMod.MODID
, BLOCK_UNLOCALIZED_NAME
替换为ClockBlock.UNLOCALIZED_NAME
.
修改mod语言文件
src/main/resources/ClockBlockMod/lang/en_us.lang
tile.<BLOCK_UNLOCALIZED_NAME>.name=Clock Block
将BLOCK_UNLOCALIZED_NAME
替换为ClockBlock.UNLOCALIZED_NAME
.
修改block model文件
src/main/resources/ClockBlockMod/models/block/clock_block_model.json
"parent": "block/cube",
"textures": {
"down": "<MODID>:blocks/<FACE_IMAGE>",
"up": "<MODID>:blocks/<FACE_IMAGE>",
"north": "<MODID>:blocks/<FACE_IMAGE>",
"east": "<MODID>:blocks/<FACE_IMAGE>",
"south": "<MODID>:blocks/<FACE_IMAGE>",
"west": "<MODID>:blocks/<FACE_IMAGE>",
}
将MODID
替换为ClockBlockMod.MODID
, FACE_IMAGE
则是用于block六个面的图形文件名, 去掉.png
后缀.
修改item文件
src/main/resources/ClockBlockMod/models/item/clock.json
"parent": "<MODID>:block/<BLOCK_UNLOCALIZED_NAME>_model"
将MODID
替换为ClockBlockMod.MODID
, BLOCK_UNLOCALIZED_NAME
替换为ClockBlock.UNLOCALIZED_NAME
.
block图形文件
创建256*256的PNG图形文件clock.png
, 放在src/main/resources/ClockBlockMod/textures/blocks/
目录下.
编译Mod
运行如下命令以编译Mod
gradlew build.
该命令在build/libs
目录下生成[archivesBaseName]-[version].jar
文件.
测试Mod
将编译生成的mod jar文件放入Minecraft mods目录(在Windows下为 %appdata%.minecraft\mods), 运行Minecraft.
在inventory找到"Clock"block,放下后用鼠标右键点击以激活该block.
小结
对Minecraft Mod开发感兴趣的朋友不妨试一试, 所有源代码和mod jar文件也可以从这里下载.