Skocz do zawartości

[PORADNIK] Destroyer nauczy Ciebie scriptingu


Destroyer

Rekomendowane odpowiedzi

Na początek zacznę inaczej troszkę.
Jak wiadomo na forach jest pełno poradników "nauka pisania pluginów" i najróżniejszych porad jak napisać plugin, lecz jak dochodzi co do czego to pojawia nam się w głowie takie duże WTF, co to K** jest za sajgon, łeb boli od widoku i itp.
Nie gwarantuję ,że od razu zaczniesz pisać pluginy bezbłędnie (ucz się na błędach swoich). 
Poradnik pisałem kiedyś ok 3/4 lata temu. 
 

Rozdział 1: Wprowadzenie, operatory
*
*

Co to jest?

To jest pierwszy "rozdział" poradniku "Nauka Scriptingu".

 

Co dzięki niemu możesz (niekoniecznie) zyskać?

 

 

    

  1. Umiejętność logicznego i kreatywnego myślenia.
  2. Utrwalenie podstawowych jak i zaawansowanych operacji arytmetyczno-logicznych.
  3. Podstawy programowania strukturalnego.
  4. Możność pisania, kto wie, może z czasem coraz to bardziej zaawansowanych pluginów przede wszystkim do Counter-Strike 1.6.
  5. W przyszłości łatwość poznawania nowych i odmiennych języków programowania.

 

 

Co dzięki niemu możesz (niekoniecznie) stracić?*

*
Poza czasem, myślę że nic.
Dobrze, skoro już wiecie z czym mniej więcej macie do czynienia, może wypadałoby przybliżyć Wam, co to w ogóle jest Pawn? Otóż Pawn to język skryptowy wykorzystywany w większości przypadków do pisania plug-inów do Counter-Strike 1.6 lub GTA San Andreas Multiplayer. Jak to wygląda i z czym to się je? Nic prostszego! Włączasz edytor obsługujący rozszerzenie .sma
, przystępujesz do pisania kodu źródłowego, po czym kompilujesz4 go! W wyniku takiej kompilacji otrzymujesz plik o rozszerzeniu .amxx, który (jeśli jest napisany dobrze) możesz wgrać na swój własny serwer! Ale bez zbędnej teorii, przejdźmy do spraw gruntownych.

 

 

Żebyś w ogóle mógł zacząć programować drogi użytkowniku potrzebujesz edytora, ja osobiście polecam chyba najbardziej popularny u "Pawn'erów" program AMX Mod X Studio, który możesz pobrać z:
AMX Mod X - Half-Life Scripting for Pros!

Zastanawiasz się teraz pewnie, czy wybrać tylko AMX Mod X Studio, czy może AMX Mod X Full Installer, polecam pobrać Full Installer. Czemu? Żeby móc skompilować nasz kod źródłowy lokalnie potrzebujemy do tego odpowiednich bibliotek, poza tym mając takie biblioteki, nasz edytor jest skłonny do tego, żeby nam pomóc i automatycznie wyświetlać nam składnie funkcji, wraz z jej parametrami. O czym teraz mówię dowiesz się za chwilę.

Pobierz więc AMX Mod X Full Installer i zainstaluj na swoim komputerze. Ważne abyś poprawnie go zainstalował i skonfigurował, a z racji że jest to lekcja programowania, odsyłam do odpowiednich poradników:

zakładam że masz już przed sobą AMX Mod X Studio lub inny edytor, nie będzie nam on jednak na razie potrzebny. Teraz znowu teorii, opowiem jak w moim mniemaniu wyglądać powinno i wygląda programowanie. Wszystko to liczby! Pewnego czasu pisałem trochę dziwny plug-in, ale myślę, że mogę się tym posłużyć, otóż wyobraź sobie, że chcesz podzielić użytkowników na kobiety i mężczyzn i zadał sobie pytanie jak to zrobisz. Uwaga! Zrobisz to na liczbach, przykładowo Twoja kobieta będzie liczbą 1, a mężczyzna liczbą 2! Oczywiście można się bawić w ciągi znaków6, ale jest to mniej optymalne i w finalnym rozrachunku one również stają się liczbami, więc jeśli nie lubisz liczb nie bierz się za programowanie.

 

Co do logicznego myślenia. Jeśli masz z tym problemy polecam najpierw poćwiczyć algorytmikę, gdyż jeżeli chcesz napisać coś sam, najpierw musisz wpaść na pomysł, nie przyjdzie on sam, nie spadnie z nieba, wykonanie go to już inna para kaloszy.

Po tych wszystkich dygresjach czas przejść w końcu do czegoś, co może będzie przydatne, postanowiłem bowiem już w pierwszym rozdziale zawrzeć operatory z którymi będziemy się spotykali cały czas (z niektórymi nieco rzadziej)!
*

  • + dodawanie
  • - odejmowanie
  • * mnożenie
  • / dzielenie
  • % operator modulo (zwraca resztę z dzielenia dwóch liczb)
  • ++ inkrementacja (zwiększenie o 1)
  • -- dekrementacja (zmniejszenie o 1)

(dzielimy je jeszcze na preinkrementacja/postinkrementacje i predekrementacje/postdekrementacje, ale to przy okazji)
*
*

 

  • < mniejszy niż
  • > większy niż
  • == równy
  • >= większy bądź równy
  • <= mniejszy bądź równy
  • || operator logiczny LUB
  • && operator logiczny I

*
*
Myślę, że jeżeli chodzi o operatory to na razie wystarczy, jeśli czytasz to i szukasz tu operatorów bitowych, opiszę je kiedy indziej. Co z typy operatorami? Będą nam one służyły do wykonywania podstawowych działań i (jeśli można to tak nazwać) zapytań logicznych. Proszę pamiętać, że żaden z nich nie ma swojego odpowiednika w innej formie, prócz skróconej, która później.

 

 

Podsumowanie: Jak widzisz, w tym rozdziale nie dowiedziałeś się zbyt wiele, ale cierpliwości! Jest ona bardzo ważna, a zarazem trudna do utrzymania przy sobie. Myśl logicznie i kreatywnie, postrzegaj wszystko, co chcesz napisać przede wszystkim jako liczby i nie poddawaj się!

Co w następnym rozdziale: Co to jest zmienna, jak ją tworzymy, typy zmiennych i operacje na nich.

1 - od ang. wtyczka, na chłopski rozum dodatek/modyfikacja
2 - plik o takim rozszerzeniu, to plik w którym zawarty jest kod źródłowy napisany w języku Pawn, w wyniku kompilacji takiegoż pliku otrzymujemy inny o rozszerzeniu .amxx
3 - kod zrozumiały dla człowieka opisujący operacje, jakie powinien wykonać komputer
4 - proces dzięki któremu otrzymujemy plik zawierający operacje zrozumiałe dla komputera, inna definicja kompilacja to zamiana kodu źródłowego na kod maszynowy
5 - kompilacja lokalna to kompilacja przeprowadzana przez nasz procesor, wykonywana na naszym komputerze
6 - przypadek w którym możemy używać wszystkich dostępnych znaków klawiaturowych, na których później możemy wykonywać odpowiednie operacje
7 - optymalizacja - ulepszanie kodu pod względem jego struktury, oraz działania
*
*
*

Rozdział 2: Co to jest zmienna, typy zmiennych, jak ją tworzymy, operacje na zmiennych
*
*

  • Co to jest zmienna

Bez zbędnego w tym przypadku wstępu, przejdę od razu do rzeczy. Uwaga, jest to moja definicja zmiennej, w żadnym przypadku nie musisz się z nią zgodzić. Zmienna to obiekt (nie mylić z programowaniem obiektowym), który posiada swoją symboliczną nazwę nadaną przez nas, posiada swój obszar widzenia w kodzie źródłowym, najogólniejszym podziałem zmiennej pod tym względem jest

  • zmienna globalna - obejmuje cały program, w całym programie możemy wykonywać na niej operacje

*

  • zmienna lokalna - obejmuje dany blok, w którym została stworzona.

Ostatnim, trzecim atrybutem zmiennej jest jej wartość, w naszym przypadku (Pawn) raz stworzona zmienna przyjmuje wartość początkową 0 - w przypadku zmiennych przechowujących wartości logiczne i liczbowe lub są puste - w przypadku zmiennej (choć w tym przypadku już tablicy) przechowującej ciąg znaków. Po co nam taka zmienna? Zmienne są wykorzystywane do wszelkiego rodzaju operacji arytmetyczno-logicznych, przechowuje się w nich wyniki działań lub same wykorzystywane są do uzyskania wyniku.
*

  • Typy zmiennych i ich tworzenie

W zależności od tego, jaką wartość chcemy przechować w zmiennej, musimy ją stworzyć w inny sposób. Zmienne dzielimy na:

  • Integer - zmienna przechowująca liczbę całkowitą (powtórka z matematyki - liczby całkowite to liczby ujemne i dodatnie bez części dziesiętnej, bez przecinka), zmienna taką tworzymy w następujący sposób:
    new nazwazmiennej

Proste, prawda?

  • Float - zmienna przechowująca liczbę rzeczywistą, a więc w tym przypadku mamy już możliwość przypisania wartości stało lub zmiennoprzecinkowej, zmienną taką tworzymy w następujący sposób:

new Float:nazwazmiennej


Nic prostszego!
*

  • Boolean - zmienna przechowująca wartość logiczną true lub false, czyli odpowiednio 1 lub 0. Wykorzystuje się ją do wszelkiego rodzaju instrukcji warunkowych, zmienną taką tworzymy w następująca sposób:

new bool:nazwazmiennej

I do przodu!
*

  • String - ciąg znaków, przechowujemy je już nie w samych zmiennych, a w tablicach, dlatego o jej deklaracji i operacji na nich, opowiem kiedy indziej.


     
  • Operacje na zmiennych

W tym przypadku posłużę się garścią kodu napisaną przeze mnie, po // są komentarze, które można umieścić w dowolnym momencie kodu i nie wpływają one na jego działanie, komentarze pisze się zazwyczaj przy rozbudowanych funkcjach po to, ażeby ktoś kto widzi pierwszy raz na oczy Twój kod źródłowy, szybciej go pojął!
*

*
new zmiennainteger
new Float:zmiennafloat
new bool:zmienna float
zmiennainteger = 8 // przypisuje zmiennej o symbolicznej nazwie 'zmiennainteger' wartość 8
zmiennafloat = 3.14 // przypisuje zmiennej 'zmiennafloat' wartość 3,14
zmiennabool = true // przypisuje zmiennej 'zmiennabool' wartość logicznej prawdy
zmiennainteger = zmiennainteger + zmiennafloat // taka instrukcja przypisana jest błędna, ponieważ do zmiennej przechowującej liczby całkowite dodaje liczbę z przecinkiem
zmiennainteger = zmiennainteger * zmiennainteger // potęguje zmienną 'zmiennainteger' mnożąc ją samą przez siebie
zmiennafloat = zmiennafloat * 2 // zwiększam wartość zmiennej 'zmiennafloat' dwukrotnie
zmiennabool = false // zmieniam wartość logiczną zmiennej 'zmiennabool' na logiczny fałsz
zmiennafloat = 5 // jest to prawidłowe przypisanie wartości 5 do zmiennej 'zmiennafloat' aczkolwiek przez brak '.0' kompilator zgłosi warning
zmiennainteger++ // inkrementacja (1 rozdział), zwiększa wartość zmiennej 'zmiennainteger' o 1
zmiennainteger-- // dekrementacja (1 rozdział), zmniejsza wartość zmiennej 'zmiennainteger' o 1


*
*
Podsumowanie: Poznałeś właśnie podstawowe operacje na zmiennych, ich typy, oraz w teorii obszar ich "widzenia", nic nie stoi więc na przeszkodzie, abyś wykorzystał je w inny sposób. Jaki? Czytaj dalej....

Co w następnym rozdziale: Instrukcja warunkowa if (jeżeli) i jej podobne, oraz instrukcja warunkowa switch.
*
*
Rozdział 3: Instrukcja warunkowa if i jej podobne, instrukcja warunkowa switch
*
*

  • [*]Instrukcja warunkowa if

Instrukcja warunkowa if (jeżeli) służy do przeprowadzenia dalej części kodu, jeśli zostanie spełniony założony przez nas warunek. Warunki zwracają wartość logiczną Prawda lub Fałsz. Do instrukcji warunkowych często potrzebne są operatory "lub" ( || ) i "i" ( && ). Myślę, że tu przyda się mały przykład, dajmy na to, że dane działanie ma się wyświetlić dla danej wartości liczbowej, instrukcja warunkowa if w takim przypadku będzie wyglądała następująco:
*

new zmienna = (wprowadza użytkownik) 
// załóżmy, że wartość do zmiennej 'zmienna' wprowadza użytkownik
 // składnia instrukcji warunkowej if wygląda następująco: 
// if( warunek ) // { // blok // } if( zmienna == 5 ) { zmienna = zmienna * 2 } // przy instrukcji składającej się z jednej linii kodu/jednego polecenia nie musimy używać klamer, 
dlatego też może ona również wyglądać następująco :
if( zmienna == 5 ) zmienna = zmienna * 2


*
Nie trudno się domyślić, że jeżeli użytkownik wprowadzi liczbę 5, program pomnoży ją przez 2 i zwróci wynik pod postacią zmiennej 'zmienna'. Sprawdźmy teraz, jak będzie to wyglądało dla dwóch mających się spełnić warunków:
*

// jeśli dwa warunki mają się spełnić musimy użyć operatora logicznego "&&", który mnoży dwie wartości i zwraca ich wartość logiczną new zmienna = (wprowadza użytkownik) // załóżmy, że wartość do zmiennej 'zmienna' wprowadza użytkownik if( zmienna > 9 && zmienna < 100 ) { zmienna = zmienna % 10 } // tak jak wcześniej, możemy to zapisać bez klamer if( zmienna > 9 && zmienna < 100 ) zmienna = zmienna % 10


W tym przypadku otrzymamy resztę z dzielenia liczby wprowadzonej przez użytkownika tylko, jeżeli wprowadził on liczbę z zakresu [10; 99] (liczby dwucyfrowe).
Co jeżeli ma się spełnić przynajmniej jeden z dwóch warunków:
*
*

// jeśli z dwóch warunków ma się spełnić przynajmniej jeden z nich, będziemy potrzebowali operatora logicznego "||", który sumuje wprowadzone wartości logiczne i zwraca ich logiczny wynik
new zmienna = (wprowadza użytkownik) // załóżmy, że wartość do zmiennej 'zmienna' wprowadza użytkownik
if( zmienna < 10 || zmienna > 99 )
{
zmienna = zmienna / zmienna
}
// bez klamer
if( zmienna < 10 || zmienna > 99 )
zmienna = zmienna / zmienna


W ostatnim przykładzie, może przetłumaczę instrukcję tak, jak powinieneś ją rozumieć. "Jeżeli zmienna jest mniejsza od 10 lub zmienna jest większa od 99, w takim wypadku przypisz wartość zmiennej 'zmienna' działania "zmienna:zmienna". Oczywiste jest tu, że jeżeli użytkownik wprowadzi liczbę jednocyfrową lub trzycyfrową i wzwyż otrzymamy 1.
*
*

  • Instrukcja warunkowa else if

Jeżeli potrzebujemy przepuścić jakąś wartość, bądź wartości przez kilka warunków, gdzie uważamy, że przynajmniej jeden z nich się spełni, z pomocną dłonią wychodzi nam else if, co powinno się tłumaczyć na: "w przeciwnym przypadku jeżeli". Jeśli się na tym zastanowić, to else if może poniekąd działać podobnie do "||". Przejdźmy do przykładów.

// żeby użyc else if potrzebujemy najpierw warunek początkowy, tworzymy go więc tak jak wcześniej // składnia else if'a jest taka sama jak if'a: //else if( warunek ) //{ // blok //} new zmienna = (wprowadza użytkownik) if( zmienna == 5 ) { zmienna = zmienna * 2 } else if( zmienna > 100 ) { zmienna = zmienna % 10 } //bez klamer if( zmienna == 5 ) zmienna = zmienna * 2 else if( zmienna > 100 ) zmienna = zmienna % 10


Przetłumaczmy to dosłownie. "Jeżeli zmienna jest równa 5, pomnóż ją przez dwie, w przeciwnym przypadku jeżeli jest ona większa od 100, zwróć resztę z dzielenia jej przez 10. W przypadku else if'a możemy tak samo używać operatorów, które poznałeś w pierwszym rozdziale.

  • Instrukcja warunkowa else

Tego typu zwrotu używamy na końcu każdego warunku, jeżeli chcemy, żeby została wykonana jakaś operacja, jeśli każdy z powyższych warunków zawiódł, nie sprawdził się. W przypadku tej instrukcji nie podajemy już żadnego warunku, bo spełni się on dla każdego, niespełnionego wcześniej warunku. Kod z przykładem:

// do użycia else'a potrzebujemy przynajmniej jednego warunku // składnia else'a nie może być prostsza, wygląda tak: // else // { // blok // } new zmienna = (wprowadza użytkownik) if( zmienna == 5 ) { zmienna = zmienna * 2 } else if( zmienna > 99 && zmienna < 1000 ) { zmienna = zmienna / 10 } else { zmienna = 0 } //bez klamer if( zmienna == 5 ) zmienna = zmienna * 2 else if( zmienna > 99 && zmienna < 1000 ) zmienna = zmienna / 10 else zmienna = 0 // do użycia else'a, else if nie był potrzebny


Po przeanalizowaniu tego przykładu powinieneś dojść do takiego wniosku: jeżeli zmienna jest równa 5, pomnóż ją przez dwa, jeżeli zaś jest ona trzycyfrowa podziel ją przez 10, jeżeli nie jest ani równa 5, ani nie jest trzycyfrowa (w przedziale: (-thumb_pre_1357604589__ddd2.gif;5) v (5; 99] v [1000; *thumb_pre_1357604589__ddd2.gif)) przypisz jej wartość 0.

  • [*]Instrukcja warunkowa switch

Instrukcję warunkową switch tłumaczę sobię tak: masz zmienną z jakąś wartością, musisz napisać dla niej instrukcje dla wielu warunków, wrzucasz więc karteczki z możliwymi wartościami tej zmiennej do koszyka i wybierasz którąś z nich, po czym wykonujesz dla niej odpowiednie zadanie. Na początku może się to wydawać trudne, ale w istocie jest prostsze, niż przypuszczasz. Do wytłumaczenia posłużę się kodem z dokładynmi komentarzami:

// składnia instrukcji warunkowej switch // switch( zmienna ) // { // case x: // case y: // case z: // } // case - czyli w przypadku takim, wykonaj to, jeżeli instrukcja jest dłuższa niż jeden wiersz (jedna funkcja/jedna operacja), zamiast samego ":" tworzymy blok: // :{ // blok // } // spróbujmy  new zmienna = (wprowadza użytkownik) switch( zmienna ) //wybierz kartkę { case 1: // jeśli zmienna jest równa 1/wybieramy jedynkę { zmienna = zmienna * 2 } case 2: // jeśli zmienna jest równa 2 { zmienna = zmienna * 10 } case 3, 4, 5: // jeśli zmienna jest równa 3, 4 lub 5 { zmienna = zmienna * zmienna } case 6..10: // jeśli zmienna mieści się w przedziale obustronnie domkniętym [6; 10] { zmienna = 1 } case default: // default działa jak else, czyli ta instrukcja wykona się dla każdej wartości zmiennej nieopisanej powyżej { zmienna = zmienna + zmienna * zmienna } } // bez klamer switch( zmienna) { case 1: zmienna = zmienna * 2 case 2: zmienna = zmienna * 10 case 3, 4, 5: zmienna = zmienna * zmienna case 6..10: zmienna = 1 case default: zmienna = zmienna + zmienna * zmienna }


Tutaj już bez zbędnego komentarza, jeśli tego nie rozumiesz, czytaj do skutku.

Podsumowanie: Jak widzisz, nie jest to aż takie trudne, przynajmniej mam nadzieję, że tak myślisz. Ćwicz do skutku, a na pewno Ci wyjdzie!

Co w następnym rozdziale: Pętle
*
Rozdział 4: Pętle
*

  • Co to jest pętla?

*
Pętla, to pewnego rodzaju operacja, pozwalająca na wykonanie danego zadania określoną ilość razy, często przy zmieniającym się którymś parametrze danego zadania. Prościej? Dajmy na to, że chcesz pewną liczbę pomnożyć dziesięć razy przez kolejne liczby całkowite. Mógłbyś to zapisać jako 10 oddzielnych działań, ale po co, skoro masz do dyspozycji pętle? Pętle należy rozumieć dosłownie. Po każdym obrocie, pętla wykonuje się na nowo, do czasu aż warunek przestanie być spełniany. Z racji, że w przypadku pętli nie mam za dużo do powiedzenia, od razu przejdę do typów pętli i ich wykorzystaniu w praktyce.

W Pawn wyróżniamy trzy typy pętli:
*
*

  • pętla for
  • pętla while
  • pętla do while

W zrozumieniu pętli przyda się również dobra znajomość języka angielskiego, dlatego tu for oznacza dla, while oznacza podczas gdy, a do while - zrób podczas gdy.
*

  • Pętla for

Pętla for będzie działała następująco: "dla jakiejś zmiennej, wtedy kiedy wynosi tyle i zwiększa się o każdy obrót pętli o ileś, zrób blok",
ale co Wam po moim rozumieniu pętli, skoro najlepiej pokazać to na kodzie
*

// załóżmy, że chcemy pokazać użytkownikowi wielokrotności liczby 10, aż do 100
// moglibyśmy napisać w tym celu 20 linii kodu, gdzie połowa to działania, a połowa to wypisywanie
// tymczasem zrobimy to pętlą
new zmienna = 0 // tworzę licznik pętli, przez który będę mnożył dziesiątkę,w celu uzyskania kolejnych jej wielokrotności
// jest on równy 0, ponieważ już przy rozpoczęciu pętli, zwiększę wartość zmiennej 'zmienna' o 1
new wynik // zmienna, która będzie przechowywała wielokrotności dziesiątki
// budowa pętli for wygląda następująco
// for( licznik_pętli; warunek_dla_którego_ma_się_wykonywać; działanie wykonane po każdym obrocie pętli )
// {
// blok
// }
// nasza pętla wypisująca więc kolejne wielokrotności liczby 10 będzie wyglądała
for( zmienna; zmienna <= 10; zmienna += 1 )
{
wynik = zmienna * 10
wypisz wynik // wypisz wynik jest niepoprawne, jednakże jak na razie nie znasz żadnej funkcji wyjściowej
}
// jak będzie ona działała?
// dla zmiennej zmienna, mniejszej lub równej 10, co każdy obrót pętli zwiększ ją o jeden i wykonaj blok
// blok pomnoży wartość licznika o 10 i zwróci jego wartość użytkownikowi
// dla rozjaśnienia rozpiszę tą całą pętle
pętla dla zmiennej 'zmienna'
zmienna = 1, zmienna <= 10 ? tak, więc:
wynik = 1 * 10
wypisz wynik
zmienna = 2, zmienna <= 10 ? tak, więc:
wynik = 2 * 10
wypisz wynik
zmienna = 3, zmienna <= 10 ? tak, więc:
wynik = 3 * 10
wypisz wynik
zmienna = 4, zmienna <= 10 ? tak, więc:
wynik = 4 * 10
wypisz wynik
zmienna = 5, zmienna <= 10 ? tak, więc:
wynik = 5 * 10
wypisz wynik
zmienna = 6, zmienna <= 10 ? tak, więc:
wynik = 6 * 10
wypisz wynik
zmienna = 7, zmienna <= 10 ? tak, więc:
wynik = 7 * 10
wypisz wynik
zmienna = 8, zmienna <= 10 ? tak, więc:
wynik = 8 * 10
wypisz wynik
zmienna = 9, zmienna <= 10 ? tak, więc:
wynik = 9 * 10
wypisz wynik
zmienna = 10, zmienna <= 10 ? tak, więc:
wynik = 10 * 10
wypisz wynik
zmienna = 11, zmienna <= 10 ? nie, więc przerwij pętle
// jeśli chcemy zacząć od wartości dla zmiennej 'zmienna' 1, należy wykonać operację w trzecim parametrze tworzenia...
// pętli for, na zwiększenie po pierwszym obrocie pętli wartości zmiennej o 1 (tzw. postinkrementacja, odsyłam do rozdziału 1)
// a wygląda to tak: zmienna++
// działaniem równoznacznym z zmienna += 1 będzie preinkrementacja, czyli ++zmiena, lub po prostu zmienna = zmienna + 1
// warto zaznaczyć, że zmienną możemy stworzyć przy tworzeniu pętli
// stwórzmy więc teraz tak samo działającą pętle, aczkolwiek z zmienna stworzoną wewnątrz niej i z innym działaniem
for( new zmienna = 1, zmienna <= 10, zmienna++ )
{
wynik = zmienna * 10
wypisz wynik
}
// pętla ta zadziała identycznie, jak ta podana wyżej

  • Pętla while.

Pętla while będzie działała następująco: "podczas gdy spełnia się dany warunek wykonaj blok". Stwórzmy więc pętle while, działająca jak wyżej wymieniony for.

// pętla while wygląda nastepująco
// while( warunek_dla_którego_ma_się_spełniać )
// {
// blok
// }
// w pętli while zmienną zawsze tworzymy poza jej instrukcją
// wartość licznika pętli tym razem zmieniamy w bloku pętli
// pętla while wypisująca wielokrotności liczby 10 do 100
new zmienna = 1
new wynik
while( zmienna <= 10 )
{
wynik = zmienna * 10
wypisz wynik
zmienna++
}
// w tym przypadku możemy również zacząć od wartości początkowej licznika pętli 0
new zmienna
new wynik
while( zmienna <= 10 )
{
zmienna++
wynik = zmienna * 10
wypisz wynik
}
// zawsze należy pamiętać, że kod wykonuje się od góry do dołu


*
*

  • Pętla do while

Pętla do while nie różni się prawie niczym, od pętli while. Cała różnica polega na tym, że zaczynamy od bloku poprzedzonego słowem do, po czym podajemy warunek, dla którego ma się wykonywać. Rozumiemy ją tak: "zrób blok podczas gdy spełnia się warunek". No i żeby sprawiedliwości stało się zadość, tu też łapcie kod.

*
// instrukcja pętli do while
// do
// {
// blok
// }
// while( warunek )
// przykłady pętli do while dla wypisania wielokrotności liczby 10
new zmienna = 1
new wynik
do
{
wynik = zmienna * 10
wypisz wynik
zmienna++
}
while( zmienna <= 10 )
// i dla wartości początkowej zmiennej 'zmienna' == 0
new zmienna
new wynik
do
{
zmienna++
wynik = zmienna * 10
wypisz wynik
}
while( zmienna <= 10 )


*
*

  • Przydatne rzeczy

Jeśli chcesz przerwać pętle w którymś momencie, bo na przykład szukasz jakiejś wartości i odpowiednim warunkiem już ją znalazłeś, powinieneś użyć słowa kluczowego break.
Jeśli zaś chcesz obrócić pętle o jeden raz, jeśli spełni się warunek, dla którego inne zadanie w pętli nie ma się wykonać powinieneś użyć słowa kluczowego continue.

Podsumowanie: Cóż mogę więcej powiedzieć? Pętle w programowaniu odgrywają bardzo istotną rolę i bez nich dużo nie napiszesz.*

Co w następnym rozdziale: Tablice
*
*
Rozdział 5: Tablice

  • Co to jest tablica?

Tablica to pewnego rodzaju kontener z danymi różnego rodzaju, na chłopski rozum to ponumerowana skrzynka ze zmiennymi. Po co są tablice? Przyda się już tutaj wiedza odnośnie silnika Half-Life. Otóż jak wiadomo do serwerów Counter-Strike może podłączyć się maksymalnie 32 graczy, każdy z nich dostaje z chwilą wejścia na serwer swój unikalny identyfikator od 1 do 32, 0 przeznaczone jest do operacji wykonywanych na całym serwerze/dla całego serwera. Co za tym idzie? Załóżmy, że potrzebujemy jakiejś informacji o każdym graczu oddzielnie, ale nie będziemy tworzyć każdemu oddzielnie innej zmiennej, stworzymy więc tablicę z 33 polami. Czemu 33? Tak jak powiedziałem, istnieje również serwer, który ma wartość 0, a więc de facto na serwerze mamy 33 klienty. Poprzez podanie elementu takiej tablicy (czyli najczęściej identyfikatora gracza na którym właśnie operujemy) możemy wpisać w danym polu tablicy jakąś wartość. Możemy bawić się w tablice 32-elementowe, aczkolwiek w takim przypadku musielibyśmy podawać wartość o 1 niższą od identyfikatora gracza. Czemu? Tworząc tablicę na przykład 5-elementową mamy do wyboru pola {0, 1, 2, 3, 4}, a nie {1, 2, 3, 4, 5}. Koniec gadania, czas przejść do przykładów.

  • Tablica przechowująca wartości integer*

 

// stwórzmy tablicę przechowującą aktualną wartość HP każdego gracza
// do tego celu przekonamy się jak wygląda pierwsza funkcja z biblioteki fun
// będziemy ją musieli załadować do naszego pluginu za pomocą odpowiedniej definicji
// będziemy również potrzebowali pętli, aby wykonać operację na każdym graczu
// musimy jednak sprawdzać, czy gracz jest żywy, poznamy więc również inną funkcję
// będzie nam więc potrzebna także biblioteka amxmodx do wykonania warunku
#include <amxmdox> // ładujemy do pluginu bibliotekę amxmodx
#include <fun> // ładujemy do pluginu bibliotekę fun
new ZycieGraczy[33] // tworzymy tablicę 33-elementową przechowującą wartości integer
for(new i=1; i<=32; i++) // rozpoczynamy pętlę, która zadziała dla liczb w przedziale {1; 32}
{
                 if(is_user_alive(i)) // sprawdzamy czy gracz o identyfikatorze i jest żywy
                 {
                                 ZycieGraczy[i]=get_user_health(i) // wpisujemy do i pola tablicy
                                 // wartość życia gracza o identyfikatorze i
                 }
}
// jak będzie to wyglądało dla tablicy 32-elementowej?
new ZycieGraczy[32]
for(new i=0; i<=31; i++)
{
                 if(is_user_alive(i+1)) // i+1 ponieważ 0 to serwer, a i zaczynamy od 0
                 {
                                 ZycieGraczy[i]=get_user_health(i+1)
                 }
}
 
  • Tablica przechowująca wartości bool

 

// stworzymy tablicę, dzięki której będziemy wiedzieli czy dany gracz jest żywy bez sprawdzania tego cały czas
// będziemy więc potrzebowali tylko biblioteki amxmodx, dzięki której otrzymamy funkcję is_user_alive(identyfikator)
// identyfikator w pluginach najczęściej oznaczany jest symbolem "id"
// przejdźmy więc do rzeczy
#include <amxmodx>
new bool:CzyJestZywy[33] // tablica 33-elementowa przechowująca wartości true lub false
for(new id=1; id<=32; id++) // stwórzmy zmienną id, a nie i żeby zacząć się przyzwyczajać do tego oznaczenia
{
                 if(is_user_alive(id))
                 {
                                 CzyJestZywy[id]=true
                 }
                 else
                 {
                                 CzyJestZywy[id]=false
                 }
}
// i dla ćwiczenia dla tablicy 32-elementowej
new bool:CzyJestZywy[32]
for(new id=0; id<=31; id++)
{
                 if(is_user_alive(id+1))
                 {
                                 CzyJestZywy[id]=true
                 }
                 else
                 {
                                 CzyJestZywy[id]=false
                 }
}
*
  • Tablica przechowująca wartości Float

 

// w pluginach wartości Float często używane są przy pobieraniu lub ustawianiu prędkości gracza
// do pobrania lub ustawienia prędkości gracza poznamy dwie nowe funkcje z biblioteki fun
// pobierzemy więc do tablicy wartość prędkości każdego gracza i ustawimy o ją na o 10 większą
#include <amxmodx>
#include <fun>
new Float:PredkoscGracza[33] // tablica 33-elementowa przechowująca wartości float
for(new id=1; id<=32; id++)
{
                 if(is_user_alive(id))
                 {
                                 PredkoscGracza[id]=get_user_maxspeed(id) // get_user_maxspeed(identyfikator_gracza)
                                 // pobiera aktualną prędkość gracza
                                 set_user_maxspeed(id, PredkoscGracza[id]+10.0)
                                 // set_user_maxspeed(identyfikator_gracza, predkosc)
                                 // ustawia prędkość gracza o identyfikatorze identyfikator_gracza na wartość predkosc
                 }
}
// i dla tablicy 32-elementowej
new Float:PredkoscGracza[32]
for(new id=0; id<=31; id++)
{
                 if(is_user_alive(id+1))
                 {
                                 PredkoscGracza[id]=get_user_maxspeed(id+1)
                                 set_user_maxspeed(id+1, PredkoscGracza[id]+10.0)
                 }
}
*
*
  • String (ciąg znaków)

Nie wiemy jeszcze jak do zmiennej zapisać ciąg znaków (ciąg znaków, czyli najzwyczajniej mówiąc wartość zawierającą słowa, zdania, znaki). Otóż, żeby tego dokonać potrzebuje właśnie tablicy. Wpisując dane słowo bądź zdanie do tablicy musimy pamiętać o tym, że każdy kolejny znak z naszego ciągu znaków wpisuje się oddzielnie kolejno do poszczgólnych elementów tablicy, co za tym idzie jeśli chcemy przechować zdanie składające się na przykład z 30 znaków, tak dużej będziemy potrzebowali również tablicy. Jak to działa? Zaraz się przekonasz:
*

// tablice przechowujące stringi często używane są do
// zapisania nicku gracza
// nick gracza może zawierać maksymalnie 32 znaki, toteż stworzymy tablicę 32-elementową
new NickGracza[32]
// spróbujmy najpierw wpisać nick, który znamy i zrozumieć w jaki sposób zapiszę on się w naszej tablicy
NickGracza="shock" // tablica NickGracza zawiera aktualnie ciąg znakow "shock"
// jak wyglądają jej poszczególne elementy
// NickGracza[0]=='S'
// NickGracza[1]=='H'
// NickGracza[2]=='O'
// NickGracza[3]=='C'
// NickGracza[4]=='K'
// NickGracza[5]=='I'
// warto wspomnieć, iż jeśli przypisujemy tablicy tylko jeden znak, nie używa się cudzysłowów, tylko apostrofy
// w ten możemy zmieniać pojedyncze elementy tablicy (jeśli mamy do czynienia ze znakami, a nie wartościami liczbowymi)


*

  • Tablice wielowymariowe

Tablice wielowymiarowe mogą się wydawać z początku nieco ciężkie do ogarnięcia, ale w gruncie rzeczy takie nie są, są za to bardzo przydatne i z czasem każdy zapalony programista stwierdzi, że nawet "fajne". Tablica wielowymiarowa? Pewnie niewiele Ci to mówi. Tablica wielowymiarowa to jakby kontener w kontenerze. Kontenerów takich możesz mieć wiele, jednakże, jeśli chcesz zmienić wartość któregoś z nich, zawsze musisz znać i podać elementy kontenerów przynajmniej do przedostatniego z wszystkich. Myślę, że tu przykład będzie jak znalazł:

// załóżmy czysto-teoretycznie, że każdy z graczy na serwerze ma ten sam nick
// chcemy przechować nick każdego gracza oddzielnie
// w takim wypadku nie będziemy przecież tworzyli 32 tablic i do każdej wpisywali odpowiedniej wartości
// stworzymy więc tablicę dwuwymiarową, gdzie pierwszym "kontenerem" będzie identyfikator gracza, a drugim jego nick
new NickiGraczy[33][32] // 33 - identyfikatory / 32 - miejsce na nick gracza
// nietrudno zauważyć, że każdy identyfikator będzie miał do dyspozycji swoją tablicę jednowymiarową, 32-elementową
// dla przykładu przypiszmy coś identyfikatorowi 5
NickiGraczy[5]="Najlepszy nick w miescie"
// jeśli jednak w przypadku takiej tablicy chcemy zmienić jeden znak, zrobimy to tak
// zamieńmy "Najlepszy" na "najgorszy"
NickiGraczy[5][3]='g'
NickiGraczy[5][4]='o'
NickiGraczy[5][5]='r'
// warto przypomnieć, że tablica zaczyna się od 0 elementu, nie 1
// dopiszmy więc tą sama wartość wszystkim graczom
for(new i=1; i<=32; i++) // jeśli nie wiesz co oznacza co właśnie napisałem, odsyłam do rozdziału 4
{
NickiGraczy[i]="Najlepszy gracz w miescie"
}
// jeśli teraz chcemy zmienić każdemu z nich "najlepszy" na "najgorszy" zrobimy to tak:
for(new i=1; i<=32; i++)
{
NickiGraczy[i][3]='g'
NickiGraczy[i][4]='o'
NickiGraczy[i][5]='r'
}
*
*
Podsumowanie: Cóż mogę powiedzieć, opisałem najlepiej jak potrafiłem.

Co w następnym rozdziale: Nie wiem czy takowy jeszcze powstanie, ale jeśli tak to dowiecie się właśnie w nim.

 
 
 
Zakaz kopiowania bez mojej zgody.

Edytowane przez Creizi Monki
  • Like 16
Odnośnik do komentarza
Udostępnij na innych stronach

Może usuń nazwę drugiej sieci.

 

Czas na naukę! Dzięki za poradnik :)

Edytowane przez -_-
Ta sieć chyba i tak już nie istnieje jako sieć cs 1.6
Odnośnik do komentarza
Udostępnij na innych stronach

Mała podpowiedź.

 

Zamula Ci edytor (amxx studio) przy obszernych pluginach np. zp czy cod?

Polecam sobie zmodyfikowac notepada (notepad++) w praktyce wygląda to tak

http://scr.hu/1wm4/v7w2y

nic nie zamula, i można tak samo kompilator sobie podpiąć pod to amxx jak i source. 

Co najważniejsze w tym jeszcze? Nie męczą się oczy przy tym tle, oczywiście każdy może sobie dowolne tło dać.

 

Sam używam i lepiej się pisze wszystko: pluginy do amxx/source oraz można też używać sobie do pisanie w innych językach. :)

Wszystko co i jak na stronie supportu pluginów znajdziecie (darkGL pisał "przygotowanie środowiska pracy")

 

Jak ktoś z was już zaczął sobie praktykować pisanie pluginów to zapraszam do wrzucania swoich prac, jak coś pomogę w poprawkach.

Edytowane przez Destroyer
  • Like 2
Odnośnik do komentarza
Udostępnij na innych stronach

Bardzo fajny ten poradnik. Ale chyba łatwo nie bedzie się tego nauczyc  :crazy:

Nauka pawn nie polega na samym czytaniu poradnika , tylko też na pisaniu byle jakiego pluginu - nawet zwykłego na interp czy powitania na hudmessage.

Aby się nauczyć pisać pluginy trzeba zacząć je pisać, nawet z błędami ale zacząć "coś"

  • Like 1
Odnośnik do komentarza
Udostępnij na innych stronach

  • 2 miesiące temu...

Automatycznie wygenerowana wiadomość.

Temat został zamknięty przez któregoś z moderatora.

 

Powód: Brak aktywności.

 

Jeżeli się z tym nie zgadzasz zgłoś to Administratorowi z wyższą rangą.

 

Pozdrawiamy

Administracja Forum | Cs-Classic.PL | Klasyczna sieć serwerów

Odnośnik do komentarza
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Korzystając z tej strony zgadzasz się na Polityka prywatności