4. diel - Minecraft Modding - Soľná palička a crafting
V tomto dieli by som rád urobil nejaký poriadny item, ktorý už bude dokonca niečo robiť (bude to soľná prútik, s ktorou my budeme môcť zjesť akýkoľvek block a doplní sa nám hungerbar).
ItemSulWand
Ako som spomínal v minulom dieli, pretože potrebujeme reagovať na nejaké eventy, je nutné vytvoriť potomka triedy Item.
public class ItemSulWand extends Item{ public ItemSulWand(){ setUnlocalizedName("itemWand"); setCreativeTab(CreativeTabs.tabTools); setTextureName("sul_wand"); this.maxStackSize=1; this.setMaxDamage(32); } }
Tu by som mohol podotknúť, že Minecraft uvidí tento item už ako nástroj, pretože platí, že maxstacksize == 1 a maxdamage> 0. To ale len tak okrajovo. Zatiaľ sme si urobili item, ktorý sa môže poškodiť 32-krát a nemožno ho stackovat. My však chceme reagovať na event kliknutie pravým tlačidlom. Musíme teda prekryť metódu onItemUse, ktorá sa zavolá vždy, keď klikneme s týmto Item v ruke na nejaký blok. V tomto prípade vracia true, ak tento item niečo robí.
/** java * @param itemstack s kterým klikám * @param player hráč, který itemstack drží * @param world svět * @param x coordináty bloku * @param y coordináty bloku * @param z coordináty bloku * @param side strana bloku, na kterou klikám * @param px coordináty kam přesně na tom bloku jsem klikl např doprostřed, vlevo dole...., rozsah 0.0-1.0 * @param py coordináty kam přesně na tom bloku jsem klikl * @param pz coordináty kam přesně na tom bloku jsem klikl */ @Override public boolean onItemUse(ItemStack itemstack, EntityPlayer player, World world, int x, int y, int z, int side, float px, float py, float pz){ return true; }
Nu a teraz si môžeme už hrať a robiť čokoľvek čo chceme. Pomocou parametra world môžeme pristupovať k svetu a teda aj k zmene blokov. Na zmenu bloku má World metódu setBlock (int x, int y, int z, Block block), kde xyz sú súradnice blocku a block, ktorý na súradnice chceme položiť. Keby som túto metódu mal priblížiť vizuálne, v jednej chvíli by tam bol Obsidian a vzápätí glass alebo air. Lenže to sa nám nepáči. My by sme chceli aby táto zmena blocku bola sprevádzaná nejakým efektom (napr: Particles a zvuk rozbitie). A preto je tu funkcia func_147480_a (int x, int y, int z, boolean shouldDropAsItem), ktorá má ako parametre súradnice xyz a boolean či nám má vypadnúť block, keď ho zničíme. Áno, táto metóda má bohužiaľ pekne blbý názov, ale dôležité je, že nám rozbije block aj s efektom. Ďalej je potom potrebné dať ošetriť nejaké výnimky, ako napríklad aby sme nemohli zjesť Bedrock. Na zistenie na aký block klikáme nám poslúži metóda getBlock ().
if (world.getBlock(x, y, z)!=Blocks.bedrock){ world.func_147480_a(x,y,z,false); itemstack.damageItem(1, player); }
Teraz ak klikneme pravým tlačidlom na akýkoľvek block okrem Bedrock, tak sa nám zničia. Pomocou metódy damageItem poškodzujeme našu prútik o 1 stupeň pri každom zjedení. (Keď dôjde výdrž paličky, tak sa nám zničia.)
player.getFoodStats().addStats(1,0.1F);
Postarali sme sa o nasýtení hráča, kde ako 1. param je foodlevel a ako 2. je tu nasýtenosť (ako dlho bude trvať než mu zasa vyhladnete).
player.playSound("random.burp", 1F, 1F);
A tu prehrávame hráči zvuk metódou playSound (String zvukName, float hlasitosť, float rychlost_přehrání (väčšie ako 1F bude zvuk spomalený)). Zoznam všetkých mien zvukov je na stiahnutie pod článkom.
Ak si teraz loadneme svet a skúsime s našou prútikom kliknúť na nejaký block (okrem Bedrock), tak sa rozbije, nás to nakŕmi a nakoniec sa ešte prehrá zvuk zjedení.
Particles
Keďže by sme chceli efekt soľných particles na tom bloku čo ničíme a teoreticky aj prúd particles od bloku k hráčovi, použijeme World metódu spawnParticle (String particleid, double x, double y, double z, double motionX, double MOTION, int motionZ). Názvy particles aj s obrázkami tu. Tu budem chcieť particle salt blocku, ktorý som si vytvoril v min. diele. blockcrack_id_data
world.spawnParticle("blockcrack_"+Block.getIdFromBlock(BlocksManager.blockSul)+"_0", x, y+1, z, world.rand.nextGaussian(), world.rand.nextGaussian(), world.rand.nextGaussian());
Tu len pripomienka, že používam Random atribútu inštancie world.
Teraz, pretože to vyzerá cool, by som rád spawnul particles medzi hráčom a Bločky, ktorý ničí.
int posX=(int) player.posX; int posY=(int) player.posY; int posZ=(int) player.posZ; for (int i = 0;i<40;i++){ int xp=(int) (x-posX<0?x+world.rand.nextInt(Math.abs(x-posX)==0?1:Math.abs(x-posX)):posX+world.rand.nextInt(Math.abs(x-posX)==0?1:Math.abs(x-posX))); int yp=(int) (y-posY<0?y+world.rand.nextInt(Math.abs(y-posY)==0?1:Math.abs(y-posY)):posY+world.rand.nextInt(Math.abs(y-posY)==0?1:Math.abs(y-posY))); int zp=(int) (z-posZ<0?z+world.rand.nextInt(Math.abs(z-posZ)==0?1:Math.abs(z-posZ)):posZ+world.rand.nextInt(Math.abs(z-posZ)==0?1:Math.abs(z-posZ))); world.spawnParticle("blockcrack_"+Block.getIdFromBlock(BlocksManager.blockSul)+"_0", xp, yp, zp, 0,0, 0); }
A týmto by sme mali magickú soľnou prútik, s ktorou môžem zjesť takmer akýkoľvek block. Avšak zrada! Kde ju len vziať! Možno by bolo fajn si ju vycraftit.
Crafting Shaped Recipes
Pre vytvorenie receptov využijeme eventu init v našej triede Main a metódy addRecipe () / addShapedRecipe () = tieto 2 metódy sú totožné. (Respektíve addRecipe () volá addShapedRecipe ()).
GameRegistry.addShapedRecipe(new ItemStack(Items.golden_chestplate, 1), "y y", "yyy", "yyy", 'y', new ItemStack(Items.gold_ingot));
Takto vyzerá craftící recept pre golden chestplate. Tu platí že prvý param je výsledná vec, ktorú vyrábame a ďalšie:
- max 3 stringy s dĺžkou max 3 kde platí, že prvé string sú prvé max 3 okienka v crafting table.
- char ktorý sme používali v našich reťazcoch
- Itemstack, ktorý sa vzťahuje k charu, ktorý som napísali v 2. kroku.
- opakujeme kroky 2 a 3 aby som takto vypísali všetky char použité v reťazci a ich priradenie k itemstackům.
Keďže sme si vedomý nepřehledosti v tomto zmätenom výklade, uvediem ešte pár iných príkladov:
Piston
GameRegistry.addShapedRecipe(new ItemStack(Blocks.piston, 1), "ddd", "kzk", "krk", 'd', new ItemStack(Blocks.planks), 'k', new ItemStack(Blocks.cobblestone), 'z', new ItemStack(Items.iron_ingot), 'r', new ItemStack(Items.redstone));
Torch
GameRegistry.addShapedRecipe(new ItemStack(Blocks.torch, 4), "u", "k", 'u', new ItemStack(Items.coal), 'k', new ItemStack(Items.stick));
U Torche receptu normálne platí, že uhlie nemusí byť presne v ľavom hornom rohu, jediná dôležitá vec je, aby pod ním bol paličku.
Slab
GameRegistry.addShapedRecipe(new ItemStack(Blocks.stone_slab, 6), "yyy", 'y', new ItemStack(Blocks.cobblestone));
Pri slabo tiež platí ignorácia presného riadku, kam sa má Cobblestone dať.
náš SůlBlock
GameRegistry.addShapedRecipe(new ItemStack(BlocksManager.blockSul, 1), "ss", "ss", 's', new ItemStack(ItemsManager.itemSul));
naše Hůlka
GameRegistry.addShapedRecipe(new ItemStack(ItemsManager.itemWand, 1), "d", "s", "s", 's', new ItemStack(ItemsManager.itemSul), 'd', new ItemStack(Items.diamond));
Tu odporúčam si pár Receptíky skúsiť urobiť, aby ste prišli na presne správne správanie tohto craftícího zápisu, druhá varianta je so pozrieť na zobraz zdroj metódy addShapedRecipe ().
Crafting Shapeless Recipes
Ak chceme urobiť nejakú zmes, treba zmiešať 4 prášky, tak je nám asi jedno, v ktorom z 9 okínek sa bude nachádzať, hlavne že tam sú. A k tomu je o dosť jednoduchšie metóda addShapelessRecipe (Itemstack output, Itemstack ... suroviny).
GameRegistry.addShapelessRecipe(new ItemStack(Items.bronz, 4), new ItemStack(Items.cín), new ItemStack(Items.měď), new ItemStack(Items.měď), new ItemStack(Items.měď));
Tu sme pridali recept na výrobu bronzu z jedného cínu a troch meďou.
Tak a je hotovo. Zdrojáky triedy ItemWand a Main na stiahnutie pod článkom.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 36x (4.13 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java