A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Cancel Create
mc-modding-book / book / 1.11+ / forge / gui / custom_inventory / article.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cannot retrieve contributors at this time
1110 lines (833 sloc) 48.5 KB
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents Copy raw contents
Copy raw contents
Создание своего инвентаря
Рабочий тестовый мод с материалами данной статьи можно скачать здесь.
Туториал предполагает что вы знакомы с использованием прокси и умеете общаться с CAP`ой на уровне жестов(если не умеете то будем учить), а как отправлять пакеты постараюсь пояснить:)
КАК СДЕЛАТЬ АНИМИРОВАННЫЙ ИНВЕНТАРЬ в МАЙНКРАФТ на VIMEWORLD | АНИМИРОВАННЫЙ ИНВЕНТАРЬ для МАЙНКРАФТ
Мы будем создавать вот такой инвентарь:
Это будет отдельный инвентарь(т.е. он не будет перекрывать обычный), который мы сможем открыть по нажатию созданной нами в дальнейшем кнопки Н. Для повышения совместимости кнопку сделаем так, что ее можно будет поменять в настройках управления на другую, таким образом любой пользователь сможет настроить все как ему удобно.
Нам нужно создать четыре «базовых» для нашего инвентаря класса:
- CustomInventory.java — класс который будет управлять содержимым инвентаря, например: хранение, сохранение и восстановление инвентаря, управление предметами и т.д..
- ContainerCustomInv,java — контейнер. В нем будут добавляться слоты и описываться механика перетаскивания предметов из слота в слот при шифт-клике на них.
- StandartSlot.java — кастомные слоты, которые будем добавлять в контейнер. Хотя можно использовать и ванильные, но заодно покажу как использовать свои.
- GUICustomInv.java — то, как будет выглядеть инвентарь(бинд текстуры и прочее).
Для того, чтоб вы не путались с индексами слотов когда будете делать или менять контейнер, я прикреплю такую картинку в помощь. На ней все слоты промаркированные:
Теперь нужно настроить контейнер:
Если вы хотите добавить, либо убрать слот, то нужно не забыть уменьшить или увеличить размер списка, в котором хранятся предметы(CustomInventory.java -> INV_SIZE). Так же не забудьте поправить индексы в методе transferStackInSlot , что в классе ContainerCustomInv . Если этого не сделать, то пойдут краши, такие как выход за пределы массива( ArrayIndexOutOfBoundsException ) и прочие.
КАК САМОМУ СДЕЛАТЬ АНИМИРОВАННЫЙ ИНВЕНТАРЬ ИЗ ЛЮБОГО ВИДЕО В МАЙНКРАФТЕ! ОТВЕТ ЗДЕСЬ!
Пару слов о том, как ориентироваться в размещении слотов. Слоты, которые мы добавляем в инвентарь стандартного размера(16 x 16). Когда добавляем слот( this.addSlotToContainer(new StandartSlot(player, cInventory, 0, x, y) ), указываем x и y координаты, на которых этот слот будет размещен. В качестве центра выступает левый верхний угол слота. Думаю, понятнее будет, если посмотреть на картинку ниже:
Как видно на картинке, желтые точки это точки с координатами x и y, которые указывались при добавлении слота. Красным отмечен контур слота и как он располагается относительно указанной точки. Здесь я добавил два слота, с координатами x = 0, y = 0 и x = 87, y = 8.
Осталось только GUI:
Есть. Теперь где-то надо это все хранить. Ибо мало того, что мы просто добавим инвентарь. При первом же перезаходе игрока в мир все вещи пропадут. Для этого будем использовать такую штуку как КАПа, или Capability . Это замена IExtendedEntityProperties для новых версий.
- ICAPCustomInventory.java — интерфейс, в котором опишем основные методы для взаимодействия КАПы с инвентарем.
- CAPCustomInventory.java — класс, реализующий данный интерфейс. Так же в нем будет хранится обьект нашего инвентаря — CustomInventory.
- CAPCustomInventoryProvider.java — в нем располагаются методы для доступа к КАПе а так же проводится вызов методов чтения и сохранения (десериализации и сериализации). Вызов этих методов — это по сути вызов методов writeNBT и readNBT из класса CAPCustomInventoryStorage , функционал которого описан пунктом ниже.
- CAPCustomInventoryStorage.java — в этом классе есть всего два метода: writeNBT и readNBT . Мы должны описать в них то, что и как будет записываться и читаться в/из НБТ. Под записью и чтением в/из НБТ подразумевается сохранение нужной нам информации например при выходе игрока из игры, и ее считывание(загрузка), когда игрок заходит обратно в игру. Наши вещи будут в безопасности:)
// ICAPCustomInventory.java package com.example.test; public interface ICAPCustomInventory < public void copyInventory(ICAPCustomInventory inventory); public CustomInventory getInventory(); >
Готово. Нужно зарегистрировать КАПу. Пишем в коммон прокси в инит стадии:
// CommonProxy.java CapabilityManager.INSTANCE.register(ICAPCustomInventory.class, new CAPCustomInventoryStorage(), CAPCustomInventory.class); CapabilityEventHandler.
register();
Для чего CapabilityEventHandler.register(); ? При создании игрока нужно ему добавить КАПу. Для этого создаем класс CapabilityEventHandler.java и добавляем в него:
Пример того, как через КАПу получить доступ к нашему инвентарю:
//Достаем КАПу, затем инвентарь EntityPlayer player = . ;//Любым способом достать игрока ICAPCustomInventory cap = player.getCapability(CAPCustomInventoryProvider.INVENTORY_CAP, null); CustomInventory inv = cap.getInventory();
Клавиша на клавиатуре
Такс. Инвентарь есть, КАПа для хранения есть. Теперь самое интересное. Создадим свой кей бинд(т.е. забиндим кнопку), при нажатии на который будем посылать пакет на сервер с просьбой открыть наш GUI-контейнер(инвентарь). Для этого делаем класс KeyHandler.java, в котором ловим событие нажатии кнопки и отправляем пакет:
Обязательно регаем все это дело в клиент прокси (в ините например):
KeyHandler.register();
Позже в настройках(когда доделаем все и запустим) получим что-то типа такого:
В коде выше будут ошибки. Будет ругаться на NetworkHandler.network.sendToServer(new OpenInventoryMessage()); . Это какраз и есть отправка пакетов. Чтобы это работало нужно:
- Создать класс NetworkHandler.java, в котором зарегистрируем наш пакет.
- Создать класс OpenInventoryMessage.java — это сам пакет а так же в нем есть вложенный класс-обработчик пакета. Он реализует метод onMessage, который срабатывает когда пакет приходит на сервер(в данном случае).
// NetworkHandler.java package com.example.test; import net.minecraftforge.fml.
common.network.NetworkRegistry; import net.minecraftforge.fml.
common.network.simpleimpl.SimpleNetworkWrapper; import net.minecraftforge.
fml.relauncher.Side; public class NetworkHandler < public static SimpleNetworkWrapper network; public static void init() < //инициализируем класс, что занимается передачей и обработкой пакетов между клиентом и сервером. TestMod.MOD_ID — айди мода. network = NetworkRegistry.INSTANCE.newSimpleChannel(TestMod.
MOD_ID); /* Регистрируем пакет. Параметры: класс обработчика(статический класс, который лежит внутри OpenInventoryMessage), класс самого сообщения, идентификатор, сторона, на которой будет обрабатываться пакет. Так как мы посылаем его на сервер, для открытия GUI менно оттуда, то указываем Side.SERVER */ network.registerMessage(OpenInventoryMessage.Handler.
class, OpenInventoryMessage.class, 0, Side.SERVER); > >
Не забываем зарегать это дело. В главном классе в преините пишем:
NetworkHandler.init();
Готово. Но будут ошибки в OpenInventoryMessage -> player.openGui(. ); . Нам нужен класс GuiHandler который при открытии GUI для сервера открывает контейнер, а для клиента GUI:
Его нужно зарегистрировать в коммон прокси в ините:
NetworkRegistry.INSTANCE.registerGuiHandler(TestMod.INSTANCE, new GuiHandler());
Воу. Почти все готово.
Уже можно даже запускать.
Но есть пару важных нюансов. При смерти игрока вещи не будут выпадать. При клонировании игрока вещи пропадут. Модифицируем наш ранее созданный класс для событий CapabilityEventHandler.java чтоб он теперь выглядел вот так:
Еще раз проверьте:
- Зарегистрировали вы КАПу
- Зарегистрировали вы кей бинд (KeyHandler)
- Зарегистрировали ли вы обработчики событий (CapabilityEventHandler)
- Зарегистрировали вы GuiHandler
- Зарегистрировали ли вы NetworkHandler и OpenInventoryMessage
Все. Можно запускать, открывать(жмякать Н, но можно теперь поменять в настройках) и радоваться жизни.
Задний фон у слотов
Но есть еще кое-что. Наши кастомные слоты пустые, без текстуры, не как например слоты брони. Самый простой способ добавить текстуру слоту — это дорисовать ее на картинке:). Перерисуем нашу inventory_gui.png и добавим задний фон слотам:
Источник: github.com
[Tutorial] Как сделать себе инвентарь с картинкой
Итак, как я уже сказал я покажу вам как сделать себе инвентарь с картинкой, поехали.
Для начала вам нужно взять картинку инвентаря из какого-нибудь ресурспака. resourcepack/assets/minecraft/textures/gui/container/inventory.png
Далее открываем картинку в любом фоторедакторе, я же буду использовать photoshop CS6.
Теперь накладываем какую-нибудь картинку или текст и делаем ей прозрачность по вашему усмотрению, я же сделал тесте Lemon с непрозрачностью 80%.
Дальше сохраняем и помещаем туда же откуда и взяли этот файл. resourcepack/assets/minecraft/textures/gui/container/inventory.png
А теперь в игре выбираем этот ресурспак и наслаждаемся результатом.
Если вы хотите сделать таким же инвентарь в креативе, то нужно взять файл tab_inventory.png и проделать с ним все те же махинации. resourcepack/assets/minecraft/textures/gui/container/creative_inventory/tab_inventory.png
Ну, а на этом я прощаюсь, с вами был Just_Lemon , всем пока.
Источник: ru-minecraft.ru
Создание кастомного инвентаря игрока
По просьбе решил написать простой туториал о создании кастомного инвентаря игрока. Прочитав данную статью, я подумал сделать свой инвентарь но с многими изменениями и под новую версию майна.
Туториал предполагает что вы знакомы с использованием прокси и умеете общаться с CAP`ой на уровне жестов(если не умеете то будем учить), а как отправлять пакеты постараюсь пояснить
Инвентарь, который получиться будет выглядеть так:
Это будет отдельный инвентарь(т.е. он не будет перекрывать обычный), который мы сможем открыть по нажатию созданной нами в дальнейшем кнопки Н. Для повышения совместимости кнопку сделаем так, что ее можно будет поменять в настройках управления на другую, таким образом любой пользователь сможет настроить все как ему удобно.
- CustomInventory.java — класс который будет управлять содержимым инвентаря, например: хранение, сохранение и восстановление инвентаря, управление предметами и т.д..
- ContainerCustomInv,java — контейнер. В нем будут добавляться слоты и описываться механика перетаскивания предметов из слота в слот при шифт-клике на них.
- StandartSlot.java — кастомные слоты, которые будем добавлять в контейнер. Хотя можно использовать и ванильные, но заодно покажу как использовать свои.
- GUICustomInv.java — то, как будет выглядеть инвентарь(бинд текстуры и прочее).
Спойлер: CustomInventory.java
Для того, чтоб вы не путались с индексами слотов когда будете делать или менять контейнер, я прикреплю такую картинку в помощь. На ней все слоты промаркированные:
Теперь нужно настроить контейнер:
Спойлер: ContainerCustomInv.java
Если вы хотите добавить, либо убрать слот, то нужно не забыть уменьшить или увеличить размер списка, в котором хранятся предметы(CustomInventory.java -> INV_SIZE). Так же не забудьте поправить индексы в методе transferStackInSlot, что в классе ContainerCustomInv. Если этого не сделать, то пойдут краши, такие как выход за пределы массива(ArrayIndexOutOfBoundsException) и прочие.
Пару слов о том, как ориентироваться в размещении слотов. Слоты, которые мы добавляем в инвентарь стандартного размера(16 x 16). Когда добавляем слот( this.addSlotToContainer(new StandartSlot(player, cInventory, 0, x, y)) , указываем x и y координаты, на которых этот слот будет размещен. В качестве центра выступает левый верхний угол слота. Думаю, понятнее будет, если посмотреть на картинку ниже:
Как видно на картинке, желтые точки это точки с координатами x и y, которые указывались при добавлении слота. Красным отмечен контур слота и как он располагается относительно указанной точки. Здесь я добавил два слота, с координатами x = 0, y = 0 и x = 87, y = 8.
Спойлер: StandartSlot.java
Думаю логика понятна, не так уж и сложно)
Источник: forum.mcmodding.ru