Туториал по созданию своего GUI средствами ModLoader`a

exphines

ʏᴏᴜ ᴀɪɴ'ᴛ ᴋᴀᴡᴀɪɪ
В данной статье я расскажу как создать свой GUI интерфейс в minecraft 1.2.5-1.4.2
Давайте напишим простой интерфейс по нажатию кнопки которого будет спауниться 1 слизя.
Для начала пропишем хуки в основном файле мода (mod_***.java)
Для этого в начало public void load допишем:
Код:
loader.setInGameHook(this, true, true);
loader.setInGUIHook(this, true, true);
чтобы получилось вот так:
Код:
public void load(){
    loader.setInGameHook(this, true, true);
    loader.setInGUIHook(this, true, true);
 
    // -----------
    // Регистрация блоков, предметов и т.д.
    // -----------
 
}
Теперь создадим наш заветный Gui***.java
В его основу копипастнем это:
Код:
package net.minecraft.src;
 
import org.lwjgl.input.Keyboard;
 
import net.minecraft.client.Minecraft;
 
public class GUI*** extends GuiContainer
{
    private World worldObj;
    private EntityPlayer playerObj;
 
    public GUI***(World world, EntityPlayer player)
    {
        super(new Container***(player));
        worldObj = world;
        playerObj = player;
    }
 
    public void initGui()
    { 
        super.initGui();
    }
 
    public void actionPerformed(GuiButton button)
    {
 
        super.actionPerformed(button);
    }
 
 
    protected void drawGuiContainerBackgroundLayer(float var1, int var2, int var3)
    {
 
    }
 
    protected void drawGuiContainerForegroundLayer()
    {
 
    }
 
            public void onGuiClosed()
            {
                super.onGuiClosed();
            }
 
    protected void mouseClicked(int par1, int par2, int par3)
    {
            if (Keyboard.isKeyDown(42)==false & Keyboard.isKeyDown(54)==false)
        {
                super.mouseClicked(par1, par2, par3);
                }
    }
}
В этом файле мы будет выводить графические данные. Теперь нужно создать еще один файл (Container***.java) отвечающий за слоты GUI (Если слотов нету то оставте все как есть)
Код:
package net.minecraft.src;
 
public class Container*** extends Container
{
    public Container***(EntityPlayer player)
    {
 
    }
 
    public boolean canInteractWith(EntityPlayer entityplayer)
    {
        return true;
    }
}
В игре GUI игроку показывает данная комманда:
Код:
ModLoader.openGUI(player, new GUIExampleGUI(world, player));
У меня она стоит в событии активации блока игроком (В файле настроек вашего блока Block***.java)
Код:
public boolean blockActivated(World world, int x, int y, int z, EntityPlayer player)
{
    ModLoader.openGUI(player, new GUIExampleGUI(world, player));
    return false;
}
Теперь уже можно и скомпилировать наш мод. Главное не забудте поменять все звездочки в именах файлов на свои названия. Но кликнув в игре по блоку мы видим что игрок не может двигаться как будто он в инвентаре, но и GUI не видно. Сей час мы это исправим. Приготовте паинт или фотошоп! Будем рисовать на GUI.

Важно: За основу лучше взять стандартный гуи и перерисовать его под себя. Он должен быть 256х256 пикселей в формате png. Если гуи меньше, то он должен находиться в левом верхнем углу.

Нарисовали? Теперь пихайте нашу картинку в minecraft.jar и в файле Gui***.java в
Код:
protected void drawGuiContainerBackgroundLayer
вписываем:
Код:
        int img = this.mc.renderEngine.getTexture("/guitemp.png"); // Загружаем текстуру в память
        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); // Устанавливаем дефолт цвет
        this.mc.renderEngine.bindTexture(img); // Биндим текстуру
        int varx = (this.width - 176) / 2; // Устанавливаем текстуру по центру экрана. 176 - ваша ширена GUI
        int vary = (this.height - 166) / 2; // 166 - ваша высота GUI
        this.drawTexturedModalRect(varx, vary, 0, 0, 176, 166); // Отрисовуем текстуру в координатах (varx,vary) шириной 176 и высотой 166
Компилим, видим, что теперь видна наша текстура, но взаимодействовать с инвентарем мы не можем. Но это тоже не проблема. Для начала добавим кнопу и зададим ей действие.
Для этого в файле Gui***.java в
Код:
public void initGui()
после
Код:
super.initGui();
пишем:
Код:
  controlList.clear(); // очищаем старые компоненты
        controlList.add(new GuiButton(0, (this.width - 176) / 2 + 95, (this.height - 166) / 2 + 60 ,75,20, "Spawn Slime")); // добавляем кнопку
Первой коммандой мы чистим старые компоненты, а второй добавляем одну кнопку. Первый параметр (0) - это ID кнопки в списке компонентов, Второй ( (this.width - 176) / 2 + 95 )- координата x кнопки, Третий параметр аналогично второму, Четвертый - надпись на кнопке.

Теперь добавляем действие кнопке. За это отвечает
Код:
public void actionPerformed
Думаю тут сами розберетесь:
Код:
  public void actionPerformed(GuiButton button)
 
    {
 
 
 
        super.actionPerformed(button);
 
 
 
        if (button.id==0)
 
        {
 
            EntitySlime entityslime = new EntitySlime(worldObj);
 
            entityslime.setLocationAndAngles(playerObj.posX, playerObj.posY+1, playerObj.posZ, 0.0F, 0.0F);
 
            worldObj.spawnEntityInWorld(entityslime);
 
        }
 
    }
Компилим и смотрим. Теперь при нажатии кнопки будет спаунится слизень.

Важно: слизень не будет спауниться, если игровой режим стоит на мирном, поскольку он является враждующим мобом.

Так же возможно вы заметили, что я нарисовал в GUI клеточки инвентаря, но предметы в них не появляются. Чтобы это исправить открывем Container***.java и в
Код:
public ContainerExampleGUI(EntityPlayer player)
вписываем:
Код:
    for (int j = 0; j < 3; j++)
 
        {
 
            for (int i1 = 0; i1 < 9; i1++)
 
            {
 
                addSlot(new Slot(player.inventory, i1 + j * 9 + 9, 8 + i1 * 18, 84 + j * 18));
 
            }
 
        }
 
 
 
        for (int k = 0; k < 9; k++)
 
        {
 
            addSlot(new Slot(player.inventory, k, 8 + k * 18, 142));
 
        }
Это добавит нам нужные слоты, а в конец Container***.java добавляем:
Код:
public ItemStack transferStackInSlot(int par1)
 
    {
 
        ItemStack itemstack = null;
 
        Slot slot = (Slot)inventorySlots.get(par1);
 
 
 
        if (slot != null && slot.getHasStack())
 
        {
 
            ItemStack itemstack1 = slot.getStack();
 
            itemstack = itemstack1.copy();
 
 
 
            if (par1 < 9)
 
            {
 
                if (!mergeItemStack(itemstack1, 9, 45, true))
 
                {
 
                    return null;
 
                }
 
            }
 
            else if (!mergeItemStack(itemstack1, 0, 9, false))
 
            {
 
                return null;
 
            }
 
 
 
            if (itemstack1.stackSize == 0)
 
            {
 
                slot.putStack(null);
 
            }
 
            else
 
            {
 
                slot.onSlotChanged();
 
            }
 
 
 
            if (itemstack1.stackSize != itemstack.stackSize)
 
            {
 
                slot.onPickupFromSlot(itemstack1);
 
            }
 
            else
 
            {
 
                return null;
 
            }
 
        }
 
 
 
        return itemstack;
 
    }
Этот кусок кода отвечает за перемещение предметов между слотами. Его трогать не нужно.

Все, на этом мой тутор окончен. Спасибо за внимание!


Не обращайте внимания на ошибки, создатель этого тутора не очень уж и грамотен.


ОК, извиняюсь)
 
Сверху