Ekwpiunek i statystyki
Wtorek, 11 Czerwca 2024, 22:52
Czas czytania 9 minut, 32 sekundy
Zgodne z GM:
Opis tego jak stworzyć ekwipunek i statystyki postaci.
Mamy już na GMCLANie artykuł o tym jak stworzyć inwentory, a teraz przyszedł czas na ekwipunek. Oba systemy można ze sobą połączyć, lub używać rozdzielnie. Dla uproszenia, w tym artykule założymy, że nie będzie istniał plecak, a zdobyty przedmiot będziemy mogli wymieniać.
Baza przedmiotów
Po pierwsze, musimy stworzyć bazę przedmiotów. W przeciwieństwie do przykładu z inventory, nie wystarczy nam lista spritów czy obiektów - itemy muszą bowiem mieć swoje statystyki.
Itemy muszą gdzieś trafić - potrzebujemy dwóch rzeczy - tablicy z ID itemów jakie obecnie są wyekwipowane (-1 gdy żaden), oraz typów slotów, żeby przedmioty automatycznie trafiały w dobre miejsca.
Ja uznałem, że przygotujemy sloty na: hełm, miecz, zbroję, tarczę, spodnie, buty.
Skrypt
Tworzymy nowy skrypt i definiujemy wspominany enum.
kod// defnicja miejsc, w ktore moga trafic itemy
enum slot_type {
helmet,
sword,
armor,
shield,
pants,
boots,
__size, // bedziemy uzywac tego enuma gdy trzeba policzyć ilość elementów; tutaj __size = 6
}
Wskazówka:
Ponieważ enum działa podobnie do #macro - w momencie kompilacji enumy zamieniane są na kolejne liczby rzeczywiste - w grze nie istnieje możliwość policzenia ile elementów miał enum. Wystarczy jednak dodać na końcu jakiś dodatkowy element, który po konwersji będzie podobnie jak przy tablicach oznaczał, ile jest elementów i poniżej jakiego elementu wykonywać pętle for.
Teraz stworzymy konstruktor, który będzie tworzył nam structy z definicją itemów.
kod/// @desc konstruktor dla itemów
/// @param {String} _name Nazwa
/// @param {Asset.GMSprite} _sprite Sprite
/// @param {Enum.slot_type} _slot Slot (slot_type. )
/// @param {Real} _atk Atak
/// @param {Real} _def Defensywa
function item(_name, _sprite, _slot = slot_type.sword, _atk = 0, _def = 0) constructor {
name = _name;
atk = _atk;
def = _def;
sprite = _sprite;
slot = _slot;
}W tym przykładzie itemy będą mieć tylko dwie statystyki - atk i def, czyli atak i defensywę.
Następnie stworzymy definicję zmiennych gracza - jego ataku, defensywy i ewkipunku:
kod// statsy gracza
global.atk = 0;
global.def = 0;
// definicja itemów i ekwipunku
global.equipment = array_create(slot_type.__size, -1); // tablica o rozmiarze 6, indeksy od 0 - 5A na koniec stworzymy tablicę, w której znajdą się structy z itemami. ID itemów będą indeksy tej tablicy.
kodglobal.items = [
new item("Hełm (srebro)", spr_helmet, slot_type.helmet, 0, 2),
new item("Miecz (brąz)", spr_sword_brown, slot_type.sword, 2, 0),
new item("Miecz (srebro)", spr_sword_silver, slot_type.sword, 5, 0),
new item("Zbroja (brąz)", spr_armor_brown, slot_type.armor, 0, 5),
new item("Zbroja (srebro)", spr_armor_silver, slot_type.armor, 0, 10),
new item("Tarcza (srebro)", spr_shield_silver, slot_type.shield, 0, 2),
new item("Tarcza (złoto)", spr_shield_gold, slot_type.shield, 0, 5),
new item("Nogawki (brąz)", spr_pants_brown, slot_type.pants, 0, 1),
new item("Nogawki (srebro)", spr_pants_silver, slot_type.pants, 0, 2),
new item("Buty (brąz)", spr_boots_silver, slot_type.boots, 0, 2),
new item("Buty (srebro)", spr_boots_silver, slot_type.boots, 0, 2),
];Zatem Hełm ze srebra to item 0, a Buty ze srebra to 10 (bo to 11 element).
Potrzebujemy jeszcze 3 funkcji - tworzącej przedmioty na ziemi (wykorzystamy ją na starcie gry, oraz wyrzucając ekwipunek), funkcji dodawania i usuwania ekwipunku.
Tworzenie przedmiotu:
kod/// @desc Tworzy item na ziemi
/// @param {Real} _item_id id itemu w global.inventory
function create_item(_item_id) {
return instance_create_layer(irandom_range(300, 900), irandom_range(200, 500), layer, obj_item, {item_id: _item_id});
}
Dodanie itemu do ekwipunku (po kliknięciu, ale można też wymusić jakiś item w dowolnym momencie gry). Ponieważ za chwilę dodamy funkcję do usuwania przedmiotu z ekwipunku, skorzystamy z niej i jeśli coś już aktualnie jest w ekwipunku, wyrzucimy to - to raptem 2 dodatkowe linijki kodu.
Wskazówka:
Jeśli nie chcesz takiej funkcji i gracz ma ręcznie wyrzucić item zanim doda nowy, wystarczy zakomentować pierwszego ifa.kod/// @desc Ekwpuje item
/// @param {Real} _item_id id itemu w global.inventory
/// @returns {Bool}
function item_equip(_item_id) {
var _slot = global.items[_item_id].slot; // w jaki slot władować
// usuń jeśli coś już jest
if (global.equipment[_slot] != -1) {
item_remove(_slot);
}
global.equipment[_slot] = _item_id; // ustal jaki item jest teraz w tym slocie
// zwieksz statsy
global.atk += global.items[_item_id].atk;
global.def += global.items[_item_id].def;
return true;
}Następnie, usuwanie itemu z danego slotu ekwipunku - oczywiście o ile coś tam jest (-1 oznacza, że nic).
kod/// @desc Usuwa item z ekwipunku
/// @param {Real} _slot numer slotu w global.equipment
/// @returns {Bool} Zwraca czy usunieto item
function item_remove(_slot) {
if (global.equipment[_slot] == -1) {
return false; // juz jest pusty
}
var _item_id = global.equipment[_slot]; // sprawdź jaki item jest w tym slocie
// ZMNIEJSZ statsy
global.atk -= global.items[_item_id].atk;
global.def -= global.items[_item_id].def;
create_item(_item_id); // wyrzuc na ziemię
global.equipment[_slot] = -1; // ustaw, ze nic tu nie ma
return true;
}
Na koniec dodamy jeszcze jedną funkcję pomocniczą, która wyświetli nam opis przedmiotu obok kursora myszy:
kod/// @desc Rysuje opis itemu
/// @param {Real} _item_id id itemu w global.inventory
function item_desc_draw(_item_id) {
/// ustaw kolor i font
draw_set_color(c_white);
draw_set_font(fnt_main);
/// ustaw opis
var _desc = $"{global.items[_item_id].name}\nAtk: {global.items[_item_id].atk}, Def: {global.items[_item_id].def}";
/// rysuj, podążaj za kursorem
draw_text(mouse_x + 20, mouse_y + 10, _desc);
}
To już wszystko co dodawaliśmy w skrypcie
Przy okazji, w funkcji rysowania zauważyliście może, że wymuszam czcionkę
- Add (Add new range)
- From Code, Add Range
Można zamknąć okno czcionek.
Teraz przejdziemy do programowania obiektów.
Obiekt - item
Pierwszy z obiektów jest bardzo prosty - to obiekt item. Będzie posiadał zmienną
Tworzymy więc
Event Create
Sprawdzamy, czy przy
kodif (item_id == -1) {
instance_destroy();
}
sprite_index = global.items[item_id].sprite;
Draw
Rysujemy item, a jeśli akurat jest nad nim kursor myszy, pokazujemy opis:
koddraw_self();
if position_meeting(mouse_x, mouse_y, self) {
item_desc_draw(item_id);
}
Left Pressed
Jeśli wciśnięto lewy przycisk myszy na danym itemie - dodajmy go do ekwipunku i niszczymy item w grze:
kod/// @desc ekwipuj
item_equip(item_id);
instance_destroy();
Wyświetlanie ekwipunku
Teraz sprawa najtrudniejsza, ale i najważniejsza - wyświetlanie ekwipunku na ekranie. Część kodu będzie przypominać ten dotyczący wyświetlania inventory z przykładu który wcześniej wspomniałem. Zaczniemy jednak od tego, że nasz obiekt na start stworzy nam po 1 sztuce każdego możliwego itemu na obszarze gry.
Tworzymy obiekt
Event Create
kod/// stwórz po 1 sztuce każdego itemu
var n = array_length(global.items);
for(var i = 0; i < n; i++) {
create_item(i);
}
Draw GUI
Teraz czas na rysowanie.
Ponieważ itemy mogą być wyświetlane na tle postaci, odpowiednie sloty muszą wylądować w odpowiednich miejscach.
Wykonamy pewną sztuczkę - zamiast rysować po kolei każdy z 6 slotów, narysujemy ich nieco więcej - aż 12.
Stworzymy jednak tymczasową tablicę, która będzie trzymała informację w jakim kwadracie jest jaki slot, a jeśli w danym kwadracie nie ma być nic wyświetlane, wpiszemy tam -1.
Zamiast więc wyświetlać ekwipunek na pozycjach 0 - 6, wyświetlimy go na pozycjach 1, 3, 4, 5, 7, 10.
Następnie, w pętli, odczytamy jaki "faktycznie" slot ma być w danym miejscu i na tej podstawie wyświetlimy już prawidłowy element z ekwipunku.
kod// ustal w którym kwadracie będzie widoczny item z jakiego slotu
var slot_id = [
-1, slot_type.helmet, -1,
slot_type.sword, slot_type.armor, slot_type.shield,
-1, slot_type.pants, -1,
-1, slot_type.boots, -1,
];Teraz przygotujemy tymczasowe zmienne:
kod// przygotuj zmiene tymczasowe
var row = 0, col = 0; // rząd, kolumna komórki
var n = array_length(slot_id); // ilosc tablicy ze slotami
var xx = 0, yy = 0; // x i y aktualnej komórki
var hover = false; // czy kursor najechał
A następnie narysujemy cały ekwipunek. Jak już wspomniałem, jeśli dany slot_id = -1, pomijamy rysowanie korzystając z instrukcji
Standardowo sprawdzimy też czy najeżdżamy kursorem - jeśli tak, to zmieniamy obwódkę prostokątu na czerwono. Jeśli jest tam jakiś item, dodatkowo klikając PRAWYM przyciskiem myszy, możemy go usunąć z tego slotu.
kod/// pętla rysująca przedmioty
for(var i = 0; i < n; i++) {
if (slot_id[i] == -1) {
// w tym slocie nie ma zadnego typu itemu, pomiń
continue;
}
// rysuj w prostokacie, max 3 sloty na linię
col = i mod 3;
row = i div 3;
// pozycja slotu
xx = 10 + col * 40; // 40, bo 32 + 8 pikseli marginesu
yy = 10 + row * 40;
// sprawdź kursor
hover = false;
draw_set_color(c_gray);
// jeśli kursor najechał
if (mouse_x >= xx and mouse_x < xx + 32) {
if (mouse_y >= yy and mouse_y < yy + 32) {
hover = true;
draw_set_color(c_red);
}
}
// rysuj prostokąt
draw_rectangle(xx, yy, xx + 32, yy + 32, true);
// sprawdź czy w tym slocie jest jakiś item
var _item_id = global.equipment[ slot_id[i] ]; // mapuj slot w tym kwadracie na ekwipunek
// jeśli jest, narysuj go
if (_item_id != -1) {
draw_sprite(global.items[ _item_id ].sprite, 0, xx, yy);
// jeśli kursor najechał, dodatkowo pokaż opis
if (hover) {
item_desc_draw(_item_id);
// jeśli kursor najechał i wciśnięto PPM, usuń item
if (mouse_check_button_pressed(mb_right)) {
item_remove(slot_id[i]);
}
}
}
}
Na koniec wyświetlimy jeszcze globalne statystyki gracza, żeby sprawdzić, czy dodawanie i usuwanie itemów zwiększa/zmniejsza atak i defensywę.
kod// statystyki gracza
draw_set_color(c_white);
draw_set_font(fnt_main);
var _stats = $"Atak: {global.atk}\nObrona: {global.def}";
draw_text(10, 180, _stats);
Uff, prawie 70 linijek za nami i... niemal wszystko gotowe.
Wystarczy teraz dodać
Gotowy projekt (GM 2024.4) pobierzesz tutaj: gmclan.org/upload/gm/gmclan_equipment.yyz .
Baza przedmiotów
Po pierwsze, musimy stworzyć bazę przedmiotów. W przeciwieństwie do przykładu z inventory, nie wystarczy nam lista spritów czy obiektów - itemy muszą bowiem mieć swoje statystyki.
Itemy muszą gdzieś trafić - potrzebujemy dwóch rzeczy - tablicy z ID itemów jakie obecnie są wyekwipowane (-1 gdy żaden), oraz typów slotów, żeby przedmioty automatycznie trafiały w dobre miejsca.
Ja uznałem, że przygotujemy sloty na: hełm, miecz, zbroję, tarczę, spodnie, buty.
Skrypt
scr_items
Tworzymy nowy skrypt i definiujemy wspominany enum.
kod// defnicja miejsc, w ktore moga trafic itemy
enum slot_type {
helmet,
sword,
armor,
shield,
pants,
boots,
__size, // bedziemy uzywac tego enuma gdy trzeba policzyć ilość elementów; tutaj __size = 6
}
Wskazówka:
Ponieważ enum działa podobnie do #macro - w momencie kompilacji enumy zamieniane są na kolejne liczby rzeczywiste - w grze nie istnieje możliwość policzenia ile elementów miał enum. Wystarczy jednak dodać na końcu jakiś dodatkowy element, który po konwersji będzie podobnie jak przy tablicach oznaczał, ile jest elementów i poniżej jakiego elementu wykonywać pętle for.
Teraz stworzymy konstruktor, który będzie tworzył nam structy z definicją itemów.
kod/// @desc konstruktor dla itemów
/// @param {String} _name Nazwa
/// @param {Asset.GMSprite} _sprite Sprite
/// @param {Enum.slot_type} _slot Slot (slot_type. )
/// @param {Real} _atk Atak
/// @param {Real} _def Defensywa
function item(_name, _sprite, _slot = slot_type.sword, _atk = 0, _def = 0) constructor {
name = _name;
atk = _atk;
def = _def;
sprite = _sprite;
slot = _slot;
}W tym przykładzie itemy będą mieć tylko dwie statystyki - atk i def, czyli atak i defensywę.
Następnie stworzymy definicję zmiennych gracza - jego ataku, defensywy i ewkipunku:
kod// statsy gracza
global.atk = 0;
global.def = 0;
// definicja itemów i ekwipunku
global.equipment = array_create(slot_type.__size, -1); // tablica o rozmiarze 6, indeksy od 0 - 5A na koniec stworzymy tablicę, w której znajdą się structy z itemami. ID itemów będą indeksy tej tablicy.
kodglobal.items = [
new item("Hełm (srebro)", spr_helmet, slot_type.helmet, 0, 2),
new item("Miecz (brąz)", spr_sword_brown, slot_type.sword, 2, 0),
new item("Miecz (srebro)", spr_sword_silver, slot_type.sword, 5, 0),
new item("Zbroja (brąz)", spr_armor_brown, slot_type.armor, 0, 5),
new item("Zbroja (srebro)", spr_armor_silver, slot_type.armor, 0, 10),
new item("Tarcza (srebro)", spr_shield_silver, slot_type.shield, 0, 2),
new item("Tarcza (złoto)", spr_shield_gold, slot_type.shield, 0, 5),
new item("Nogawki (brąz)", spr_pants_brown, slot_type.pants, 0, 1),
new item("Nogawki (srebro)", spr_pants_silver, slot_type.pants, 0, 2),
new item("Buty (brąz)", spr_boots_silver, slot_type.boots, 0, 2),
new item("Buty (srebro)", spr_boots_silver, slot_type.boots, 0, 2),
];Zatem Hełm ze srebra to item 0, a Buty ze srebra to 10 (bo to 11 element).
Potrzebujemy jeszcze 3 funkcji - tworzącej przedmioty na ziemi (wykorzystamy ją na starcie gry, oraz wyrzucając ekwipunek), funkcji dodawania i usuwania ekwipunku.
Tworzenie przedmiotu:
kod/// @desc Tworzy item na ziemi
/// @param {Real} _item_id id itemu w global.inventory
function create_item(_item_id) {
return instance_create_layer(irandom_range(300, 900), irandom_range(200, 500), layer, obj_item, {item_id: _item_id});
}
Dodanie itemu do ekwipunku (po kliknięciu, ale można też wymusić jakiś item w dowolnym momencie gry). Ponieważ za chwilę dodamy funkcję do usuwania przedmiotu z ekwipunku, skorzystamy z niej i jeśli coś już aktualnie jest w ekwipunku, wyrzucimy to - to raptem 2 dodatkowe linijki kodu.
Wskazówka:
Jeśli nie chcesz takiej funkcji i gracz ma ręcznie wyrzucić item zanim doda nowy, wystarczy zakomentować pierwszego ifa.kod/// @desc Ekwpuje item
/// @param {Real} _item_id id itemu w global.inventory
/// @returns {Bool}
function item_equip(_item_id) {
var _slot = global.items[_item_id].slot; // w jaki slot władować
// usuń jeśli coś już jest
if (global.equipment[_slot] != -1) {
item_remove(_slot);
}
global.equipment[_slot] = _item_id; // ustal jaki item jest teraz w tym slocie
// zwieksz statsy
global.atk += global.items[_item_id].atk;
global.def += global.items[_item_id].def;
return true;
}Następnie, usuwanie itemu z danego slotu ekwipunku - oczywiście o ile coś tam jest (-1 oznacza, że nic).
kod/// @desc Usuwa item z ekwipunku
/// @param {Real} _slot numer slotu w global.equipment
/// @returns {Bool} Zwraca czy usunieto item
function item_remove(_slot) {
if (global.equipment[_slot] == -1) {
return false; // juz jest pusty
}
var _item_id = global.equipment[_slot]; // sprawdź jaki item jest w tym slocie
// ZMNIEJSZ statsy
global.atk -= global.items[_item_id].atk;
global.def -= global.items[_item_id].def;
create_item(_item_id); // wyrzuc na ziemię
global.equipment[_slot] = -1; // ustaw, ze nic tu nie ma
return true;
}
Na koniec dodamy jeszcze jedną funkcję pomocniczą, która wyświetli nam opis przedmiotu obok kursora myszy:
kod/// @desc Rysuje opis itemu
/// @param {Real} _item_id id itemu w global.inventory
function item_desc_draw(_item_id) {
/// ustaw kolor i font
draw_set_color(c_white);
draw_set_font(fnt_main);
/// ustaw opis
var _desc = $"{global.items[_item_id].name}\nAtk: {global.items[_item_id].atk}, Def: {global.items[_item_id].def}";
/// rysuj, podążaj za kursorem
draw_text(mouse_x + 20, mouse_y + 10, _desc);
}
To już wszystko co dodawaliśmy w skrypcie
scr_items
, można go zamknąć. Razem powinno tam być 5 funkcji, 4 zmienne globalne (poza funkcjami) i enum.Przy okazji, w funkcji rysowania zauważyliście może, że wymuszam czcionkę
fnt_main
. To dlatego, że domyślny GMowy font nie obsługuje polskich znaków diakrytycznych, więc aby je wyświetlić, należy stworzyć nową czcionkę fnt_main
, oraz wybrać w niej:- Add (Add new range)
- From Code, Add Range
Można zamknąć okno czcionek.
Teraz przejdziemy do programowania obiektów.
Obiekt - item
Pierwszy z obiektów jest bardzo prosty - to obiekt item. Będzie posiadał zmienną
item_id
, ale skorzystamy z funkcjonalności GMa która pozwala nam przekazać zmienną w trakcie tworzenia obiektu, przed eventem Create i w tym evencie sprawdzić, czy została ona ustawiona.Tworzymy więc
obj_item
i otwieramy okno Variable Definitions. Tam dodajemy zmienną item_id
, typu Real, o domyślnej wartości -1
.Event Create
Sprawdzamy, czy przy
instance_create_layer()
przekazano id_itemu i jeśli tak - ustawiamy sprite tego obiektu, jeśli nie - niszczymy go:kodif (item_id == -1) {
instance_destroy();
}
sprite_index = global.items[item_id].sprite;
Draw
Rysujemy item, a jeśli akurat jest nad nim kursor myszy, pokazujemy opis:
koddraw_self();
if position_meeting(mouse_x, mouse_y, self) {
item_desc_draw(item_id);
}
Left Pressed
Jeśli wciśnięto lewy przycisk myszy na danym itemie - dodajmy go do ekwipunku i niszczymy item w grze:
kod/// @desc ekwipuj
item_equip(item_id);
instance_destroy();
Wyświetlanie ekwipunku
Teraz sprawa najtrudniejsza, ale i najważniejsza - wyświetlanie ekwipunku na ekranie. Część kodu będzie przypominać ten dotyczący wyświetlania inventory z przykładu który wcześniej wspomniałem. Zaczniemy jednak od tego, że nasz obiekt na start stworzy nam po 1 sztuce każdego możliwego itemu na obszarze gry.
Tworzymy obiekt
obj_equipment
.Event Create
kod/// stwórz po 1 sztuce każdego itemu
var n = array_length(global.items);
for(var i = 0; i < n; i++) {
create_item(i);
}
Draw GUI
Teraz czas na rysowanie.
Ponieważ itemy mogą być wyświetlane na tle postaci, odpowiednie sloty muszą wylądować w odpowiednich miejscach.
Wykonamy pewną sztuczkę - zamiast rysować po kolei każdy z 6 slotów, narysujemy ich nieco więcej - aż 12.
Stworzymy jednak tymczasową tablicę, która będzie trzymała informację w jakim kwadracie jest jaki slot, a jeśli w danym kwadracie nie ma być nic wyświetlane, wpiszemy tam -1.
Zamiast więc wyświetlać ekwipunek na pozycjach 0 - 6, wyświetlimy go na pozycjach 1, 3, 4, 5, 7, 10.
Następnie, w pętli, odczytamy jaki "faktycznie" slot ma być w danym miejscu i na tej podstawie wyświetlimy już prawidłowy element z ekwipunku.
kod// ustal w którym kwadracie będzie widoczny item z jakiego slotu
var slot_id = [
-1, slot_type.helmet, -1,
slot_type.sword, slot_type.armor, slot_type.shield,
-1, slot_type.pants, -1,
-1, slot_type.boots, -1,
];Teraz przygotujemy tymczasowe zmienne:
kod// przygotuj zmiene tymczasowe
var row = 0, col = 0; // rząd, kolumna komórki
var n = array_length(slot_id); // ilosc tablicy ze slotami
var xx = 0, yy = 0; // x i y aktualnej komórki
var hover = false; // czy kursor najechał
A następnie narysujemy cały ekwipunek. Jak już wspomniałem, jeśli dany slot_id = -1, pomijamy rysowanie korzystając z instrukcji
continue;
, a w przeciwnym wypadku wiemy, że jest to slot z global.inventory
. Wciąż jednak może tam nie być żadnego itemu, dlatego trzeba będzie sprawdzić czy nie jest on równy -1 (ostatni "if").Standardowo sprawdzimy też czy najeżdżamy kursorem - jeśli tak, to zmieniamy obwódkę prostokątu na czerwono. Jeśli jest tam jakiś item, dodatkowo klikając PRAWYM przyciskiem myszy, możemy go usunąć z tego slotu.
kod/// pętla rysująca przedmioty
for(var i = 0; i < n; i++) {
if (slot_id[i] == -1) {
// w tym slocie nie ma zadnego typu itemu, pomiń
continue;
}
// rysuj w prostokacie, max 3 sloty na linię
col = i mod 3;
row = i div 3;
// pozycja slotu
xx = 10 + col * 40; // 40, bo 32 + 8 pikseli marginesu
yy = 10 + row * 40;
// sprawdź kursor
hover = false;
draw_set_color(c_gray);
// jeśli kursor najechał
if (mouse_x >= xx and mouse_x < xx + 32) {
if (mouse_y >= yy and mouse_y < yy + 32) {
hover = true;
draw_set_color(c_red);
}
}
// rysuj prostokąt
draw_rectangle(xx, yy, xx + 32, yy + 32, true);
// sprawdź czy w tym slocie jest jakiś item
var _item_id = global.equipment[ slot_id[i] ]; // mapuj slot w tym kwadracie na ekwipunek
// jeśli jest, narysuj go
if (_item_id != -1) {
draw_sprite(global.items[ _item_id ].sprite, 0, xx, yy);
// jeśli kursor najechał, dodatkowo pokaż opis
if (hover) {
item_desc_draw(_item_id);
// jeśli kursor najechał i wciśnięto PPM, usuń item
if (mouse_check_button_pressed(mb_right)) {
item_remove(slot_id[i]);
}
}
}
}
Na koniec wyświetlimy jeszcze globalne statystyki gracza, żeby sprawdzić, czy dodawanie i usuwanie itemów zwiększa/zmniejsza atak i defensywę.
kod// statystyki gracza
draw_set_color(c_white);
draw_set_font(fnt_main);
var _stats = $"Atak: {global.atk}\nObrona: {global.def}";
draw_text(10, 180, _stats);
Uff, prawie 70 linijek za nami i... niemal wszystko gotowe.
Wystarczy teraz dodać
obj_equipment
do Roomu i odpalić grę.Gotowy projekt (GM 2024.4) pobierzesz tutaj: gmclan.org/upload/gm/gmclan_equipment.yyz .