Inventory

Põhimõte

Inventory on tavaliselt kogum, kus mängija saab hoida teatud ressursse või esemeid (item), nagu näiteks toitu, varustust ja/või relvi. Inventory võime implementeerida klassina, mis salvestab mängija esemeid massiivis. Samuti loome eraldi klassi Item.

Item

Esmalt implementeerime Item klassi. See võiks sisaldada eseme kirjeldust või omadusi, nagu näiteks nimi, tugevus, vastupidavus, tähendus jms., olenevalt mis tüüpi esemeid Sa planeerid oma mängus kasutada.

public class Item {
    private final String name;

    public Item(String name) {
        this.name = name;
        // Siia võib lisada rohkem omadusi
    }

    public String getName() {
        return name;
    }
}

Inheritance

Item klass võib olla baasiks erinevatele esemetele, nagu Weapon ja Food, mis laiendavad selle funktsionaalsust. Inheritance ehk päriluse abil saame luua uusi klasse, mis põhinevad olemasolevatel. Näiteks on allpool Weapon klass, mis on laiendus Item klassist. Kõik Item omadused on ka Weapon klassil, kuid see saab lisada ka oma omadusi, nagu damage.

public class Weapon extends Item {
     private final int damage;

     public Weapon(String name, int damage) {
         super(name);
         this.damage = damage;
     }

     public int getDamage() {
         return damage;
     }
 }

Selle loogikaga saab ka teha stackable asju ehk asju, mida on ühe inventory koha peal mitu. Näiteks inventory hoiab viite õuna ühe koha peal.

public class StackableItem extends Item {
    private int quantity;
    private final int maxQuantity;

    public StackableItem(String name, int quantity, int maxQuantity) {
        super(name);
        this.quantity = quantity;
        this.maxQuantity = maxQuantity;
    }

    public int getQuantity() {
        return quantity;
    }

    public void addQuantity(int amount) {
        if (quantity + amount > maxQuantity) {
            return;
        }
        this.quantity += amount;
    }
}

Inventory

Kui Item klass on defineeritud, saame luua Inventory klassi. Selle jaoks kasutame massiivi, kus hoida Item objekte ning võime defineerida, kui suur see on.

public class Inventory {
    private final ArrayList<Item> items;
    private final int maxCapacity;

    public Inventory(int maxCapacity) {
        this.maxCapacity = maxCapacity;
        this.items = new ArrayList<>();
    }

    public boolean addItem(Item item) {
        if (items.size() < maxCapacity) {
            items.add(item);
            return true;
        }
        return false;
    }

    public void removeItem(Item item) {
        items.remove(item);
    }

    public ArrayList<Item> getItems() {
        return items;
    }

    public int getMaxCapacity() {
        return maxCapacity;
    }
}

Näide Inventory kasutamisest

Inventory inventory = new Inventory(10); // Loome uue inventari, kus on maksimaalselt 10 eset

Item key = new Item("Key"); // Loome uue eseme nimega Key
Weapon sword = new Weapon("Sword", 15); // Loome uue eseme nimega Sword, damage=15

inventory.addItem(key); // Lisame eseme inventari
inventory.removeItem(key); // Eemaldame eseme inventarist

Tihti on vaja kahe erineva inventory vahel asju liigutada. Näiteks teise mängijaga asju vahetada või asju kasti tõsta. Selleks on mõistlik luua inventory klassi abimeetod transferItemTo().

public boolean transferItemTo(Item item, Inventory targetInventory) {

    if (this.items.contains(item) && targetInventory.addItem(item)) { // Kui selles inventaris on asi ja teise inventaari lisame asja

        this.removeItem(item); // Võtame algsest inventaarist asja ära
        return true;
    }
    return false;
}

Nüüd saame asjad ümber tõsta.

Inventory playerInventory = new Inventory(5);
Inventory chestInventory = new Inventory(10);

Item apple = new Item("Apple");

playerInventory.addItem(apple);

boolean success = playerInventory.transferItemTo(apple, chestInventory); // Tõstame õuna mängijalt kirstu

if (success) {
    System.out.println("Apple transferred successfully!");
} else {
    System.out.println("Transfer failed.");
}

Visuaalne Inventory

Nüüd on inventory funktsionaalsus valmis. Seda saab rakendada mitmel moel, sõltuvalt mängu vajadustest. Puudu on kõigest frontend ehk inventory visualiseerimine. Alustame sellest, et lisame igale Item klassile ka enda tekstuuri. Nii saame mugavalt kuvada pildi tervest inventarist. Uus Item klass võiks välja näha selline:

public class Item {
    private final String name;
    private final TextureRegion texture;

    public Item(String name, TextureRegion texture) {
        this.name = name;
        this.texture = texture;
        // Siia võib lisada rohkem omadusi
    }

    public String getName() {
        return name;
    }

    public TextureRegion getTexture() {
        return texture;
    }
}

Samuti tuleb muuta teiste alamklasside konstruktoreid. Näiteks StackableItem näeks välja selline:

public class StackableItem extends Item {
    private int quantity;
    private final int maxQuantity;

    public StackableItem(String name, int quantity, int maxQuantity, TextureRegion texture) {
        super(name, texture);
        this.maxQuantity = maxQuantity;
        this.quantity = quantity;
    }

    public int getQuantity() {
        return quantity;
    }

    public void addQuantity(int amount) {
        if (quantity + amount > maxQuantity) {
            return;
        }
        this.quantity += amount;
    }
}

Järgmisena tuleb luua uus klass, mis visualiseerib meie loodud inventari. Kõigepealt defineerime kõik muutujad, mida plaanime kasutada.

public class VisualInventory {
    private final Inventory inventory;
    private final TextureRegion slotTexture;
    private final int slotsPerRow;
    private final int spaceBetweenSlotsX;
    private final int spaceBetweenSlotsY;
    private final BitmapFont font;
    private final int maxSlots;
    private final int startingPositionX;
    private final int startingPositionY;
    private final int slotSize;

Tundub justkui muutujaid on hirmuäratavalt palju, kuid see annab võimaluse muuta oma koodi vastavalt vajadusele. Järgmisena loome konstruktori. Paljud väärtused on vaikimisi pandud kindlateks numbriteks, neid võid muuta vastavalt vajadusele.

public VisualInventory(Inventory inventory, TextureRegion slotTexture) {
    this.inventory = inventory;
    this.slotTexture = slotTexture;
    this.slotsPerRow = 5;
    this.spaceBetweenSlotsX = 40;
    this.spaceBetweenSlotsY = 50;
    this.font = new BitmapFont();
    font.setColor(1, 0, 0, 1);
    this.maxSlots = inventory.getMaxCapacity();


    this.startingPositionX = 50;
    this.startingPositionY = 50;
    this.slotSize = 32;

}

Kui constructor on olemas, peame looma render meetodi. See visualiseerib kõik meie jaoks vajaliku.

public void render(SpriteBatch batch) {
    for (int i = 0; i < maxSlots; i++) {
        int currentRow = i / slotsPerRow;
        int currentCol = i % slotsPerRow;
        int currentPositionX = startingPositionX + spaceBetweenSlotsX * currentCol;
        int currentPositionY = startingPositionY + spaceBetweenSlotsY * currentRow;
        batch.draw(slotTexture, currentPositionX, currentPositionY, slotSize, slotSize);
        if (i < inventory.getItems().size()) {
            Item item = inventory.getItems().get(i);
            batch.draw(item.getTexture(), currentPositionX, currentPositionY, slotSize, slotSize);
            if (item instanceof StackableItem) {
                font.draw(batch, String.valueOf(((StackableItem) item).getQuantity()), currentPositionX + slotSize / 2, currentPositionY + slotSize / 2);
            }
        }
    }
}

Nüüd kui klassid on loodud, tuleb lisada ka pildid inventari jaoks. Vaja on tühja ruudu pilti ning iga Item-i enda pilti. Need lisame assets kausta sisse. Siin näites kasutan järgnevaid pilte:

../_images/frame.png ../_images/switch.png ../_images/router.jpg

Nüüd on kogu loogika tehtud! Tuleb vaid inventar luua ja kuvada. Näide:

TextureRegion routerTexture = new TextureRegion(new Texture("sprites/routerImage.jpg"));
TextureRegion switchTexture = new TextureRegion(new Texture("sprites/switchImage.png"));
Item routerItem = new Item("Router", routerTexture);
StackableItem switchItem = new StackableItem("Switch", 12, 64, switchTexture);
Inventory inventory = new Inventory(10);
inventory.addItem(routerItem);
inventory.addItem(switchItem);
TextureRegion boxTexture = new TextureRegion(new Texture("sprites/inventoryBox.png"));
VisualInventory visualInventory = new VisualInventory(inventory, boxTexture);

Nii saab sellise lihtsa inventari:

../_images/example.png

Lisaks abistavaid blogisid, tutoriale