Na wstępnie chciałbym zaznaczyć, że próbując zrozumieć tablice musimy mieć podstawowe (choć w pełni opanowane) informacje co do zwyczajnych zmiennych.
Zakładam również, że wiemy jak wyglądają tablice oraz znamy zasadę liczenia od 0.
Po przeczytaniu tego przyjdzie czas na poprawną naukę - to tylko wstęp, do którego można wracać i uzupełniać wiedzę.
Czym są tablice?
Tablice to nic innego jak zbiór wielu wartości w jednej zmiennej. Pozwalają nam na przechowywanie wielu danych z mniejszą ilością kodu, a co najważniejsze - pozwalają nam na zapis stringów (a właściwie napisów, nie stringów, bo to nie to samo [przynajmniej w tym przypadku]).
Żeby w pełni zrozumieć zasadę tablic, trzeba uciec się do zrozumienia tego, jak zbudowany jest język, w którym piszemy.
AMXX (lub też pawn) zmienne przechowuje w czymś, co nazywamy komórką ('cell', z j. ang.), w której przetrzymuje tylko i wyłącznie jedną wartość.
Pojęcia
- Rozmiar tablicy - jest to maksymalna ilość komórek, jakie udostępni nam dana tablica.
- Typ danych tablicy - typ danych, jakie przechowuje tablica. Cała tablica musi przechowywać ten sam typ danych. (przykładowo Float - dla liczb zmiennoprzecinkowych, bool - dla wartości logicznych)
- Indeks gracza - unikalny identyfikator gracza przypisywany do niego przy wejściu na serwer (min. 1 max. 32)
- Indeks tablicy - identyfikator 'pola', z którego chcemy wyciągnąć dane z tablicy
- charsmax - funkcja w amxx zwracająca maksymalną ilość wartości, jaką możemy 'włożyć' do tablicy
Jak działają tablice?
Sprawa jest bardzo prosta, choć często wyolbrzymiana do tego stopnia, że niejeden sobie odpuścił i zrobił tak:
Zwykła zmienna będzie miała możliwość przechowania tylko jednej wartości w ten sposób:
Zmienna o nazwie 'var' przechowująca wartość '5'.
new var = 5;
Tablice dają nam możliwość przechowania więcej niż jednej wartości, w ten sposób:
Tablica o nazwie 'arr' przechowująca wartości '5' i '6' na indeksach '0' i '1'.
new arr[2]; // Inicjacja tablicy o rozmiarze 2. arr[0] = 5; // Przypisywanie wartosci '5' do indeksu '0' tablicy 'arr'. arr[1] = 6; // Przypisywanie wartosci '6' do indeksu '1' tablicy 'arr'.
Możemy ich używać np. do przechowywania informacji o graczach. W tym celu musimy stworzyć tablicę o wielkości o 1 większej niż ilość graczy (domyślnie 32).
Stwórzmy trzy tablice, które będą przechowywać:
- Pieniądze gracza (float)
new Float:userMoney[33];
- Poziom gracza (int)
new userLevel[33];
- Informacje czy gracz ma vipa (bool)
new bool:isVip[33];
Dlaczego rozmiar to 33:
- Maksymalna ilość graczy to 32
- Liczymy od zera (tak wiec jeśli dalibyśmy 32, gracz z indeksem 32 byłby powodem wyjścia poza wielkość tablicy)
Przypuśćmy, że na serwerze mamy obecnych trzech graczy. Oto ich dane dla poszczególnych tablic:
// Gracz o indeksie 1: userMoney[index] = 7.15; userLevel[index] = 10; isVip[index] = false; // Gracz o indeksie 2: userMoney[index] = 4.19; userLevel[index] = 3; isVip[index] = true; // Gracz o indeksie 3: userMoney[index] = 9.18; userLevel[index] = 9; isVip[index] = true;
Jak wygląda to od strony tablicy:
userMoney[0] = 0.0; userMoney[1] = 7.15; userMoney[2] = 4.19; userMoney[3] = 9.18; userLevel[0] = 0; userLevel[1] = 10; userLevel[2] = 3; userLevel[3] = 9; isVip[0] = false; isVip[1] = false; isVip[2] = true; isVip[3] = true;
Dlaczego wszystkie pola z indeksem '0' są równe zero? Dlatego, że nigdy ich nie ustawiliśmy. Gracze na serwerze mają indeksy 1, 2 oraz 3, tak więc tylko te indeksy tablicy będą zmienione.
Napisy
Sprawa z napisami nie jest skomplikowana. Oczywistym powinno już być, że do przechowania napisu musimy mieć tablicę.
Przykładowym napisem będzie "amxx" - chcemy go zapisać do tablicy.
Tworzenie tablicy o wielkości 10, żeby na pewno zmieścić nasz napis:
new text[10];
Dodawanie napisu:
formatex(text, charsmax(text), "amxx");
Gotowe - ale co tak naprawdę się stało; do tablicy 'text' przypisane zostały litery, więc tablica teraz wygląda tak:
text[0] = 'a'; text[1] = 'm'; text[2] = 'x'; text[3] = 'x';
Dostęp do konkretnych wartości
Aby dostać się do konkretnych wartości, jakie przechowuje tablica musimy mieć indeks - numer 'pola' w tablicy, z którego chcemy wyciągnąć dane.
W przypadku graczy nie jest to dużym problemem - wystarczy podać indeks gracza, a w rezultacie otrzymamy jego dane (dlatego, że byliśmy mądrzejsi i zrobiliśmy tablicę o rozmiarze 33, a nie 32).
Jeśli chodzi o pozostałe przypadki, tutaj sprawa się komplikuje - choć nieznacznie.
Wystarczy nam tylko trzeźwe myślenie i trochę wyobraźni.
Aby wyświetlić napis, musimy do funkcji wyświetlającej podać jako argument tę tablicę, w której przechowywany jest dany napis, na którym nam zależy - w tym przypadku nie musimy podawać indeksu, bo nie chcemy pobierać jednej wartości, ale każdą komórkę. (nie chcemy wyświetlać jednej litery, tylko cały napis)
W amxxie nie możemy zwrócić napisu, bo jest to tablica (a zwrócić możemy tylko jedną wartość). Obejściem tego problemu jest przekazywanie tablicy.
Sposób zły (zwracający tylko jedną wartość, w przypadku napisu tylko jedną literę):
Sposób dobry:
Sedno - przykłady
Przechowywanie danych o statusie vip każego gracza z osobna:
Wyświetlanie napisu "Informacja w konsoli serwera" w konsoli serwera:
Zwiększanie kasy graczowi, który wpisze komendę (z ograniczeniem do jednego na mapę) [nie zwracać uwagi na sam fakt, że można to obejść reconnectując, to tylko przykład :) ]:
Formatowanie tekstu "amxx" w funkcji:
Poszczególne indeksy (dla zobrazowania tablicy):
Wyobrażenie tablicy kluczem do jej zarządzania
Jeśli będziemy w stanie wyobrazić sobie jak wygląda tablica, z łatwością będziemy mogli nią zarządzać.
Tablica o rozmiarze 4, która przechowuje dane 3 graczy:
new userData[4]; userData[0] = 0; userData[1] = 100; userData[2] = 25; userData[3] = 7;
Żeby dostać się do poszczególnych wartości, wystarczy, że jako indeks pola użyjemy indeksu gracza:
userData[index];
Jeśli jesteśmy sami na serwerze, nasz indeks będzie (prawdopodobnie) 1, tak więc operacja pokazana powyżej zwróci 100.
Lektura wyczerpująca, niedokładna i pewnie nudna - dlatego jest to tylko wstęp, a o właściwe korzystanie z tablic należy zadbać samemu. Zadawanie pytań na forum nie jest niczym złym, do tego też zachęcamy.
Użytkownik aSiorr edytował ten post 17.08.2019 14:34