我的世界java版农民繁殖
说到方块实体(TileEntity),可以理解为一种功能性方块,比如熔炉,箱子,附魔台等。
我们今天来做一个类似于熔炉的反应器
熔炉逻辑: 放入燃料-> 放入物品 -> 获取产出物品
1.首先我们发现熔炉有一个GUI界面,所以我们也要给自己的机器先准备一个GUI界面,可以用PS等软件进行制作(大小为256×256,在教程最后可以直接下载):
将做好的GUI界面放入src\main\resources\assets\你的modid\textures\gui这个地址下:
2.在开发包的blocks文件夹下新建tileEntity包 -> tileEntity包内新建ContainerVirusGenerator类:
由于我们这次准备了4个物品槽用于反应,1个为燃料槽(2号),2个为原料槽(0号、1号),1个为产物槽(3号):
你可以修改每个槽的x,y坐标来进行修改,但同时你要修改自己的第1步中的GUI贴图。
ContainerVirusGenerator.java
package com.joy187.rejoymod.blocks.tileEntity.virusGenerator; import com.joy187.rejoymod.recipe.special.VirusGeneratorRecipes; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.IContainerListener; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.SlotItemHandler; public class ContainerVirusGenerator extends Container { private final TileEntityVirusGenerator tileentity; //我们做的是类熔炉的机器,所以设置4个参数:熔炼时间,熔炼要求时间,燃料时间,当前燃烧时间 private int cookTime, totalCookTime, burnTime, currentBurnTime; public ContainerVirusGenerator(InventoryPlayer player, TileEntityVirusGenerator tileentity) { this.tileentity = tileentity; IItemHandler handler = tileentity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null); //设置物品槽的总数与每个槽位的编号、坐标 this.addSlotToContainer(new SlotItemHandler(handler, 0, 26, 11)); this.addSlotToContainer(new SlotItemHandler(handler, 1, 26, 59)); this.addSlotToContainer(new SlotItemHandler(handler, 2, 7, 35)); this.addSlotToContainer(new SlotItemHandler(handler, 3, 81, 36)); //把Inventory中的三行物品栏和一行个人栏展示出来 for(int y = 0; y < 3; y++) { for(int x = 0; x < 9; x++) { this.addSlotToContainer(new Slot(player, x + y*9 + 9, 8 + x*18, 84 + y*18)); } } for(int x = 0; x < 9; x++) { this.addSlotToContainer(new Slot(player, x, 8 + x * 18, 142)); } } @Override public void detectAndSendChanges() { super.detectAndSendChanges(); for(int i = 0; i < this.listeners.size(); ++i) { IContainerListener listener = (IContainerListener)this.listeners.get(i); //我们一共有4个参数,所以要监视这4个参数的实时状态 if(this.cookTime != this.tileentity.getField(2)) listener.sendWindowProperty(this, 2, this.tileentity.getField(2)); if(this.burnTime != this.tileentity.getField(0)) listener.sendWindowProperty(this, 0, this.tileentity.getField(0)); if(this.currentBurnTime != this.tileentity.getField(1)) listener.sendWindowProperty(this, 1, this.tileentity.getField(1)); if(this.totalCookTime != this.tileentity.getField(3)) listener.sendWindowProperty(this, 3, this.tileentity.getField(3)); } this.cookTime = this.tileentity.getField(2); this.burnTime = this.tileentity.getField(0); this.currentBurnTime = this.tileentity.getField(1); this.totalCookTime = this.tileentity.getField(3); } @Override @SideOnly(Side.CLIENT) public void updateProgressBar(int id, int data) { this.tileentity.setField(id, data); } @Override public boolean canInteractWith(EntityPlayer playerIn) { return this.tileentity.isUsableByPlayer(playerIn); } @Override public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) { ItemStack stack = ItemStack.EMPTY; Slot slot = (Slot)this.inventorySlots.get(index); if(slot != null && slot.getHasStack()) { ItemStack stack1 = slot.getStack(); stack = stack1.copy(); if(index == 3) { if(!this.mergeItemStack(stack1, 4, 40, true)) return ItemStack.EMPTY; slot.onSlotChange(stack1, stack); } else if(index != 2 && index != 1 && index != 0) { Slot slot1 = (Slot)this.inventorySlots.get(index + 1); if(!VirusGeneratorRecipes.getInstance().getSinteringResult(stack1, slot1.getStack()).isEmpty()) { if(!this.mergeItemStack(stack1, 0, 2, false)) { return ItemStack.EMPTY; } else if(TileEntityVirusGenerator.isItemFuel(stack1)) { if(!this.mergeItemStack(stack1, 2, 3, false)) return ItemStack.EMPTY; } else if(TileEntityVirusGenerator.isItemFuel(stack1)) { if(!this.mergeItemStack(stack1, 2, 3, false)) return ItemStack.EMPTY; } else if(TileEntityVirusGenerator.isItemFuel(stack1)) { if(!this.mergeItemStack(stack1, 2, 3, false)) return ItemStack.EMPTY; } else if(index >= 4 && index < 31) { if(!this.mergeItemStack(stack1, 31, 40, false)) return ItemStack.EMPTY; } else if(index >= 31 && index < 40 && !this.mergeItemStack(stack1, 4, 31, false)) { return ItemStack.EMPTY; } } } else if(!this.mergeItemStack(stack1, 4, 40, false)) { return ItemStack.EMPTY; } if(stack1.isEmpty()) { slot.putStack(ItemStack.EMPTY); } else { slot.onSlotChanged(); } if(stack1.getCount() == stack.getCount()) return ItemStack.EMPTY; slot.onTake(playerIn, stack1); } return stack; } }同时在tileEntity包内新建GuiVirusGenerator类:
GuiVirusGenerator.java
package com.joy187.rejoymod.blocks.tileEntity.virusGenerator; import com.joy187.rejoymod.util.Reference; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.util.ResourceLocation; public class GuiVirusGenerator extends GuiContainer { //将第一步的GUI界面的路径传给TEXTURES private static final ResourceLocation TEXTURES = new ResourceLocation(Reference.Mod_ID + ":textures/gui/virus_generator.png"); private final InventoryPlayer player; private final TileEntityVirusGenerator tileentity; public GuiVirusGenerator(InventoryPlayer player, TileEntityVirusGenerator tileentity) { super(new ContainerVirusGenerator(player, tileentity)); this.player = player; this.tileentity = tileentity; } @Override protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { String tileName = this.tileentity.getDisplayName().getUnformattedText(); //在GUI界面的上方显示出机器的名字 this.fontRenderer.drawString(tileName, (this.xSize / 2 - this.fontRenderer.getStringWidth(tileName) / 2) + 3, 8, 4210752); this.fontRenderer.drawString(this.player.getDisplayName().getUnformattedText(), 122, this.ySize - 96 + 2, 4210752); } //显示出整个GUI界面 @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f); .getTextureManager().bindTexture(TEXTURES); this.drawTexturedModalRect(this.guiLeft, this.guiTop, 0, 0, this.xSize, this.ySize); if(TileEntityVirusGenerator.isBurning(tileentity)) { int k = this.getBurnLeftScaled(13); this.drawTexturedModalRect(this.guiLeft + 8, this.guiTop + 54 + 12 - k, 176, 12 - k, 14, k + 1); } int l = this.getCookProgressScaled(24); this.drawTexturedModalRect(this.guiLeft + 44, this.guiTop + 36, 176, 14, l + 1, 16); } private int getBurnLeftScaled(int pixels) { int i = this.tileentity.getField(1); if(i == 0) i = 200; return this.tileentity.getField(0) * pixels / i; } private int getCookProgressScaled(int pixels) { int i = this.tileentity.getField(2); int j = this.tileentity.getField(3); return j != 0 && i != 0 ? i * pixels / j : 0; } }3.GUI做好之后我们开始定义一个机器类,在tileEntity包内新建TileEntityVirusGenerator类:
TileEntityVirusGenerator.java
package com.joy187.rejoymod.blocks.tileEntity.virusGenerator; import com.joy187.rejoymod.item.ModItems; import com.joy187.rejoymod.recipe.special.VirusGeneratorRecipes; import net.minecraft.block.BlockFurnace; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.*; import net.minecraft.item.crafting.FurnaceRecipes; import net.minecraft.tileentity.TileEntity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.ITickable; import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentTranslation; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.ItemStackHandler; public class TileEntityVirusGenerator extends TileEntity implements ITickable { //与我们的GUI设计保持一致,本教程是一共4个槽位,你可以自己设计GUI和槽位数量 public ItemStackHandler handler = new ItemStackHandler(4); private String customName; private ItemStack smelting = ItemStack.EMPTY; private int burnTime; private int currentBurnTime; private int cookTime; //默认烧好一个物品的时间是200tick private int totalCookTime = 200; @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return true; else return false; } @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return (T) this.handler; return super.getCapability(capability, facing); } public boolean hasCustomName() { return this.customName != null && !this.customName.isEmpty(); } public void setCustomName(String customName) { this.customName = customName; } @Override public ITextComponent getDisplayName() { return this.hasCustomName() ? new TextComponentString(this.customName) : new TextComponentTranslation("container.virus_generator"); } //因为我们一共有四个参数(burnTime、cookTime、totalCookTime、currentBurnTime),都要加入NBT标签 @Override public void readFromNBT(NBTTagCompound compound) { super.readFromNBT(compound); this.handler.deserializeNBT(compound.getCompoundTag("Inventory")); this.burnTime = compound.getInteger("BurnTime"); this.cookTime = compound.getInteger("CookTime"); this.totalCookTime = compound.getInteger("CookTimeTotal"); this.currentBurnTime = getItemBurnTime((ItemStack)this.handler.getStackInSlot(2)); if(compound.hasKey("CustomName", 8)) this.setCustomName(compound.getString("CustomName")); } @Override public NBTTagCompound writeToNBT(NBTTagCompound compound) { super.writeToNBT(compound); compound.setInteger("BurnTime", (short)this.burnTime); compound.setInteger("CookTime", (short)this.cookTime); compound.setInteger("CookTimeTotal", (short)this.totalCookTime); compound.setTag("Inventory", this.handler.serializeNBT()); if(this.hasCustomName()) compound.setString("CustomName", this.customName); return compound; } public boolean isBurning() { return this.burnTime > 0; } @SideOnly(Side.CLIENT) public static boolean isBurning(TileEntityVirusGenerator tile) { return tile.getField(0) > 0; } //对机器燃烧的状态进行实时更新 public void update() { boolean flag = this.isBurning(); boolean flag1 = false; if (this.isBurning()) { --this.burnTime; } if (!this.world.isRemote) { ItemStack[] itemstack = new ItemStack[] {handler.getStackInSlot(0), handler.getStackInSlot(1)}; ItemStack fuel = this.handler.getStackInSlot(2); if (this.isBurning() || !fuel.isEmpty() && !this.handler.getStackInSlot(0).isEmpty() || this.handler.getStackInSlot(1).isEmpty()) { if (!this.isBurning() && this.canSmelt()) { this.burnTime = getItemBurnTime(fuel); this.currentBurnTime = this.burnTime; if (this.isBurning()) { flag1 = true; if (!fuel.isEmpty()) { Item item = fuel.getItem(); fuel.shrink(1); if (fuel.isEmpty()) { ItemStack item1 = item.getContainerItem(fuel); this.handler.setStackInSlot(2, item1); } } } } if (this.isBurning() && this.canSmelt()) { ++this.cookTime; if (this.cookTime == this.totalCookTime) { //熔炼时间达到了熔炼要求时间,就在3号槽产出一个产物 this.cookTime = 0; this.totalCookTime = this.getCookTime(this.handler.getStackInSlot(2)); this.smeltItem(); flag1 = true; } } else { this.cookTime = 0; } } else if (!this.isBurning() && this.cookTime > 0) { this.cookTime = MathHelper.clamp(this.cookTime - 2, 0, this.totalCookTime); } if (flag != this.isBurning()) { flag1 = true; BlockVirusGenerator.setState(this.isBurning(), this.world, this.pos); } } if (flag1) { this.markDirty(); } } private boolean canSmelt() { if(((ItemStack)this.handler.getStackInSlot(0)).isEmpty() || ((ItemStack)this.handler.getStackInSlot(1)).isEmpty()) { return false; } else { ItemStack result = VirusGeneratorRecipes.getInstance().getSinteringResult((ItemStack)this.handler.getStackInSlot(0), (ItemStack)this.handler.getStackInSlot(1)); if (result.isEmpty()) { return false; } else { ItemStack output = (ItemStack)this.handler.getStackInSlot(3); if (output.isEmpty()) { return true; } else if (!output.isItemEqual(result)) { return false; } else if (output.getCount() + result.getCount() <= 64 && output.getCount() + result.getCount() <= output.getMaxStackSize()) // Forge fix: make furnace respect stack sizes in furnace recipes { return true; } else { return output.getCount() + result.getCount() <= output.getMaxStackSize(); // Forge fix: make furnace respect stack sizes in furnace recipes } } } } public void smeltItem() { if (this.canSmelt()) { ItemStack[] itemstack = new ItemStack[] {handler.getStackInSlot(0), handler.getStackInSlot(1)}; ItemStack itemstack1 = VirusGeneratorRecipes.getInstance().getSinteringResult((ItemStack)this.handler.getStackInSlot(0), (ItemStack)this.handler.getStackInSlot(1)); ItemStack itemstack2 = this.handler.getStackInSlot(3); if (itemstack2.isEmpty()) { this.handler.setStackInSlot(3,itemstack1.copy()); } else if (itemstack2.getItem() == itemstack1.getItem()) { itemstack2.grow(itemstack1.getCount()); } itemstack[0].shrink(1); itemstack[1].shrink(1); } } //定义燃料燃烧的时间 public static int getItemBurnTime(ItemStack fuel) { if(fuel.isEmpty()) return 0; else { Item item = fuel.getItem(); // if (item instanceof ItemBlock && Block.getBlockFromItem(item) != Blocks.AIR) // { // Block block = Block.getBlockFromItem(item); // // if (block == Blocks.WOODEN_SLAB) return 150; // if (block.getDefaultState().getMaterial() == Material.WOOD) return 300; // if (block == Blocks.COAL_BLOCK) return 16000; // } // // if (item instanceof ItemTool && "WOOD".equals(((ItemTool)item).getToolMaterialName())) return 200; // if (item instanceof ItemSword && "WOOD".equals(((ItemSword)item).getToolMaterialName())) return 200; // if (item instanceof ItemHoe && "WOOD".equals(((ItemHoe)item).getMaterialName())) return 200; // if (item == Items.STICK) return 100; //我们设置燃料可以为煤炭、岩浆,你可以添加其他的东西成为燃料 if (item == Items.COAL) return 1600; if (item == Items.LAVA_BUCKET) return 20000; // if (item == Item.getItemFromBlock(Blocks.SAPLING)) return 100; // if (item == Items.BLAZE_ROD) return 2400; return GameRegistry.getFuelValue(fuel); } } public static boolean isItemFuel(ItemStack fuel) { return getItemBurnTime(fuel) > 0; } public boolean isUsableByPlayer(EntityPlayer player) { return this.world.getTileEntity(this.pos) != this ? false : player.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D; } public int getField(int id) { switch(id) { case 0: return this.burnTime; case 1: return this.currentBurnTime; case 2: return this.cookTime; case 3: return this.totalCookTime; default: return 0; } } public void setField(int id, int value) { switch(id) { case 0: this.burnTime = value; break; case 1: this.currentBurnTime = value; break; case 2: this.cookTime = value; break; case 3: this.totalCookTime = value; } } public int getCookTime(ItemStack stack) { return 200; } }在tileEntity包中新建一个BlockVirusGenerator方块类用于实现方块实体:
BlockVirusGenerator.java
package com.joy187.rejoymod.blocks.tileEntity.virusGenerator; import com.joy187.rejoymod.IdlFramework; import com.joy187.rejoymod.blocks.BlockBase; import com.joy187.rejoymod.blocks.ModBlocks; import com.joy187.rejoymod.gui.ModGuiElementLoader; import net.minecraft.block.BlockHorizontal; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.properties.PropertyDirection; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.*; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.block.state.BlockStateContainer; import java.util.Random; public class BlockVirusGenerator extends BlockBase { public static final PropertyDirection FACING = BlockHorizontal.FACING; //给机器增加一个燃烧的状态参数 public static final PropertyBool BURNING = PropertyBool.create("burning"); private static boolean keepInventory; public BlockVirusGenerator(String name) { super(name, Material.IRON); setSoundType(SoundType.METAL); this.setDefaultState(this.blockState.getBaseState().withProperty(FACING, EnumFacing.NORTH).withProperty(BURNING, false)); } @Override public Item getItemDropped(IBlockState state, Random rand, int fortune) { return Item.getItemFromBlock(ModBlocks.VIRUS_GENERATOR); } @Override public ItemStack getItem(World worldIn, BlockPos pos, IBlockState state) { return new ItemStack(ModBlocks.VIRUS_GENERATOR); } @Override public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { if(!worldIn.isRemote) { //点击方块显示我们的GUI playerIn.openGui(IdlFramework.instance, ModGuiElementLoader.GUI_VIRUS_GENERATOR, worldIn, pos.getX(), pos.getY(), pos.getZ()); } return true; } @Override public void onBlockAdded(World worldIn, BlockPos pos, IBlockState state) { if (!worldIn.isRemote) { IBlockState north = worldIn.getBlockState(pos.north()); IBlockState south = worldIn.getBlockState(pos.south()); IBlockState west = worldIn.getBlockState(pos.west()); IBlockState east = worldIn.getBlockState(pos.east()); EnumFacing face = (EnumFacing)state.getValue(FACING); if (face == EnumFacing.NORTH && north.isFullBlock() && !south.isFullBlock()) face = EnumFacing.SOUTH; else if (face == EnumFacing.SOUTH && south.isFullBlock() && !north.isFullBlock()) face = EnumFacing.NORTH; else if (face == EnumFacing.WEST && west.isFullBlock() && !east.isFullBlock()) face = EnumFacing.EAST; else if (face == EnumFacing.EAST && east.isFullBlock() && !west.isFullBlock()) face = EnumFacing.WEST; worldIn.setBlockState(pos, state.withProperty(FACING, face), 2); } } public static void setState(boolean active, World worldIn, BlockPos pos) { IBlockState state = worldIn.getBlockState(pos); TileEntity tileentity = worldIn.getTileEntity(pos); keepInventory = true; //如果机器在启动,就把机器设置为开启 if(active) worldIn.setBlockState(pos, ModBlocks.VIRUS_GENERATOR.getDefaultState().withProperty(FACING, state.getValue(FACING)).withProperty(BURNING, true), 3); else worldIn.setBlockState(pos, ModBlocks.VIRUS_GENERATOR.getDefaultState().withProperty(FACING, state.getValue(FACING)).withProperty(BURNING, false), 3); keepInventory = false; if(tileentity != null) { tileentity.validate(); worldIn.setTileEntity(pos, tileentity); } } @Override public boolean hasTileEntity(IBlockState state) { return true; } @Override public TileEntity createTileEntity(World world, IBlockState state) { return new TileEntityVirusGenerator(); } @Override public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) { return this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()); } @Override public void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { worldIn.setBlockState(pos, this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()), 2); } @Override public EnumBlockRenderType getRenderType(IBlockState state) { return EnumBlockRenderType.MODEL; } @Override public IBlockState withRotation(IBlockState state, Rotation rot) { return state.withProperty(FACING, rot.rotate((EnumFacing)state.getValue(FACING))); } @Override public IBlockState withMirror(IBlockState state, Mirror mirrorIn) { return state.withRotation(mirrorIn.toRotation((EnumFacing)state.getValue(FACING))); } @Override protected BlockStateContainer createBlockState() { return new BlockStateContainer(this, new IProperty[] {BURNING,FACING}); } @Override public IBlockState getStateFromMeta(int meta) { EnumFacing facing = EnumFacing.getFront(meta); if(facing.getAxis() == EnumFacing.Axis.Y) facing = EnumFacing.NORTH; return this.getDefaultState().withProperty(FACING, facing); } @Override public int getMetaFromState(IBlockState state) { return ((EnumFacing)state.getValue(FACING)).getIndex(); } //破坏机器,就把4个槽位的物品都弹出来 public void breakBlock(World worldIn, BlockPos pos, IBlockState state) { TileEntityVirusGenerator tileentity = (TileEntityVirusGenerator)worldIn.getTileEntity(pos); if(!keepInventory) { worldIn.spawnEntity(new EntityItem(worldIn, pos.getX(), pos.getY(), pos.getZ(), tileentity.handler.getStackInSlot(0))); worldIn.spawnEntity(new EntityItem(worldIn, pos.getX(), pos.getY(), pos.getZ(), tileentity.handler.getStackInSlot(1))); worldIn.spawnEntity(new EntityItem(worldIn, pos.getX(), pos.getY(), pos.getZ(), tileentity.handler.getStackInSlot(2))); worldIn.spawnEntity(new EntityItem(worldIn, pos.getX(), pos.getY(), pos.getZ(), tileentity.handler.getStackInSlot(3))); } tileentity.setField(0,0); tileentity.setField(1,0); tileentity.setField(2,0); tileentity.setField(3,200); super.breakBlock(worldIn, pos, state); } }在tileEntity包中新建一个TileEntityHandler类将我们所有的方块机器进行注册:
TileEntityHandler.java
import com.joy187.rejoymod.blocks.tileEntity.virusGenerator.TileEntityVirusGenerator; import com.joy187.rejoymod.util.Reference; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.common.registry.GameRegistry; public class TileEntityHandler { public static void registerTileEntities() { //GameRegistry.registerTileEntity(TileEntityCopperChest.class, new ResourceLocation(Reference.MODID + ":copper_chest")); GameRegistry.registerTileEntity(TileEntityVirusGenerator.class, new ResourceLocation(Reference.Mod_ID + ":virus_generator")); } }4.在gui包(没有就新建一个)中新建一个ModGuiElementLoader类:
ModGuiElementLoader.java
package com.joy187.rejoymod.gui; import com.joy187.rejoymod.IdlFramework; import com.joy187.rejoymod.blocks.tileEntity.virusGenerator.ContainerVirusGenerator; import com.joy187.rejoymod.blocks.tileEntity.virusGenerator.GuiVirusGenerator; import com.joy187.rejoymod.blocks.tileEntity.virusGenerator.TileEntityVirusGenerator; import com.joy187.rejoymod.gui.expOne.ContainerDemo; import com.joy187.rejoymod.gui.expOne.GuiContainerDemo; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.common.network.IGuiHandler; import net.minecraftforge.fml.common.network.NetworkRegistry; import javax.annotation.Nullable; public class ModGuiElementLoader implements IGuiHandler { //给模组中所有机器的GUI依次编号 public static final int GUI_VIRUS_GENERATOR = 1; public static final int GUI_DEMO = 2; public static final int GUI_RESEARCH = 3; public ModGuiElementLoader() { NetworkRegistry.INSTANCE.registerGuiHandler(IdlFramework.instance, this); } //sitch语句选择显示服务端的Container界面 @Nullable @Override public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { switch (ID) { case GUI_VIRUS_GENERATOR: return new ContainerVirusGenerator(player.inventory,(TileEntityVirusGenerator) world.getTileEntity(new BlockPos(x,y,z))); default: return null; } } //sitch语句选择显示客户端的Gui界面 @Nullable @Override public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { switch (ID) { case GUI_VIRUS_GENERATOR: return new GuiVirusGenerator(player.inventory,(TileEntityVirusGenerator) world.getTileEntity(new BlockPos(x,y,z))); default: return null; } } }5.给我们的机器添加其燃烧的配方,在tileEntity包中新建VirusGeneratorRecipes类:
VirusGeneratorRecipes.java
import com.google.common.collect.HashBasedTable; import com.google.common.collect.Maps; import com.google.common.collect.Table; import com.joy187.rejoymod.item.ModItems; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import java.util.Map; import java.util.Map.Entry; public class VirusGeneratorRecipes { private static final VirusGeneratorRecipes INSTANCE = new VirusGeneratorRecipes(); private final Table<ItemStack, ItemStack, ItemStack> smeltingList = HashBasedTable.<ItemStack, ItemStack, ItemStack>create(); private final Map<ItemStack, Float> experienceList = Maps.<ItemStack, Float>newHashMap(); public static VirusGeneratorRecipes getInstance() { return INSTANCE; } private VirusGeneratorRecipes() { //我们的配方一共3个物品:2个原料+1个产物 addGeneratorRecipe(new ItemStack(Items.ROTTEN_FLESH), new ItemStack(Items.GOLD_INGOT), new ItemStack(Items.NETHER_STAR), 5.0F); //addGeneratorRecipe(new ItemStack(Items.ROTTEN_FLESH), new ItemStack(Items.IRON_INGOT), new ItemStack(Items.DIAMOND), 5.0F); } public void addGeneratorRecipe(ItemStack input1, ItemStack input2, ItemStack result, float experience) { if(getSinteringResult(input1, input2) != ItemStack.EMPTY) return; this.smeltingList.put(input1, input2, result); this.experienceList.put(result, Float.valueOf(experience)); } public ItemStack getSinteringResult(ItemStack input1, ItemStack input2) { for(Entry<ItemStack, Map<ItemStack, ItemStack>> entry : this.smeltingList.columnMap().entrySet()) { if(this.compareItemStacks(input1, (ItemStack)entry.getKey())) { for(Entry<ItemStack, ItemStack> ent : entry.getValue().entrySet()) { if(this.compareItemStacks(input2, (ItemStack)ent.getKey())) { return (ItemStack)ent.getValue(); } } } } return ItemStack.EMPTY; } private boolean compareItemStacks(ItemStack stack1, ItemStack stack2) { return stack2.getItem() == stack1.getItem() && (stack2.getMetadata() == 32767 || stack2.getMetadata() == stack1.getMetadata()); } public Table<ItemStack, ItemStack, ItemStack> getDualSmeltingList() { return this.smeltingList; } public float getGeneratorExperience(ItemStack stack) { for (Entry<ItemStack, Float> entry : this.experienceList.entrySet()) { if(this.compareItemStacks(stack, (ItemStack)entry.getKey())) { return ((Float)entry.getValue()).floatValue(); } } return 0.2F; } }5.在Main.java的Init()中添加ModGuiElementLoader的初始化:
Main.java
@EventHandler public static void Init(FMLInitializationEvent event) { //ModRecipes.Init(); //RegisterTileEntity(); //initRegistries(event); //ModSpawn.registerSpawnList(); //添加GUI初始化 new ModGuiElementLoader(); //NetworkHandler.init(); //LogWarning("%s has finished its initializations", MODID); }6.在ModBlocks中声明我们的方块:
ModBlocks.java
public static final Block VIRUS_GENERATOR = new BlockVirusGenerator("virus_generator");在RegistryHandler.java中的onBlockRegister()中添加TileEntityHandler的注册语句:
@SubscribeEvent public static void onBlockRegister(RegistryEvent.Register<Block> event) { TileEntityHandler.registerTileEntities(); }7.Java包的代码部分结束,找到resources包:
在en_us.lang中添加机器方块的名称:
container.virus_generator=Virus Analyser tile.virus_generator.name=Virus Analyser在blockstates包中新建virus_generator.json用于表示机器的不同形态下的模型
virus_generator.json
{ "variants": { "burning=false,facing=north": { "model": "rejoymod:virus_generator" }, "burning=false,facing=east": { "model": "rejoymod:virus_generator", "y": 90 }, "burning=false,facing=south": { "model": "rejoymod:virus_generator", "y": 180 }, "burning=false,facing=west": { "model": "rejoymod:virus_generator", "y": 270 }, "burning=true,facing=north": { "model": "rejoymod:virus_generator_li" }, "burning=true,facing=east": { "model": "rejoymod:virus_generator_li", "y": 90 }, "burning=true,facing=south": { "model": "rejoymod:virus_generator_li", "y": 180 }, "burning=true,facing=west": { "model": "rejoymod:virus_generator_li", "y":270 } } }在models/block包中新建virus_generator.json,显示机器的模型贴图地址
virus_generator.json
{ "parent": "block/orientable", "textures": { "top": "rejoymod:blocks/sintering_furnace_side", "front": "rejoymod:blocks/sintering_furnace_front_off", "side": "rejoymod:blocks/sintering_furnace_side" } }同时需要制作方块工作时的模型贴图文件:
virus_generator_li.json
在models/item包中新建virus_generator.json,显示手拿机器的模型
virus_generator.json
{ "parent": "rejoymod:block/virus_generator" }在textures/blocks包中添加我们机器的3个贴图(一个为机器四周贴图,一个为机器关闭时贴图,一个为机器运作贴图):
8.保存所有文件 -> 运行游戏
首先拿出我们的机器并放置下来,外观显示正常
第5步中我们的反应器的一个配方为燃料+腐肉+金锭 ->下界之星,我们分别把东西摆进机器:
的确可以产出我们想要的东西,燃料和原料也都正常的消耗了。
同时我们发现在反应器工作时,机器同样显示为工作时的贴图:
本次用到的GUI界面(保存为.png格式,可根据PS软件进行修改):