说到方块实体(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));}}@Overridepublic 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);}@Overridepublic boolean canInteractWith(EntityPlayer playerIn){return this.tileentity.isUsableByPlayer(playerIn);}@Overridepublic 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界面的路径传给TEXTURESprivate 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;}@Overrideprotected 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界面@Overrideprotected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY){GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);this.mc.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;//默认烧好一个物品的时间是200tickprivate int totalCookTime = 200;@Overridepublic boolean hasCapability(Capability<?> capability, EnumFacing facing){if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return true;else return false;}@Overridepublic <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;}@Overridepublic ITextComponent getDisplayName(){return this.hasCustomName() ? new TextComponentString(this.customName) : new TextComponentTranslation("container.virus_generator");}//因为我们一共有四个参数(burnTime、cookTime、totalCookTime、currentBurnTime),都要加入NBT标签@Overridepublic 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"));}@Overridepublic 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));}@Overridepublic Item getItemDropped(IBlockState state, Random rand, int fortune){return Item.getItemFromBlock(ModBlocks.VIRUS_GENERATOR);}@Overridepublic ItemStack getItem(World worldIn, BlockPos pos, IBlockState state){return new ItemStack(ModBlocks.VIRUS_GENERATOR);}@Overridepublic boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ){if(!worldIn.isRemote){//点击方块显示我们的GUIplayerIn.openGui(IdlFramework.instance, ModGuiElementLoader.GUI_VIRUS_GENERATOR, worldIn, pos.getX(), pos.getY(), pos.getZ());}return true;}@Overridepublic 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);}}@Overridepublic boolean hasTileEntity(IBlockState state){return true;}@Overridepublic TileEntity createTileEntity(World world, IBlockState state){return new TileEntityVirusGenerator();}@Overridepublic 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());}@Overridepublic void onBlockPlacedBy(World worldIn, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack){worldIn.setBlockState(pos, this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()), 2);}@Overridepublic EnumBlockRenderType getRenderType(IBlockState state){return EnumBlockRenderType.MODEL;}@Overridepublic IBlockState withRotation(IBlockState state, Rotation rot){return state.withProperty(FACING, rot.rotate((EnumFacing)state.getValue(FACING)));}@Overridepublic IBlockState withMirror(IBlockState state, Mirror mirrorIn){return state.withRotation(mirrorIn.toRotation((EnumFacing)state.getValue(FACING)));}@Overrideprotected BlockStateContainer createBlockState(){return new BlockStateContainer(this, new IProperty[] {BURNING,FACING});}@Overridepublic IBlockState getStateFromMeta(int meta){EnumFacing facing = EnumFacing.getFront(meta);if(facing.getAxis() == EnumFacing.Axis.Y) facing = EnumFacing.NORTH;return this.getDefaultState().withProperty(FACING, facing);}@Overridepublic 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@Overridepublic 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@Overridepublic 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

    @EventHandlerpublic 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的注册语句:

 @SubscribeEventpublic 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

{"parent": "block/orientable","textures": {"top": "rejoymod:blocks/sintering_furnace_side","front": "rejoymod:blocks/sintering_furnace_front_on","side": "rejoymod:blocks/sintering_furnace_side"}
}

在models/item包中新建virus_generator.json,显示手拿机器的模型

virus_generator.json

{"parent": "rejoymod:block/virus_generator"
}

在textures/blocks包中添加我们机器的3个贴图(一个为机器四周贴图,一个为机器关闭时贴图,一个为机器运作贴图):

8.保存所有文件 -> 运行游戏

首先拿出我们的机器并放置下来,外观显示正常

第5步中我们的反应器的一个配方为燃料+腐肉+金锭 ->下界之星,我们分别把东西摆进机器:


的确可以产出我们想要的东西,燃料和原料也都正常的消耗了。

同时我们发现在反应器工作时,机器同样显示为工作时的贴图:

本次用到的GUI界面(保存为.png格式,可根据PS软件进行修改):

Minecraft 1.12.2模组开发(三十九) 反应器(TileEntity方块实体)相关推荐

  1. Minecraft 1.16.5模组开发(三十二) 自定义投掷物品实体

    如果你了解过之前我们的实体开发教程,那么本次的教程会相对比较好理解. Minecraft 1.12.2模组开发(七) 实体(魔改Zombie) 我们本次将参考雪球在MC中制作一个属于我们自己的可投掷实 ...

  2. Minecraft 1.12.2模组开发(四十九) 维度空间

    1.18.2维度空间教程 1.16.5维度空间教程 我们今天在1.12.2的模组中实现一个自定义维度的生成: 1.在Java包的init包中新建一个InitDimension类注册我们所有的维度: I ...

  3. Minecraft 1.16.5模组开发(三十八) 3D盔甲(新)

    Minecraft升级到1.16.5后,3D盔甲的制作方法也跟之前版本稍有不同(主要在第二步.第四步),建议先复习一下往期教程: Minecraft 1.12.2模组开发(三十七) 3D盔甲 1.在b ...

  4. Minecraft 1.12.2模组开发(二十) 导出模组

    模组制作完成后,我们就可以将其导出成为.jar文件,进行发布,供全世界的玩家进行下载游玩了 1.进入模组开发的文件夹 -> 起动cmd控制台 2.输入构建指令等待其构建模组 Windows系统: ...

  5. Minecraft 1.12.2模组开发(三) 创建一个物品(item)+物品栏

    本次我们来介绍一下如何创建一个基础物品: 演示包名:com.Joy187.newmod (之后都简称为包名) 1. 新建 -> 创建一个 包名.init 包 2.在刚刚创建的init包中新建一个 ...

  6. Minecraft 1.12.2模组开发(四十) buff效果(Potion Effect)

    今天我们在1.12.2的模组中尝试实现几种特殊的buff效果 1.在开发包中新建potion包 -> potion包中新建一个BaseSimplePotion类作为我们药水效果的基类: Base ...

  7. Minecraft 1.16.5模组开发(三十) 自定义成就系统(advancements)

    我们本次将尝试在模组中加入属于自己的成就系统 1.打开Minecraft成就生成制作网站进行成就的制作 我的世界成就系统制作网站 在data包下新建advancement文件夹 -> 在文件夹中 ...

  8. Minecraft 1.12.2模组开发(四十五) 水火两用船

    今天我们在MC中实现一艘可以在水中和岩浆中滑行的船 本期教程之前可以先复习一下生物实体教程,会比较好理解一些. 1.船是一种生物实体,所以我们首先要制作船的模型,这里直接使用了原版的船模型,当然你也可 ...

  9. Minecraft 1.16.5模组开发(三十四) 自定义载具

    想在MC中开车吗?今天我们在MC中制作一辆车. 由于车辆是一个生物实体,所以要首先了解MC中的实体:我的世界实体教程 1.首先我们要制作一个车辆实体的模型(blockbench) 下载地址: 将模型导 ...

最新文章

  1. verycd重整——linux教程
  2. 使用游戏测试干式EEG传感器的有效性
  3. 437. Path Sum III
  4. C++ Primer 5th笔记(chap 19 特殊工具与技术)将成员函数用作可调用对象
  5. 物联网推动时代进步 中小玩家如何傍上运营商这棵大树
  6. 动态控制jQuery easyui datagrid工具栏显示隐藏
  7. 用PowerDesigner工具条不见的
  8. TCP服务器端和客户端建立连接 - 服务器端的回调处理
  9. 人脸注册源码faceregiste
  10. java 命令行读取_Java:从控制台(console,命令行)读取字符 | 学步园
  11. STM32H743+Keil-将变量定义到指定内存
  12. Linux Apache服务详解——Apache服务访问控制
  13. 4.深入分布式缓存:从原理到实践 --- Ehcache 与 Guava Cache
  14. 海量数据处理--大数据处理概论
  15. C语言学习教程免费分享
  16. 微信会员系统的具体操作流程,怎么使用微信会员卡管理系统制作 button onclick=myFunction()
  17. 该如何在中国手机市场生存
  18. 我的25年嵌入式生涯-周立功
  19. html页面实现图片滚动
  20. java 向word中添加excel附件并向excel单元格中加入图片并压缩图片并根据图片动态控制单元格高度宽度

热门文章

  1. LeetCode——1824. 最少侧跳次数(Minimum Sideway Jumps)[中等]——分析及代码(Java)
  2. 【个人网站搭建】GitHub pages+hexo框架下为next主题添加分类及标签
  3. 阿联酋和沙特阿拉伯就加密货币展开合作
  4. 大数据学习日志tenth
  5. Linux进程同步之POSIX信号量
  6. 威盾IIS防火墙升级到V3.7
  7. Anaconda,启动中发生意外的错误
  8. 胡萝卜周博客 软件下载
  9. 从零开始学Pyqt5之【控件介绍】(15):绘图类控件QPainter、QPen、QBrush、QPixMap
  10. Ubuntu制作本地软件源