Her vil vi i fælleskab udvikle et inventory system i Godot C#. Krav til vores inventory er følgende:
using Godot; using System; [GlobalClass] public partial class Item : Resource { [Export] public int ID { get; set; } [Export] public String Name { get; set; } [Export] public Texture2D Icon { get; set; } [Export] public int Quantity { get; set; } [Export] public int MaxStackSize { get; set; } [Export] public bool IsStackable { get; set; } }
using Godot; using System; public partial class Collectable : Node { [Export] public Item item; // Called when the node enters the scene tree for the first time. public override void _Ready() { GetNode<Sprite2D>("Sprite2D").Texture = item.Icon; } public void OnBodyEntered(Node other) { if (other.Name == "Player") { GD.Print("Collectable was entered by Player."); if (GetNode<Inventory>("/root/World/CanvasLayer/Inventory").Add(this.item) == true) { this.QueueFree(); } } } }
Ansvar: Viser indhold af Item i InventoryGui
using Godot; using System; public partial class InvSlot : Panel { // Called when the node enters the scene tree for the first time. public override void _Ready() { GetNode<Sprite2D>("ItemDisplayIcon").Visible = false; // Som udgangspunkt er denne skjult } public void UpdateSlot(Item item) { if (item == null) GetNode<Sprite2D>("ItemDisplayIcon").Visible = false; else { GetNode<Sprite2D>("ItemDisplayIcon").Visible = true; GetNode<Sprite2D>("ItemDisplayIcon").Texture = item.Icon; } } // Called every frame. 'delta' is the elapsed time since the previous frame. public override void _Process(double delta) { } }
Indeholder alle vores opsamlede items. Håndtere funktionalitet ift. at tilføje og fjerne Items.
NinePatchRect er en smart Component der deler en Sprite i 9 felter, og bibeholder aspektet på ydre deområder således vi kan bruge den i forskelle størrelse (fx. baggrund til Inventory, Dialoger eller andet) se nedenstående.
Tilføj 8 stk InvSlotUI til denne GridContainer, og juster antal columns på GridContainer til 4.
using Godot; using System; public partial class Inventory : Control { public bool IsOpen = true; [Export] public Item[] items; GridContainer gridContainer; override public void _Ready() { gridContainer = GetNode<GridContainer>("NinePatchRect/GridContainer"); GD.Print("GridContainer check: " + gridContainer); } /* * Opening and Closing the inventory. * Controlled (input captured) from CanvasLayer Script */ public void OpenInventory() { this.Visible = true; IsOpen = true; } public void CloseInventory() { this.Visible = false; IsOpen = false; } public bool Add(Item item) { GD.Print("Adding item: " + item.Name + " to inventory"); for (int x = 0; x < items.Length; x++) { if (items[x] == null) { items[x] = item; UpdateAllInventorySlots(); return true; } else if ( items[x].ID == item.ID && item.IsStackable == true ) { if (items[x].Quantity < items[x].MaxStackSize) { // Der er noget plads !! if (item.Quantity + items[x].Quantity <= items[x].MaxStackSize) { // Der er plads nok i ét slot. items[x].Quantity += item.Quantity; UpdateAllInventorySlots(); return true; } else { // Fyld Slot op, Juster item quantity, og lad os om der plads andre steder item.Quantity -= (items[x].MaxStackSize - items[x].Quantity); items[x].Quantity = items[x].MaxStackSize; UpdateAllInventorySlots(); return true; } } } } GD.Print("Failed to ADD item: " + item.Name + ", to Inventory.. (maybe its full?)"); return false; } public bool HasItem(Item item) { for (int i = 0; i < this.items.Length; i++) { if (items[i].ID == item.ID) { return true; } } return false; // item was not found } public bool RemoveItem(Item item) { bool success = false; for (int i = 0; i < this.items.Length; i++) { if (items[i].ID == item.ID) { items[i] = null; success = true; } } return success; // item was not removed } /* * Updates all visible Slot GUIs so they are in sync with the items array */ public void UpdateAllInventorySlots() { for (int i = 0; i < items.Length; i++) { var slots = gridContainer.GetChildren(); ((InvSlot)slots[i]).UpdateSlot(items[i]); } } }
using Godot; using System; public partial class InvSlot : Panel { // Called when the node enters the scene tree for the first time. public override void _Ready() { GetNode<Sprite2D>("ItemDisplayIcon").Visible = false; // Som udgangspunkt er denne skjult } public void UpdateSlot(Item item) { if (item == null) GetNode<Sprite2D>("ItemDisplayIcon").Visible = false; else { GetNode<Sprite2D>("ItemDisplayIcon").Visible = true; GetNode<Sprite2D>("ItemDisplayIcon").Texture = item.Icon; } } // Called every frame. 'delta' is the elapsed time since the previous frame. public override void _Process(double delta) { } }