Приветствую! Прошлую серию уроков я начинал писать совсем не зная, как я хочу это делать. Ни опыта не было, ни ясной конечной цели уроков. К тому же местами я использовал не самые актуальные данные, что, конечно же, нужно исправлять. Сперва я хотел переписать старые, но иногда куда проще начать с чистого листа. В этот раз будет быстрее, проще, понятнее. Вообще-то я очень даже хочу попробовать создавать каких-то интересных мобов, да ещё и ИИ им какую-то прикрутить новую. Вроде строительства, добычи, охоты. Так что я мотивирован быстро подойти к новому.
И да, в прошлые разы я продолжал один проект, что могло привести к путанице. Так что теперь разные части будут разбиты по разным папкам, и залиты на github. Можно будет подсмотреть любой интересный момент и ничего лишнего 🙂 Окей, теперь погнали.
Немного о предметах
Итак. Предметы. Это важная часть игры. Запомним важный момент: всё, что вы видите в инвентаре игрока, сундуках, других слотах – это всё предметы. Блоки расположены в мире, а когда мы их добываем, то получаем предметы (хоть и выглядят эти предметы как блоки). Надеюсь, не запутал. Подробнее мы это разберём про создании блоков.
А сейчас разберём виды предметов в игре. Возьмем пару очевидных примеров.
- Первой будет палка. Её все видели, добывали. Она может лежать в инвентаре, её можно взять в руки, но при этом применить её никак нельзя.
- А вот предметы вроде торта, печи, редстоуна – можно поставить (в таком случае предмет будет преобразован в блок). Фактически это предметы, которые при нажатии ПКМ и соблюдении соответствующих условий (тростник не всегда можно поставить, но можно же можно) будут создавать связанный с ними блок.
- Ещё один вид предметов – еда. Они так же имеют уникальное применение, в результате которого какие-то изменения получит игрок (еда может давать не только сытость, но и эффекты).
- Нельзя забывать и о яйцах призыва, в т.ч. куринные яйца. Это у нас предметы, которые могут призывать существ.
- И отдельно выделю предметы с уникальным применением. Сюда я отношу часы, которые фактически ничего не дают, но внешним видом выполняют свою функцию. Там же компас, бирка, стрелы т.п.
Скажу так, классификация не общепринятая. Я её только что придумал 😀 Но с технической точки зрения как-то так бы я их и поделил.
В этот раз мы создадим самый обычный предмет. Ещё одну палку, почему нет? В следующий раз уже сделаем еду, а потом блок и предмет блока. Призывающий предмет предлагаю создавать уже после урока о мобах. Так будет интереснее. И, скорее всего, в качестве бонусных гайдов, можно создать про свои компасы, часы и т.д. Для общего образования) Мне и самому интересно, так что почему нет?
JAVA часть
Начинаю с пустого проекта. В первую очередь в корне исходного кода создадим папку item. Я и раньше говорил, что при создании мода удобно создавать иерархию файлов подобную игровой. Таким образом легче что-то найти, да и код понятнее.
В отличии от старых гайдов, где регистрация предмета сопровождалась аж тремя функциями и парой файлов, тут всё будет проще. Потому в папке предметов создаём ModItems.java и пишем туда такой код:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package mod.astler.tutorial_mod_gs.item; import mod.astler.tutorial_mod_gs.TutorialGSMod; import net.minecraft.item.Item; import net.minecraftforge.fml.RegistryObject; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; public class ModItems { public static final DeferredRegister<Item> ITEMS = new DeferredRegister<>(ForgeRegistries.ITEMS, TutorialGSMod.MODID); public static final RegistryObject<Item> STONE_STICK = ITEMS.register("stone_stick", () -> new Item(new Item.Properties())); } |
Регистрация происходит при помощи DeferredRegister. Если кратко, то этот способ гарантирует, что блоки, предметы и всё остальное будут созданы там, где нужно и когда нужно. Может спасти от некоторых ошибок).
В очередной раз можно увидеть использование Supplier (если смотрели старые гайды, то знаете). И фактически мы не создаём объект предмета прямо тут и сейчас, но при создании предметов во время загрузки игры – функция будет вызвана и предмет создан. Первый параметр — это имя предмета.
Чтобы всё это заработало регистрируем шину событий для регистра предметов (так же нужно будет делать и для блоков, структур, мобов). Класс мода должен иметь такой вид:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package mod.astler.tutorial_mod_gs; import mod.astler.tutorial_mod_gs.item.ModItems; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; @Mod(TutorialGSMod.MODID) @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) public class TutorialGSMod { public static final String MODID = "tutorial_mod_gs"; public TutorialGSMod() { IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); ModItems.ITEMS.register(bus); } } |
Ура! Предмет в игре!
Теперь нужно добавить его текстуру и модель.
Ресурсы предмета
За внешний вид предмета отвечает модель. Модель – специальный json файл, который должен быть расположен по такому пути: src/main/resources/assets/YOUR_MODID/models/item/YOUR_MODEL.json.
Для каменной палки в этом моде он будет таким: src/main/resources/assets/tutorial_mod_gs/models/item/stone_stick.json
Папка resources должна быть создана автоматически, остальные нужно будет создать.
При создании .json файла смотрите внимательно, чтобы не оставить .json.txt или вроде того. Такие модели игра читать не будет.
И пишем туда такой код:
1 2 3 4 5 6 |
{ "parent": "item/generated", "textures": { "layer0": "tutorial_mod_gs:item/stone_stick" } } |
Parent – тема-родитель. В данном случае выбрана генерируемая модель, которая будет передавать форму текстуры. Это большинство игровых предметов. К примеру яблоко, обычная палка, лопата. А textures пары элементов «имя текстуры»:«сама текстура». Так как для модели типа generated нужна только одна текстура с именем layer0, то только её мы и укажем. Множество текстур будет в моделях бревна, книжного шкафа и т.д.
Теперь нам нужно добавить саму текстуру. Путь к текстурам тоже фиксирован. В модели мы указали, что текстуру надо искать в ресурсах именно нашего мода, в папке предметов. Т.е. полный путь должен быть таким: resources/assets/tutorial_mod_gs/textures/item/stone_stick.png. Я отредактировал текстуру обычной палки и получил что-то такое:
Так же можно добавить Локализацию.
Добавляем вкладку
Уже сейчас игру можно запустить и получить предмет при помощи команд, но это не особо удобно. Не зря же был придумал творческий с этими классными и удобными вкладками?
Конечно же, мы можем добавить наш предмет в одну из существующих вкладок. Для этого добавим к свойствам предмета:
1 |
new Item.Properties() |
это
1 |
new Item.Properties().group(ItemGroup.FOOD) |
И теперь при запуске игры во вкладке еды будет и наша палка. Хотя, и не место ей там.
Вообще мы можем использовать любую доступную вкладку в игре:
1 2 3 4 5 6 7 8 |
<em><strong>BUILDING_BLOCKS DECORATIONS REDSTONE TRANSPORTATION MISC TOOLS COMBAT BREWING</strong></em> |
НО! Если у нас в моде будет много своих блоков, предметов, инструментов, еды и всего-всего – проще создать свою вкладку (а может даже несколько).
Для начала в папке предметов создадим класс вкладки (ModItemGroup.java), который будет отлично подходить для нашей реализации предметов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package mod.astler.tutorial_mod_gs.item; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import java.util.function.Supplier; public class ModItemGroup extends ItemGroup { private final Supplier<ItemStack> iconSupplier; public ModItemGroup(final String name, final Supplier<ItemStack> iconSupplier) { super(name); this.iconSupplier = iconSupplier; } @Override public ItemStack createIcon() { return iconSupplier.get(); } } |
Всё в той же папке предметов добавляем новый файл ModItemGroups.java :
1 2 3 4 5 6 7 8 |
package mod.astler.tutorial_mod_gs.item; import net.minecraft.item.ItemGroup; public class ModItemGroups { public static final ItemGroup MOD_ITEMS_ITEM_GROUP = new ModItemGroup("tutorial_mod_gs_items", () -> new ItemStack( ModItems.STONE_STICK.get())); } |
Теперь зададим каменной палке нашу вкладку:
1 |
new Item.Properties().group(ModItemGroups.MOD_ITEMS_ITEM_GROUP) |
Отлично. Вот теперь всё работает как нужно. Вернее, палка ничего не делает, но так ведь в том и суть 😀 Простые предметы без применения в основном используют в крафте, но об этом немного позже. А на этом всё, спасибо за внимание.
Пингбэк: Создание модов для Minecraft 1.15 – GeekStand
Пингбэк: Добавляем еду, еду с эффектами и корм – GeekStand
Пингбэк: [1.15.2] Добавляем свой блок – GeekStand