# Implementacja siatkowego inwentarza w GameMaker: analiza krok po kroku
System siatkowego inwentarza pozwala na umieszczanie przedmiotów o różnych rozmiarach w ds_grid, podobnie jak mechaniki w Deus Ex lub S.T.A.L.K.E.R. Na początek utwórz obiekt gracza oPlayer ze sprite'em oraz obiekt kontenera oContainer bez sprite'a domyślnie. Przygotuj sprite'y przedmiotów: spApple (32x32), spWaterBottle (32x64), spMysteriousPackage (64x64), spItemError (32x32). Umieść w pokoju rTest warstwy Instances i UI, dodaj instancje oPlayer i oContainer.
Utwórz persistent-obiekt oGameManager w początkowym pokoju rInit. W zdarzeniu Create:
global.inventoryDebugMode = true;
#macro InteractionDistance 100
global.ItemDB = {};
loadItemDefinitions();
room_goto(rTest);
To inicjalizuje tryb debugowania, stałą odległości interakcji oraz bazę przedmiotów.
Ładowanie bazy przedmiotów z JSON
Umieść plik items.json w datafiles. Struktura przedmiotu obejmuje Name, Type, Width, Height, MaxStack, Sprite, Description. Skrypt scItemDatabase zawiera loadItemDefinitions():
function loadItemDefinitions()
{
var _filename = "items.json";
if (!file_exists(_filename) && global.inventoryDebugMode)
{
show_debug_message("Fayl " + _filename + " nie znaleziony!");
return;
}
var _buffer = buffer_load(_filename);
var _jsonString = buffer_read(_buffer, buffer_string);
buffer_delete(_buffer);
var _parsedData = json_parse(_jsonString);
var _itemIDs = struct_get_names(_parsedData);
for (var i = 0; i < array_length(_itemIDs); ++i)
{
var _id = _itemIDs[i];
var _item = _parsedData[$ _id];
if (variable_struct_exists(_item, "Sprite"))
{
_item.Sprite = asset_get_index(_item.Sprite);
if (_item.Sprite == -1)
{
_item.Sprite = spItemError;
if (global.inventoryDebugMode)
show_debug_message("Withprayt nie znaleziony dla przedmiotu " + _id);
}
}
global.ItemDB[$ _id] = _item;
}
if (global.inventoryDebugMode)
show_debug_message("Baza przedmiotów załadowana. Liczba: " + string(array_length(_itemIDs)));
}
Funkcja getItemData(_itemID) zwraca strukturę przedmiotu lub undefined.
- Zalety ds_struct: dynamiczny dostęp po kluczach stringowych za pomocą [$ _id].
- Obsługa błędów: fallback na spItemError przy braku sprite'a.
- Akcesory: dla ds_grid — [# i, j], dla struct — [$ key].
Podstawy przechowywania przedmiotów w siatce
Inwentarz to ds_grid, gdzie:
- Główna komórka przedmiotu przechowuje struct {itemID, quantity}.
- Pomocnicze komórki — {refX, refY} z współrzędnymi głównej.
- Puste komórki — noone.
Przedmioty uwzględniają Width/Height z bazy oraz MaxStack dla stosów.
Skrypt scInventory zaczyna od podstawowych funkcji:
Tworzenie i niszczenie inwentarza
function inventoryCreate(_width, _height)
{
var grid = ds_grid_create(_width, _height);
ds_grid_clear(grid, noone);
return grid;
}
function inventoryDestroy(_inventory)
{
if (ds_exists(_inventory, ds_type_grid))
{
ds_grid_destroy(_inventory);
return true;
}
else
{
return false;
}
}
Funkcje sprawdzania i manipulacji siatką
Następnie zaimplementuj sprawdzenie pustości:
- inventoryIsEmpty(_inventory): skanuje grid pod kątem noone.
Kluczowe operacje na przedmiotach:
- Dodawanie: poszukiwanie wolnego miejsca według Width/Height, umieszczenie głównej komórki i ref w pozostałych.
- Przemieszczanie: sprawdzenie kolizji, aktualizacja refX/refY.
- Usuwanie: czyszczenie głównej i komórek ref.
Do interakcji: sprawdzenie odległości < InteractionDistance od oPlayer do oContainer.
Wyświetlanie UI inwentarza
Na warstwie UI rysuj siatkę za pomocą draw_sprite_part dla przedmiotów. Obsługuj mouse-over do podświetlenia, drag-and-drop za pomocą global.dragItem.
W oPlayer dodaj inventoryPlayer = inventoryCreate(10, 6); analogicznie dla kontenerów.
Co ważne
- Używaj ds_grid do efektywnego 2D-przechowywania z akcesorami [#x,y].
- Przechowuj tylko itemID/quantity w głównej komórce, resztę — za pomocą getItemData.
- Zapewnij atomowość operacji: sprawdzaj wszystkie komórki przed umieszczeniem.
- DebugMode ułatwia debugowanie ładowania i manipulacji.
- Persistent oGameManager gwarantuje globalny stan ItemDB.
— Editorial Team
Brak komentarzy.