V této lekci si do hry přidáme model itemu, který jsem si tvořili v předchozí lekci a poté začneme pracovat na funkčnosti, aby item zabránil výbuchu creepera v okolí hráče. Item budeme přidávat do módu custom-item, který jsme si tvořili v počátečních lekcích.
Přidání modelu a textury
Přidání modelu a textur funguje stejně jako u bloku. Z blockbench bychom měli mít stažený .zip soubor, ve kterém máme model (.json soubor) a textury (.png soubory).
Model přesuneme do složkysrc/main/resources/assets/custom-item/models/item.
Textury přesuneme do složkysrc/main/resources/assets/custom-item/textures/item.
Abychom si mohli u itemu změnit jeho funkčnost, tak si musíme vytvořit vlastní třídu. Tu si vytvoříme ve složce src/main/java/com/example/item a nazveme ji AntiCreeperItem. Do třídy doplníme základní strukturu pro item.
public class AntiCreeperItem extends Item {
public AntiCreeperItem(Settings settings) {
super(settings);
}
}Vytvoření třídy
Třídu vytvoříme tak, že klikneme pravým tlačítkem myši na složku, kde chceme třídu vytvořit. Dále zvolíme New > Java Class.
Dále se přesuneme do souboru ModItems, kde jsme si přidávaly itemy a následujícím kódem si náš item registrujeme. Zároveň si můžeme nastavit například omezení na 1 item ve stacku.
public static final Item ANTI_CREEPER_ITEM = register(
new AntiCreeperItem(new Item.Settings().maxCount(1)),
"anti_creeper"
);Poznámka
Abychom si mohli k itemu doplnit funkčnost, tak zde musíme použít naši nově vytvořenou třídu
AntiCreeperItem
Nyní bychom měli mít item i s texturou a modelem ve hře. Můžeme jej ale zatím získat jen pomocí příkazu give
Přidání funkčnosti itemu
Abychom upravili, co se děje, když má hráč item v inventáři, tak můžeme použít metodu inventoryTick. Stačí, když ve třídě AntiCreeperItem začnete psát inv a v nápovědě by se měla nabídnout metoda inventoryTick.
@Override
public void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) {
super.inventoryTick(stack, world, entity, slot, selected);
}Jak už název napovídá, tak tato metoda se spouští každý tick (20krát za sekundu) a to jen v případě, že má hráč item v inventáři.
Samotný postup pro zabránění výbuchu creepera bude následující:
- zkontrolujeme, že entita, která item drží je hráč
- zjistíme zda hráč item drží v ruce
- vyhledáme creepery v okolí hráče
- resetujeme creeperům čas do výbuchu
Kontrolu, zda item drží hráč provedeme pomocí metody isPlayer. Kontrolu můžeme otočit tím, že před podmínku napíšeme !. Pokud tedy entita není hráč, tak dál nemusíme pokračovat a můžeme pomocí return kód ukončit. Metoda vrací hodnotu void, což je doslova nic, takže za return žádnou hodnotu psát nemusíme.
@Override
public void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) {
if (!entity.isPlayer()){
return;
}
super.inventoryTick(stack, world, entity, slot, selected);
}Tip
Abychom nemuseli vždy u proměnné psát typ, tak můžeme použít slovo
vara typ se nastaví automaticky.
Dále si entitu převedeme z obecné entity na typ PlayerEntity (hráč).
var player = (PlayerEntity)entity;Pomocí metody getHandItems si získáme seznam itemů, které má hráč v ruce. Dále si seznam převedeme na jiný typ pomocí metody iterator.
var items = player.getHandItems().iterator();Abychom mohli zkontrolovat, že je aktuální stack itemů v jedné nebo druhé ruce, tak jej musíme převést na jiný typ seznamu pomocí Lists.newArrayList(items) a dále pak můžeme použít metodu contains, která zkontroluje, zda daný seznam obsahuje konkrétní prvek. V našem případě je to stack itemů v parametru stack. Výsledek si uložíme do proměnné isItemInHand
var isItemInHand = Lists.newArrayList(items).contains(stack);Pokud hráč item nemá v ruce, tak můžeme opět kód ukončit pomocí return.
if (!isItemInHand){
return;
}Celý kód bude vypadat následovně:
@Override
public void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) {
if (!entity.isPlayer()){
return;
}
var player = (PlayerEntity)entity;
var items = player.getHandItems().iterator();
var isItemInHand = Lists.newArrayList(items).contains(stack);
if (!isItemInHand){
return;
}
super.inventoryTick(stack, world, entity, slot, selected);
}Zbytek kódu si doděláme v následujících lekcích.