Jak stworzyć prosty system ekwipunku w Godot 4?

Ekwipunek to system przechowujący przedmioty posiadane przez gracza. Może być bardzo prosty, na przykład lista nazw przedmiotów, albo rozbudowany, z ikonami, slotami, wagą, opisami, przeciąganiem myszką i przedmiotami zużywalnymi.

W tym artykule stworzymy prosty system ekwipunku w Godot 4. Będzie on pozwalał dodawać przedmioty, usuwać je oraz sprawdzać, czy gracz posiada konkretny przedmiot.

Przykładowa struktura gracza ----------------------------

Player CharacterBody2D ├── Sprite2D ├── CollisionShape2D └── InventoryComponent Node

Tak jak w przypadku zdrowia i ataku, ekwipunek warto zrobić jako osobny komponent. Dzięki temu główny skrypt gracza nie będzie przeładowany dodatkowymi funkcjami.

Skrypt InventoryComponent.gd ----------------------------

extends Node

signal inventory\ changed items: Array\ String\

var items: Array\ String\ = \ \

func add\ item item\ name: String -> void: if item\ name.is\ empty : return

func remove\ item item\ name: String -> void: if not items.has item\ name : return

func has\ item item\ name: String -> bool: return items.has item\ name

func get\ items -> Array\ String\ : return items

Co robi ten skrypt? -------------------

Tablica items przechowuje nazwy przedmiotów. Funkcja add\ item dodaje przedmiot, remove\ item usuwa go, a has\ item sprawdza, czy dany przedmiot znajduje się w ekwipunku.

Sygnał inventory\ changed jest emitowany za każdym razem, gdy zawartość ekwipunku się zmieni. Dzięki temu interfejs ekwipunku może automatycznie się odświeżać.

Przykładowy przedmiot do zebrania ---------------------------------

Utwórz scenę przedmiotu, na przykład ItemPickup.

ItemPickup Area2D ├── Sprite2D └── CollisionShape2D

Do node’a ItemPickup dodaj skrypt:

extends Area2D

@export var item\ name: String = "Klucz"

func \ ready -> void: body\ entered.connect \ on\ body\ entered

func \ on\ body\ entered body: Node -> void: if not body.has\ node "InventoryComponent" : return

var inventory = body.get node "InventoryComponent" inventory.add item item name

queue free

Gdy gracz wejdzie w obszar przedmiotu, przedmiot zostanie dodany do ekwipunku, a obiekt zniknie ze sceny.

Sprawdzanie, czy gracz ma klucz -------------------------------

Załóżmy, że w grze są drzwi, które można otworzyć tylko wtedy, gdy gracz posiada klucz. Można to sprawdzić w taki sposób:

func try\ open\ door player: Node -> void: if not player.has\ node "InventoryComponent" : return

var inventory = player.get node "InventoryComponent"

if inventory.has item "Klucz" : print "Drzwi otwarte" else: print "Potrzebujesz klucza"

Prosty interfejs ekwipunku --------------------------

Do wyświetlania ekwipunku można użyć na przykład VBoxContainer i dodawać do niego etykiety z nazwami przedmiotów.

InventoryUI Control └── ItemListContainer VBoxContainer

Przykładowy skrypt interfejsu:

extends Control

@onready var item\ list\ container: VBoxContainer = $ItemListContainer

func update\ inventory items: Array\ String\ -> void: for child in item\ list\ container.get\ children : child.queue\ free

Jak rozbudować ekwipunek? -------------------------

Prosty system oparty na nazwach jest dobry na początek, ale w większej grze warto stworzyć osobny zasób opisujący przedmiot.

ItemData Resource ├── name ├── description ├── icon ├── max\ stack └── item\ type

Dzięki temu każdy przedmiot może mieć ikonę, opis, typ, wartość, obrażenia albo inne właściwości.

Najczęstsze błędy -----------------

- trzymanie całego ekwipunku w skrypcie gracza,

- brak sygnału informującego interfejs o zmianie ekwipunku,

- brak sprawdzania, czy przedmiot już istnieje,

- mieszanie logiki przedmiotu z logiką GUI,

- brak planu na rozbudowę systemu.

Podsumowanie ------------

Prosty system ekwipunku w Godot 4 można stworzyć bardzo szybko. Wystarczy komponent z tablicą przedmiotów, funkcje dodawania i usuwania oraz sygnał informujący o zmianie ekwipunku. To dobra baza pod bardziej rozbudowany system przedmiotów.

<center <sub Published using <a href=' Publisher</a from <a href='

Komentarze

Ładuję komentarze…