今天是1024程序员日,我们尝试在1.19.2的模组中实现物品栏、方块和物品
1.在项目主类Main.java中添加物品栏声明,同时将物品和方块的类进行注册:
Main.java
package com.joy187.re8joymod;
import com.joy187.re8joymod.init.BlockInit;
import com.joy187.re8joymod.init.ItemInit;
import com.mojang.logging.LogUtils;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Blocks;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.registries.ForgeRegistries;
import org.slf4j.Logger;
// The value here should match an entry in the META-INF/mods.toml file
@Mod(Main.MOD_ID)
public class Main
{
// Define mod id in a common place for everything to reference
public static final String MOD_ID = "re8joymod"; //修改为你的模组名称
// Directly reference a slf4j logger
private static final Logger LOGGER = LogUtils.getLogger();
//物品栏声明
public static final CreativeModeTab TUTORIAL_TAB = new CreativeModeTab(MOD_ID) {
@Override
public ItemStack makeIcon() {
//这个是物品栏的图标使用哪个物品来展示
return new ItemStack(BlockInit.EXAMPLE_BLOCK.get());
}
};
public Main()
{
IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
// Register the commonSetup method for modloading
bus.addListener(this::commonSetup);
bus.addListener(this::setup);
//添加物品、方块的注册
ItemInit.ITEMS.register(bus);
BlockInit.BLOCKS.register(bus);
// Register ourselves for server and other game events we are interested in
MinecraftForge.EVENT_BUS.register(this);
}
private void setup(final FMLCommonSetupEvent event)
{
}
private void commonSetup(final FMLCommonSetupEvent event)
{
// Some common setup code
LOGGER.info("HELLO FROM COMMON SETUP");
LOGGER.info("DIRT BLOCK >> {}", ForgeRegistries.BLOCKS.getKey(Blocks.DIRT));
}
// You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent
@Mod.EventBusSubscriber(modid = MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
public static class ClientModEvents
{
@SubscribeEvent
public static void onClientSetup(FMLClientSetupEvent event)
{
}
}
}
2.Java包中新建init包,init包中新建一个我们的物品类ItemInit :
ItemInit.java
package com.joy187.re8joymod.init;
import com.joy187.re8joymod.Main;
import net.minecraft.world.item.Item;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import java.util.function.Supplier;
public class ItemInit {
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, Main.MOD_ID);
//我们的第一个物品
public static final RegistryObject<Item> LEI = register("lei",
() -> new Item(new Item.Properties().tab(Main.TUTORIAL_TAB)));
//第二个物品
//public static final RegistryObject<Item> FAKE = register("fake",
// () -> new Item(new Item.Properties().tab(Main.TUTORIAL_TAB)));
private static <T extends Item> RegistryObject<T> register(final String name, final Supplier<T> item) {
return ITEMS.register(name, item);
}
}
3.在init包中新建一个我们的方块类BlockInit:
BlockInit.java
package com.joy187.re8joymod.init;
import com.joy187.re8joymod.Main;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.StainedGlassBlock;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.material.MaterialColor;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import java.util.function.Function;
import java.util.function.Supplier;
public class BlockInit {
public static DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, Main.MOD_ID);
public static final DeferredRegister<Item> ITEMS = ItemInit.ITEMS;
//第一个方块 of(方块和什么类似,方块颜色) strength(挖掘时长(越大时间越长),防爆等级(越大越防爆)) sound(挖方块的声音)
public static final RegistryObject<Block> EXAMPLE_BLOCK = register("example_block",
() -> new Block(BlockBehaviour.Properties.of(Material.METAL, MaterialColor.COLOR_PURPLE).strength(5f, 6f)
.sound(SoundType.METAL).requiresCorrectToolForDrops()),
object -> () -> new BlockItem(object.get(), new Item.Properties().tab(Main.TUTORIAL_TAB)));
//第二个方块
//public static final RegistryObject<Block> HOT_BLOCK = register("hot_block",
// () -> new Block(BlockBehaviour.Properties.of(Material.METAL, MaterialColor.COLOR_PURPLE).strength(5f, 6f)
// .sound(SoundType.METAL).requiresCorrectToolForDrops()),
// object -> () -> new BlockItem(object.get(), new Item.Properties().tab(Main.TUTORIAL_TAB)));
private static <T extends Block> RegistryObject<T> registerBlock(final String name,
final Supplier<? extends T> block) {
return BLOCKS.register(name, block);
}
private static <T extends Block> RegistryObject<T> register(final String name, final Supplier<? extends T> block,
Function<RegistryObject<T>, Supplier<? extends Item>> item) {
RegistryObject<T> obj = registerBlock(name, block);
ITEMS.register(name, item.apply(obj));
return obj;
}
private static <T extends Block> RegistryObject<T> registerBlock(String name, Supplier<T> block, CreativeModeTab tab) {
RegistryObject<T> toReturn = BLOCKS.register(name, block);
registerBlockItem(name, toReturn, tab);
return toReturn;
}
private static <T extends Block> RegistryObject<Item> registerBlockItem(String name, RegistryObject<T> block,
CreativeModeTab tab) {
return ItemInit.ITEMS.register(name, () -> new BlockItem(block.get(),
new Item.Properties().tab(tab)));
}
private static <T extends Block> RegistryObject<T> registerBlockWithoutBlockItem(String name, Supplier<T> block) {
return BLOCKS.register(name, block);
}
public static Supplier<Block> createStainedGlassFromColor(DyeColor color) {
return () -> new StainedGlassBlock(color, BlockBehaviour.Properties.of(Material.GLASS, color).strength(0.3F)
.sound(SoundType.GLASS).noOcclusion().isValidSpawn(BlockInit::never).isRedstoneConductor(BlockInit::never).isSuffocating(BlockInit::never).isViewBlocking(BlockInit::never));
}
public static boolean always(BlockState state, BlockGetter reader, BlockPos pos) {
return true;
}
public static boolean never(BlockState state, BlockGetter reader, BlockPos pos) {
return false;
}
public static boolean always(BlockState state, BlockGetter reader, BlockPos pos, EntityType<?> entityType) {
return true;
}
public static boolean never(BlockState state, BlockGetter reader, BlockPos pos, EntityType<?> entityType) {
return false;
}
}
4.代码部分结束,进入资源包制作环节:
在resources/assets/lang/你的模组名称
包中的en_us.json中添加英文名称:
en_us.json
{
"item.re8joymod.lei":"125 Lei",
"block.re8joymod.example_block": "Umbrella Block",
"itemGroup.re8joymod": "RE8 Item"
}
在zh_cn.json中添加中文名称:
zh_cn.json
{
"item.re8joymod.lei":"125 物品",
"block.re8joymod.example_block": "方块",
"itemGroup.re8joymod": "RE8 物品栏"
}
在blockstates
包中新建一个我们的方块文件,指明其模型位置:
example_block.json
{
"variants": {
"": {
"model": "re8joymod:block/example_block"
}
}
}
在models/block
中添加方块的模型文件:
example_block.json
{
"parent": "block/cube_all",
"textures": {
"all": "re8joymod:block/example_block"
}
}
在models/item
中添加方块和物品的手持模型文件:
添加方块的手持模型文件:
example_block.json
{
"parent": "re8joymod:block/example_block"
}
添加物品的手持模型文件:
lei.json
{
"parent": "item/generated",
"textures": {
"layer0": "re8joymod:item/lei"
}
}
在textures/block
中添加方块的贴图,在textures/item
中添加物品的贴图:
5.在resources/data文件夹下新建2个文件夹,一个叫minecraft,另一个是你的模组名称(以re8joymod为例)
在minecraft文件夹中新建 -> tags文件夹 -> tags包中新建blocks文件夹 -> blocks包中新建mineable文件夹 ->在mineable中新建 pickaxe.json(定义方块是否可挖掘)
pickaxe.json
{
"replace": false,
"values": [
"re8joymod:example_block" //这里面的方块都是可以被挖掘的
]
}
在re8joymod中新建loot_tables文件夹 -> 在loot_tables中新建blocks文件夹 -> 在blocks文件夹中新建 方块名.json(名称与BlockInit.java中你自定义的方块名称保持一致)
example_block.json(挖掉之后方块的掉落物)
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1.0,
"entries": [
{
"type": "minecraft:item",
"name": "re8joymod:example_block" //掉落物格式:模组名称:物品、方块的名称,原版默认是minecraft:xxx
}
]
}
]
}