====== Resources i Inventory ====== I et RPG skal spilleren kunne samle våben, potions og armor op og beholde dem, når spilleren skifter scene. Vi løser det ved at oprette en **global** `InventoryManager` som **Autoload**. Den eksisterer, så længe spillet kører, og kan tilgås fra alle scener. ===== 1. Opret InventoryManager ===== Opret et C#-script med navnet `InventoryManager.cs`. using Godot; using Godot.Collections; public partial class InventoryManager : Node { public Array Items { get; private set; } = new(); public void AddItem(Item item) { if (item == null) return; Items.Add(item); GD.Print($"Samlede op: {item.Name}"); } } **Hvad sker der?** * `Array` indeholder spillerens items. * `AddItem()` tilføjer et item til inventory. * `InventoryManager` indeholder kun data og logik for inventory – ikke selve brugergrænsefladen. Bemærk, at `Item` er den fælles Resource-klasse fra den foregående øvelse. Både `WeaponItem` og `PotionItem` kan derfor tilføjes. ---- ===== 2. Gør InventoryManager global ===== For at inventory overlever sceneskift, skal `InventoryManager` oprettes som en **Autoload**. - Åbn **Project → Project Settings → Globals → Autoload**. Menunavnet kan variere lidt mellem Godot-versioner. - Vælg filen `InventoryManager.cs`. - Angiv navnet `InventoryManager`. - Aktivér Autoload. (markér checkbox 'Enabled') Godot opretter nu en global instans af `InventoryManager`, som ikke bliver fjernet, når en almindelig scene skiftes ud. Du kan tilgå den fra C# med: GetNode("/root/InventoryManager"); ---- ===== 3. Opret ItemPickup ===== Opret et script med navnet `ItemPickup.cs`. Det sættes på en `Area2D`, som spilleren kan gå ind i for at samle et item op. using Godot; public partial class ItemPickup : Area2D { [Export] public Item Data { get; set; } public override void _Ready() { _sprite = GetNode("Sprite2D"); if (item != null) { _sprite.Texture = item.Icon; } BodyEntered += OnBodyEntered; } private void OnBodyEntered(Node2D other) { if (other is Player) { var inventory = GetNode("/root/InventoryManager"); inventory.AddItem(Data); QueueFree(); } } } **Bemærk:** `Player` skal svare til navnet på jeres spillers C#-klasse. ---- ===== 4. Opsæt pickup-scenen ===== Opret følgende nodestruktur: ItemPickup (Area2D) ├── Sprite2D └── CollisionShape2D - Tilføj `ItemPickup.cs` til `Area2D`. - Opret en `CollisionShape2D`, der dækker det område, spilleren skal ramme. - Sørg for, at `Area2D` har `Monitoring` aktiveret. - Forbind signalet `body_entered` til metoden `OnBodyEntered`. - Tildel en konkret `Item`-resource til egenskaben `Data` i Inspector. Du kan nu genbruge samme pickup-scene til eksempelvis `Sword.tres`, `HealthPotion.tres` og `IronArmor.tres`. ---- ===== 5. Test sceneskift ===== - Start spillet i en scene med et item. - Gå hen til item'et, og saml det op. - Skift til en anden scene. - Undersøg `InventoryManager.Items`, eller udskriv indholdet i Output. Tilføj eventuelt denne metode til `InventoryManager` for at teste indholdet: public void PrintItems() { foreach (Item item in Items) { GD.Print(item.Name); } } Kald metoden fra et passende sted i spillet, når du vil kontrollere inventory. ---- ===== 6. Hvorfor virker det? ===== En almindelig scene bliver fjernet, når spillet skifter til en anden scene. En Autoload-instans lever derimod videre, mens spillet kører. Inventory ligger derfor ikke i den scene, spilleren forlader, men i en global instans. ++++ Vigtigt: Hvad gemmes egentlig? | InventoryManager gemmer referencer til de `Item`-resources, spilleren har samlet op. Det betyder ikke, at spillet automatisk gemmer fremskridtet på disken. Hvis spilleren også skal beholde inventory efter at have lukket spillet, skal I senere implementere et save/load-system. ++++ ===== Opgave ===== - Opret en `HealthPotion.tres` baseret på `PotionItem`. - Placér en potion i én scene og et sværd i en anden. - Saml begge items op. - Skift mellem scenerne, og kontrollér, at inventory stadig indeholder begge items. - Forklar, hvorfor `InventoryManager` skal være en Autoload, og hvorfor det er praktisk at lade inventory indeholde `Item` i stedet for kun `WeaponItem`. ===== Opsummering ===== * `Item` er basisklassen for alle items. * `InventoryManager` holder styr på spillerens items. * Autoload gør inventory tilgængeligt fra alle scener og bevarer det under sceneskift. * Et save/load-system er nødvendigt, hvis inventory også skal overleve, at spillet lukkes.