如何系统地向 Minecraft GUI 容器添加插槽
How to Systematically Add Slots to a Minecraft GUI Container
我使用 Minecraft Forge 创建了一个新的 Tile 实体。
这是一个简单的箱子,有 81 个插槽(9 行,9 列)。
基本上,我需要创建一个 x 和一个 y 坐标。
i的每个间隔,将SLOT_X_SPACING
添加到x坐标,但在9个间隔后重置为0。
i的每9个区间,我需要在SLOT_Y_SPACING
.
上加18
如何将这些 For
循环重新排列成一个循环?
(我觉得我的整个容器 class 是必要的,因为仅仅 for 循环是不够的信息)
public class ModDrawerContainer extends Container {
private ModTileEntityDrawer tileEntityInventoryBasic;
private final int HOTBAR_SLOT_COUNT = 9;
private final int PLAYER_INVENTORY_ROW_COUNT = 3;
private final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
private final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
private final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
private final int VANILLA_FIRST_SLOT_INDEX = 0;
private final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
private final int TE_INVENTORY_SLOT_COUNT = 81;
public ModDrawerContainer(InventoryPlayer invPlayer, ModTileEntityDrawer tileEntityInventoryBasic) {
this.tileEntityInventoryBasic = tileEntityInventoryBasic;
final int SLOT_X_SPACING = 18;
final int SLOT_Y_SPACING = 18;
final int HOTBAR_XPOS = 12;
final int HOTBAR_YPOS = 232;
for (int x = 0; x < HOTBAR_SLOT_COUNT; x++) {
int slotNumber = x;
addSlotToContainer(new Slot(invPlayer, slotNumber, HOTBAR_XPOS + SLOT_X_SPACING * x, HOTBAR_YPOS));
}
final int PLAYER_INVENTORY_XPOS = 12;
final int PLAYER_INVENTORY_YPOS = 174;
for (int y = 0; y < PLAYER_INVENTORY_ROW_COUNT; y++) {
for (int x = 0; x < PLAYER_INVENTORY_COLUMN_COUNT; x++) {
int slotNumber = HOTBAR_SLOT_COUNT + y * PLAYER_INVENTORY_COLUMN_COUNT + x;
int xpos = PLAYER_INVENTORY_XPOS + x * SLOT_X_SPACING;
int ypos = PLAYER_INVENTORY_YPOS + y * SLOT_Y_SPACING;
addSlotToContainer(new Slot(invPlayer, slotNumber, xpos, ypos));
}
}
if (TE_INVENTORY_SLOT_COUNT != tileEntityInventoryBasic.getSizeInventory()) {
System.err.println("Mismatched slot count in ContainerBasic(" + TE_INVENTORY_SLOT_COUNT
+ ") and TileInventory (" + tileEntityInventoryBasic.getSizeInventory()+")");
}
final int TILE_INVENTORY_XPOS = 12;
int TILE_INVENTORY_YPOS = 8;
for (int i = 0; i < 9; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * i, TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *1;
for (int i = 9; i < 18; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-9), TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *2;
for (int i = 18; i < 27; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-18), TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *3;
for (int i = 27; i < 36; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-27), TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *4;
for (int i = 36; i < 45; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-36), TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *5;
for (int i = 45; i < 54; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-45), TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *6;
for (int i = 54; i < 63; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-54), TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *7;
for (int i =63; i < 72; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-63), TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *8;
for (int i = 73; i < 81; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-72), TILE_INVENTORY_YPOS));
}
}
@Override
public boolean canInteractWith(EntityPlayer player)
{
return tileEntityInventoryBasic.isUseableByPlayer(player);
}
@Override
public ItemStack transferStackInSlot(EntityPlayer player, int sourceSlotIndex)
{
Slot sourceSlot = (Slot)inventorySlots.get(sourceSlotIndex);
if (sourceSlot == null || !sourceSlot.getHasStack()) return null;
ItemStack sourceStack = sourceSlot.getStack();
ItemStack copyOfSourceStack = sourceStack.copy();
if (sourceSlotIndex >= VANILLA_FIRST_SLOT_INDEX && sourceSlotIndex < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
if (!mergeItemStack(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT, false)){
return null;
}
} else if (sourceSlotIndex >= TE_INVENTORY_FIRST_SLOT_INDEX && sourceSlotIndex < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
if (!mergeItemStack(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
return null;
}
} else {
System.err.print("Invalid slotIndex:" + sourceSlotIndex);
return null;
}
if (sourceStack.stackSize == 0) {
sourceSlot.putStack(null);
} else {
sourceSlot.onSlotChanged();
}
sourceSlot.onPickupFromSlot(player, sourceStack);
return copyOfSourceStack;
}
@Override
public void onContainerClosed(EntityPlayer playerIn)
{
super.onContainerClosed(playerIn);
this.tileEntityInventoryBasic.closeInventory(playerIn);
}
}
这是一张库存图片,您可以直观地看到发生了什么:
对于水平位置,可以使用取模运算符(%
)得到除以9的余数,这样就可以了。 i % 9
将始终 return 一个从 0 到 8 的值。为此你会使用 TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i % 9)
.
对于垂直位置,您可以简单地使用除法来获取行 - i / 9
将是当前行。因此,要获得该位置,您将使用 8 + 18 * (i / 9)
.
将两者放在一起并在循环中使用 slotNumber
而不是 i
会产生以下结果:
final int TILE_INVENTORY_XPOS = 12;
final int TILE_INVENTORY_YPOS = 8;
for (int slotNumber = 0; slotNumber < TE_INVENTORY_SLOT_COUNT; slotNumber++) {
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber,
TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i % 9),
TILE_INVENTORY_YPOS + SLOT_Y_SPACING * (i / 9)));
}
我使用 Minecraft Forge 创建了一个新的 Tile 实体。
这是一个简单的箱子,有 81 个插槽(9 行,9 列)。
基本上,我需要创建一个 x 和一个 y 坐标。
i的每个间隔,将SLOT_X_SPACING
添加到x坐标,但在9个间隔后重置为0。
i的每9个区间,我需要在SLOT_Y_SPACING
.
上加18
如何将这些 For
循环重新排列成一个循环?
(我觉得我的整个容器 class 是必要的,因为仅仅 for 循环是不够的信息)
public class ModDrawerContainer extends Container {
private ModTileEntityDrawer tileEntityInventoryBasic;
private final int HOTBAR_SLOT_COUNT = 9;
private final int PLAYER_INVENTORY_ROW_COUNT = 3;
private final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
private final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
private final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
private final int VANILLA_FIRST_SLOT_INDEX = 0;
private final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
private final int TE_INVENTORY_SLOT_COUNT = 81;
public ModDrawerContainer(InventoryPlayer invPlayer, ModTileEntityDrawer tileEntityInventoryBasic) {
this.tileEntityInventoryBasic = tileEntityInventoryBasic;
final int SLOT_X_SPACING = 18;
final int SLOT_Y_SPACING = 18;
final int HOTBAR_XPOS = 12;
final int HOTBAR_YPOS = 232;
for (int x = 0; x < HOTBAR_SLOT_COUNT; x++) {
int slotNumber = x;
addSlotToContainer(new Slot(invPlayer, slotNumber, HOTBAR_XPOS + SLOT_X_SPACING * x, HOTBAR_YPOS));
}
final int PLAYER_INVENTORY_XPOS = 12;
final int PLAYER_INVENTORY_YPOS = 174;
for (int y = 0; y < PLAYER_INVENTORY_ROW_COUNT; y++) {
for (int x = 0; x < PLAYER_INVENTORY_COLUMN_COUNT; x++) {
int slotNumber = HOTBAR_SLOT_COUNT + y * PLAYER_INVENTORY_COLUMN_COUNT + x;
int xpos = PLAYER_INVENTORY_XPOS + x * SLOT_X_SPACING;
int ypos = PLAYER_INVENTORY_YPOS + y * SLOT_Y_SPACING;
addSlotToContainer(new Slot(invPlayer, slotNumber, xpos, ypos));
}
}
if (TE_INVENTORY_SLOT_COUNT != tileEntityInventoryBasic.getSizeInventory()) {
System.err.println("Mismatched slot count in ContainerBasic(" + TE_INVENTORY_SLOT_COUNT
+ ") and TileInventory (" + tileEntityInventoryBasic.getSizeInventory()+")");
}
final int TILE_INVENTORY_XPOS = 12;
int TILE_INVENTORY_YPOS = 8;
for (int i = 0; i < 9; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * i, TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *1;
for (int i = 9; i < 18; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-9), TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *2;
for (int i = 18; i < 27; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-18), TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *3;
for (int i = 27; i < 36; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-27), TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *4;
for (int i = 36; i < 45; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-36), TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *5;
for (int i = 45; i < 54; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-45), TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *6;
for (int i = 54; i < 63; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-54), TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *7;
for (int i =63; i < 72; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-63), TILE_INVENTORY_YPOS));
}
TILE_INVENTORY_YPOS = 8 + 18 *8;
for (int i = 73; i < 81; i++) {
int slotNumber = i;
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber, TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i-72), TILE_INVENTORY_YPOS));
}
}
@Override
public boolean canInteractWith(EntityPlayer player)
{
return tileEntityInventoryBasic.isUseableByPlayer(player);
}
@Override
public ItemStack transferStackInSlot(EntityPlayer player, int sourceSlotIndex)
{
Slot sourceSlot = (Slot)inventorySlots.get(sourceSlotIndex);
if (sourceSlot == null || !sourceSlot.getHasStack()) return null;
ItemStack sourceStack = sourceSlot.getStack();
ItemStack copyOfSourceStack = sourceStack.copy();
if (sourceSlotIndex >= VANILLA_FIRST_SLOT_INDEX && sourceSlotIndex < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
if (!mergeItemStack(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT, false)){
return null;
}
} else if (sourceSlotIndex >= TE_INVENTORY_FIRST_SLOT_INDEX && sourceSlotIndex < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
if (!mergeItemStack(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
return null;
}
} else {
System.err.print("Invalid slotIndex:" + sourceSlotIndex);
return null;
}
if (sourceStack.stackSize == 0) {
sourceSlot.putStack(null);
} else {
sourceSlot.onSlotChanged();
}
sourceSlot.onPickupFromSlot(player, sourceStack);
return copyOfSourceStack;
}
@Override
public void onContainerClosed(EntityPlayer playerIn)
{
super.onContainerClosed(playerIn);
this.tileEntityInventoryBasic.closeInventory(playerIn);
}
}
这是一张库存图片,您可以直观地看到发生了什么:
对于水平位置,可以使用取模运算符(%
)得到除以9的余数,这样就可以了。 i % 9
将始终 return 一个从 0 到 8 的值。为此你会使用 TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i % 9)
.
对于垂直位置,您可以简单地使用除法来获取行 - i / 9
将是当前行。因此,要获得该位置,您将使用 8 + 18 * (i / 9)
.
将两者放在一起并在循环中使用 slotNumber
而不是 i
会产生以下结果:
final int TILE_INVENTORY_XPOS = 12;
final int TILE_INVENTORY_YPOS = 8;
for (int slotNumber = 0; slotNumber < TE_INVENTORY_SLOT_COUNT; slotNumber++) {
addSlotToContainer(new Slot(tileEntityInventoryBasic, slotNumber,
TILE_INVENTORY_XPOS + SLOT_X_SPACING * (i % 9),
TILE_INVENTORY_YPOS + SLOT_Y_SPACING * (i / 9)));
}