[TUT] Osnove skriptanja

Započeo admin, Maj 03, 2009, 11:33:11 PRE PODNE

prethodna tema - sledeća tema

0 članova i 2 gostiju pregledaju ovu temu.

Osnove Skriptanja


Početak


Ispod je jedna od najjednostavnijih primjera skripte koju mozete naskriptati:


#include <a_samp>

main()
{
print("hello");
return 1;
}



Različiti aspekti bit će pokazani u daljnjem tutorialu, sada se usredotoćimo na prvu liniju (prvi redak)

Sastojci (Include)


#include <a_samp>

To jednostavno pokreće kod iz pawno/includes/a_samp.inc u vašu skriptu, pa možete sve sto taj kod ima iskoristiti. Jedan dio je:

#include <core>
#include <float>
#include <string>
#include <file>
#include <time>
#include <datagram>
#include <a_players>
#include <a_vehicles>
#include <a_objects>
#include <a_sampdb>


Ti includeovi su svi fajlovi koji su u tom direktoriju, pa cete njihovim dodavanjem imati pristup svima funkcijama SA:MP-a (vise o funkcijama poslije)


Pozivi (Calls)

Idući dio je o dvije strane poziva funkcije. main() je funkcija kojim ispisujete kod i pozivate ju od bilo kuda, print(string[]) je funkcija sa kodom od bilo kuda, koju pozivate. Trenutačno sve što to radi jest da ponovno otvara, print string (npr. print „hello“ (bez navodnika)) u server konzolu na kraju.

return 1;

Vraća vrijednost (1) natrag na mjesto koje poziva main da kaze sto se dogodilo (tocan iznos koji prolazi ovdje nije bitan, ali u drugim mjestima jest). Sada imate prvu najjednostavniju skriptu. Ako ste izabrali  file->new u pawnu dat ce vam mnogo veći start sa svim pripadajucim callbackovima , uključujući i  ''main'' (tehnički nije callback ali se ponaÅ¡a kao jedan)




Izjave (Statements)

print i return linije imaju „;“ na sebi, to jednostavno označava kraj izjave (izjava je grupa od jedne ili više nardebi i operatora koji zajedno nešto rade, slično rečenici u jednostavnom govoru). Većina ljudi stavlja odvojeno izjave, svaku u svoj red, ali to nije potrebno, samo cini sve preglednije, sljedeće je jednako ispravno:

main() { print("hello"); return 1; }

{} (te zagrade (krivudave zagrade), ne obićne zagrade)) zatvaraju grupu izjava koju treba izvesti zajedno (kao paragraf u obićnom jeziku) ako ste napravili :

main() print("hello"); return 1;

Dobit ćete error jer sada "return 1;" nije grupiran pa nece biti dio main-a. Zagrade grupiraju nekoliko izjava u jednu izjavu. (nazvano zajednička izjava) a funkcije imaju jednu izjavu sa njima. Bez tih zagrada print i return su potpuno nepovezane izjave, pa postoje dvije od njih,a  kao funkcija moze biti samo 1 izjava, tako da druga izjava nije u funkciji, ciji kod to ne može biti.

Funkcije (Functions)

Funkcija je jednostavno dio koda koji nesto radi, i moze biti napravljena da radi stvari od bilo kuda. Može i dati podatke koje radi natrag na mjesto koje je reklo da to radi (mjesto koje ju poziva).

Pozivanje (Calling)

print("hello");


Kao sto je objasnjeno u “ Kako Početi tj Uvodu”, to poziva funkciju koja se zove “print” (definirano u a_samp.inc, zbog cega ju morate inkludati (uključiti)) i kaze da prikaze nesto u server konzoli (riječ hello)


Funkcija se sastoji od imena funkcije (npr „print“), koje govori sistemu koji dio koda pozivate, i liste parametra, koju zatvaraju zagrade () poslije imena funkcije, koja daje dodatne podatke funkciji da pomogne u njenom izvoÄ'enju. Da nemate parametre trebali bi milijone funkcija:


printa();
printaa();
printab();
printac();
// itd




Funkcije mogu imat parametara koliko god zelite, od 0 nadalje (moze biti i gornji limit ali je barem 128):

printf("hello", 1, 2, 3, 4, 5, 6);

Ne brinite o tome Å¡to funkcija radi za sada, samo zapamtite da ima 7 parametara, svaki odvojen zarezom.

Definiranje (Defining)

Kao i pozivanje gotovih funkcija mozete isto tako i naskriptati i pozvati svoju:

#include <a_samp>

main()
{
return MyFunction();
}

MyFunction()
{
print("hello");
return 1;
}


Princip rada je jednak originalnom kodu, samo je aranžirano drugačije. Kada je main() pozvan, a to je kad se mod pokreće (pozvano je automatski) poziva novu obraÄ'enu funkciju nazvanu MyFunction(). Ta funkcija ispisuje originalnu poruku u server konzoli pa vraća broj 1 na main(). main() uzima vraćenu vrijednosti (1) i tada ju vraća serveru (npr.mjesto koje poziva main isprva). Posto je „return MyFunction();“ samostalna izjava, možete napraviti :

#include <a_samp>

main() return MyFunction();

MyFunction()
{
print("hello");
return 1;
}


No većina ljudi ne pazi na jasnoće. Isto tako možete ne iskoristiti MyFunction  return vrijednost uopće i napraviti :

#include <a_samp>

main()
{
MyFunction();
return 1;
}

MyFunction()
{
print("hello");
return 1;
}


Parametri (Parameters)

Parametri su vrste varijabli koje netreba deklarirati jer dolaze od mjesta koje poziva funkciju.


#include <a_samp>

main()
{
return MyFunction("hello");
}

MyFunction(string[])
{
print(string);
return 1;
}


Ovaj kod još uvijek radi istu stvar , samo sad govorimo ''MyFunction()'' sta da prikaže. Poziv premješta string „hello“ na funkciju gdje je spremljen, u varijabli nazvanoj string ([] označava niz što je objašnjeno poslije). Print funkcija je ona pozvana, ona onda prenosi sadržaj string varijable, znamo da je varijabla jer nema „“ više.

Varijable (Variables)

Varijabla je jednostavno bit memorije, to je gdje su podaci spremljeni i moze se promjeniti i čitati po želji. Varijable su jedna ili više ćelija, jedna ćelija je 32 bita (4 bajta), i u osnovi je upisana pa se može spremiti od -2147483648 do 2147483647 (iako je -2147483648 slabo definirana u PAWN-u i daje slabe rezultate ako je prikazana). Varijabla napravljena od jedne ili više ćelija je nazvana niz, stringovi su specijalni tipovi nizova kod kojih svaka ćelija sadrži lik stringa (ili 4 lika upakirana u stringove, ali oni nisu prikazani ovdje).

Deklaracija (Declaration)

Kako bi napravili novu varijabli, morate ju deklarirati:

new
myVariable;


To sistemu daje do znanja da napravi novu varijablu nazvanu myVariable, početna vrijednost te varijable je 0.






Postavljanje (Setting)

new
myVariable = 7;



To deklarira novu varijablu i postavlja njenu početnu vrijednost na 7, pa ce ispis te varijable biti 7. Za prikaz varijable koja nije string potrebno je vratiti se natrag na printf() funkciju spomenutu prije.

new
myVariable = 7;
printf("%d", myVariable);


opet sve što trebamo znati jest da će to ispisati vrijednost myVariable (npr 7 u ovom trenutku) na serveru

new
myVariable = 7;
printf("%d", myVariable);
myVariable = 8;
printf("%d", myVariable);


Ovaj kod ispisuje 7, mjenja vrijednost varijable na 8 i prikazuje novu vrijednost u prozoru servera takoÄ'er. Ima mnogo drugih stvari koje možete učiniti varijablama, neke su napisane ispod, većina je ispisana drugdje...

myVariable = myVariable + 4;

Postavlja vrijednost myVariable na staru vrijednost i dodaje 4, npr. povećava njenu vrijednost za 4. Može se napisati kao:

myVariable += 4;

što jednostavno znaći „ povećaj myVariable za 4“.

myVariable -= 4;

To će smanjiti vrijednost za 4.

myVariable *= 4;

To će pomnoziti vrijednost sa 4.

myVariable /= 4;

To će podijeliti vrijednost sa 4.


Nizovi

Deklaracija (Declaration)


Niz je varijabla u koju možete spremiti višestruke dijelove podataka i dinamički im pristupati. Niz je deklariran da odredi velićinu pri vremenu kompiliranja, pa trebate znati koliko djelova podataka trebate pohraniti unaprijed,a dobar primjer ovoga je vrlo uobicajan red MAX_PLAYERS,jer ima jedno mjesto za svakog moguceg spojenog igraca, dakle podaci od jednog igraca nece se uplitati u podatke drugog igraca ( vise na definicijama kasnije).


new
myArray[5];

Taj kod ce izjaviti niz od 5 mjesta, dakle mozete pohraniti 5 komada podataka odjednom, ali ono sto ne mozete napraviti je nesto kao:
new
myVariable = 5,
myArray[myVariable];

Kod izgleda kao da ce napraviti niz od bilo kojeg broja pohranjenog u myVariable (ovdje je 5 ali moze biti bilo sto), ali ne mozete raditi ovo. U PAWN-u memorija za varijable je dodijeljena kada kompilirate vas kod, to znaci da su nizovi uvijek jedne velicine, velicinu mozete staviti na koju god zelite i kada god zelite.
Pristupanje (Accesing)
Da bi podesili vrijednost u nizu morate reci u koji dio niza zelite pohraniti podatke ,to MOZE biti napravljeno sa drugom varijablom:

new
myArray[5];
myArray[2] = 7;

Ovo ce deklarirati niz od 5 slotova i drugom slotu dati vrijednost 7, posto zadane varijable uvijek krecu kao 0, ucinit ce vrijednosti u retku ovakvima:
0, 0, 7, 0, 0
Zasto nije:
0, 7, 0, 0, 0
pitate se? To je zato sto brojanje zapravo krece od broja 0, ne od 1. Razmotrite slijedece:
2, 4, 6, 8
Ako idete kroz listu onda nakon broja 2 vec imate jedan broj (2) , ovo znaci ako racunate brojeve do vremena dok dodete do 4  vec ste na jedan, niste na jedan kada dodete do 2, tada ste na nuli. Tako je 2 na poziciji nula i 4 na poziciji jedan, i tako se nastavlja da je 6 na poziciji 2, koja je pozicija gdje je i 7 u prvom primjeru iznad. Ako smo oznacili slotove za prvi primjer dobijemo:
0 1 2 3 4
0 0 7 0 0

Ovdje je 5 slotova ali kao sto vidite, i ovo je vrlo vazno, NEMA SLOTA BROJ 5, slijedeca radnja vam moze srusiti vas server: 
new
myArray[5];
myArray[5] = 7;

Kao sto je spomenuto gore, nizov index (index je slot u koji zapisujete) moze biti bilo sto, broj, varijabla, cak i funkcija koja vraca vrijednost.
new
myArray[5],
myIndex = 2;
[b]myArray[myIndex] = 7;

Jednom kad imate niz i index mozete koristiti taj block upravo kao da imate bilo koju drugu varijablu:[/b]
myArray[2] = myArray[2] + 1;
myArray[2] += 1;
myArray[2]++;

Primjer (Example)
Kao sto je gore spomenuto najcesci tip niza je MAX_PLAYERS niz . MAX_PLAYERS nije varijabla, to je definicija koja ce biti objasnjena kasnije, ali za sada prihvatite da je to konstantan broj jednak maksimalnom broju igraca koji server moze izdrzati (pocetno je 200,  cak i ako promjenite broj u vasoj server.cfg datoteci). Slijedeci kod koristi normalne varijable da bi zadrzao podatke za 4 igraca i radi nesto sa tim igracima u funkciji ( radi jednostavnosti pretpostavite da je MAX_PLAYER 4 za sada) :
new
gPlayer0,
gPlayer1,
gPlayer2,
gPlayer3;

SetPlayerValue(playerid, value)
{
if (playerid == 0)
{
gPlayer0 = value;
}
else if (playerid == 1)
{
gPlayer1 = value;
}
else if (playerid == 2)
{
gPlayer2 = value;
}
else if (playerid == 3)
{
gPlayer3 = value;
}
}

Pogledajte sekciju kontrolnih struktura za vise informacija sto se tamo dogadja, takodjer zapamtite da ovo moze biti napravljeno kao ''switch'' ali je malo teze za primjer a efekt je jedanak kod onako i ovako.
Sada usporedite to koristeci niz s jednim slotom po igracu, imajuci u vidu da index niza moze biti bilo koja vrijednost:

new
gPlayers[MAX_PLAYERS];

SetPlayerValue(playerid, value)
{
gPlayers[playerid] = value;
}

Ovo ce napraviti globalni niz (vidi zaglavlje o opsegu) sa jednim slotom za svakog igraca, tada ce funkcija dodjeliti sto god je u varijabli "value" slotu predvidjenom za tog igraca. Prvi primjer je bio velik sa samo 4 igraca, koristeci 4 reda po igracu, to je 800 redova za 200 igraca (moze biti i manje ali i dalje previse), druga verzija je jedan red bez obzira koliko igraca imate.

Strings (Nizovi)

Osnovna uporaba
Niz je poseban tip reda, koji se koristi da drzi vise znakova kako bi stvorio rijec ili recenicu ili tekst citljiv od strane covjeka. Karakter je velik 1 byte (iako postoje prosirene verzije gdje karakter ima vise byte-ova ali to nije dobro definirano u SA:MP-u) i po definiciji karakter zauzima jednu celiju ( jednu normalnu varijablu ili jedan tip slota).  Karakteri su sifrirani u sistemu zvanom ASCII, karakter "A" je zastupljen brojem 65, naputak sistemu da prikaze broj, dati ce 65, naputak sistemu da prikaze karakter dati ce A. Ocito je da jedan karakter zauzima jednu celiju, a vise karaktera (tj. tekst)  vise celija, niz celija, kao sto je upravo objasnjeno zove se array (niz).
Nizovi u PAWN-u (i drugim jezicima) su ono sto zovemo "NULL terminated (nulom raskinuti)", to znaci da kad je 0 dostignuta, niz zavrsava. Ovo nije isto kao karakter "0", zastupljen brojem 48, to je NULTI karakter, zastupljen brojem 0. Ovo znaci da mozete imati  niz redova od velikih 20 celija ali samo da je 3 karaktera dug, ako je cetvrti karakter NULTI karakter, oznacavajuci kraj niza. Medutim ne mozete imati niz 20 karaktera dug jer NULTI karakter MORA biti u nizu, dakle red od 20 celija moze imati niz od 19 karaktera  i NULTI raskidajuci karakter.

new
myString[16] = "hello";

Taj kod deklarira novi niz sa dovoljno prostora za 15 karaktera i namjesta ga na niz od pocetnih 5 karaktera "hello", dupli navodnici oko teksta naznacuju da je to niz. the double quotes around the text indicate that it's a string. Interno, red ce izgledati kao:
104 101 108 108 111 0 x x x x x x x x x x
Ovo "x" ne znaci nista, u ovom primjeru to ce sve biti 0 (nula) ali posto su poslje nultog karaktera nema veze kakvi su, nece utjecati na niz. 
Niz moze biti manipuliran kao normalni red, na primjer:

new
myString[16] = "hello";
myString[1] = 97;

Promjeniti ce karakter u slotu 1 u karakter zastupljen brojem 97 (malo slovo "a"), rezultirajuci da niz cita "hallo". Ovo moze biti napisano puno čitkije i lako za izmjeniti kao:
new
myString[16] = "hello";
myString[1] = 'a';

Ovi navodnici oko "a" znace da je to karakter, ne niz, karakteri ne trebaju biti nulom zavrseni jer su dugi samo jednu celiju, mogu jos biti koristeni u internim promjenama sa brojevima ako znate sto predstavljaju.
new
myString[16] = "hello";
myString[1] = '\0';

'\0' su dva karaktera, doduse \ je specijalni karakter koji modificira slijedeci karakter, \0 znaci NULA, taj kod je isto kao:
new
myString[16] = "hello";
myString[1] = 0;

Ali NIJE isto kao:
new
myString[16] = "hello";
myString[1] = '0';

Prva i druga verzija ce zavrsiti u redu izgledavsi ovako:
h
Treca verzija ce zavrsiti u redu ovako:
h0llo
Escape character (izlazni lik)[/b][/u]
Kao sto je ukratko objasnjeno backslash ( \ ) je specijalni karakter:
'\'
ili:
"\"
Kompiler ce prikazati gresku zato jer \ modificira slijedeci karakter dakle te konstante nece biti zavrsene ispravno, to se moze koristiti da stvori karakter koji ne moze biti normalno stvoren, na primjer:
new
myString[4] = "\"";

Ovaj kod ce stvoriti niz sastavljen samo od duplih navodnika, normalno , dupli navodnici naznacuju kraj pisanog niza ali backslash ( \ ) ucini duple navodnike odmah iza njih dijelom niza, dupli navodnici poslje toga zavrsavaju niz umjesto toga. Ostali specijalni karakteri su:
\0    NULL character   Zavrsava niz.
\n    Line feed    Koristi se \n za novi red u Linuxu (takodjer radi na Windowsima)
\r    Carriage return    Koristenje \r\n za novi redak u Windowsima
\\    Backslash   Koristi se da stavi pravi znak \ u niz
\'    Single Qoute    Koristi se da stavi pravi jedan navodnik kao karakter u jednostavnim izjavama (uporaba: '\'')
\"    Double Qoutes    Koristen da stavi prave duple navodnike u niz
\xNNN;    Hex number    Koristen da namjesti karakter na karakter zastupljen hex brojem naznacenim u mjestu na NNN
\NNN;    Number   Koristen da namjesti karakter na karakter zastupljen hex brojem na mjestu NNN (vidi \0)
Ima i ostalih ali ovo su glavni.

Tags
Tag je dodatni dio informacije na varijabli koja definira gdje moze biti koristena. Za primjer:
new
    Float:a = 6.0;

Dio "Float" je tag, to definira tu varijablu kao float (ne-cijeli broj) i  odredjuje gdje moze biti koristena.
native SetGravity(Float:gravity);
Ovo znaci da SetGravity funkcija uzima jedan parametar koji treba biti float, za primjer:
SetGravity(6.0);
new
   Float:fGrav = 5.0;
SetGravity(fGrav);

To ce namjestiti gravitaciju na 6  (6.0 kao float) onda 5 (5.0 kao float). Koristeci pogresan tag na pogresnom mjestu cesto ce prouzrociti neslaganje taga:
SetGravity(MyTag:7);
To ce pokusati staviti gravitaciju na 7 sa tagom "MyTag", to sigurno nije "Float" dakle pogresno je . Takoder zapamtite da su tagovi osjetljivi na veliko-malo slovo.
Scope (djelokrug)
[/u]
Scope (djelokrug) je nacin gdje varijabla moze biti koristena. Ima 4 glavna djelokruga: lokalni, lokalni staticki, globalni i globalni staticki. Sve varijable mogu samo biti koristene nakon sto su deklarirane pa je ovo ispravno:
new
    var = 4;
printf("%d", var);

Ovo je pogresno:
printf("%d", var);
new
    var = 4;

local
Lokalna varijabla je ona koja deklarira "new" unutar funkcije ili dijela funkcije:
MyFunc()
{
    new
        var1 = 4;
    printf("%d", var1);
    {
        // var1 jos uvijek postoji jer je ovo nizi nivo
        new
            var2 = 8;
        printf("%d %d", var1, var2);
    }
    // var2 vise ne postoji na visem nivou
}
// var1 vise ne postoji

Lokalne varijable su ostatak svaki puta, na primjer:
for (new i = 0; i < 3; i++)
{
    new
        j = 1;
    printf("%d", j);
    j++;
}

Napisati ce:
1
1
1

Zato jer je stvoren ''J'', ispisan, povecan i zatim unisten, pa tada kod radi petlju!
static local
Static local (lokalne staticke) mogu takoder biti koristene na istome mjestu kao i lokalne ali ne zaboravljaju njihovu staru vrijednost, na primjer:
MyFunc()
{
    static
        var1 = 4;
    printf("%d", var1);
    {
        // var1 jos uvijek postoji jer je ovo nizi nivo
        static
            var2 = 8;
        printf("%d %d", var1, var2);
    }
    // var2 vise ne postoji na visem nivou
}
// var1 vise ne postoji

Taj kod ce se ponasati tocno kao novi primjer, medutim ovo:
for (new i = 0; i < 3; i++)
{
    static
        j = 1;
    printf("%d", j);
    j++;
}

Ispisati ce:
1
2
3

Zato jer je ''J'' staticno, pa pamti njegovu staru vrijednost.
global
Global (globalne) varijable su deklarirane izvan funkcije i mogu biti koristene u bilo kojoj funkciji:
new
    gMyVar = 4;

MyFunc()
{
    printf("%d", gMyVar);
}

Nikad nisu resetirane ili izgubljene.
global static
Global static varijable su kao normalne globalne varijable ali mogu biti koristene samo u datoteci u kojoj su deklarirani:
Datoteka1:
static
    gsMyVar = 4;

MyFunc()
{
    printf("%d", gsMyVar);
}

#include "File2"

Datoteka 2:
MyFunc2()
{
    // Ovo je pogresno jer gsMyVar ne postoji ovdje
    printf("%d", gsMyVar);
}

static se takoder moze primjeniti na funkcije na isti nacin.

NAPOMENA: Svaki pokusaj i svako kopiranje ovog teksta ili dijela ovog teksta strogo ce se kaznjavati!

Poslednja Izmena: April 17, 2012, 00:43:57 PRE PODNE od joXy_

lep TuT i sve to....samo ja sam procitao sve moguce tut o skriptanju i nista,kao da mi nesto neda da naucim sktapirti...:(

ja ovdje nista ne kuzim  :'(
http://i.imgur.com/MMUzj.jpg
Pro Zupanja Rol3Play Gaming, dodite i uzivaj te u serveru[KLIKNI NA LINK].
Trazite se vele skripter nagrada 1339 admin, ako bude dobar dobije 1340 admina.
Obratite mi se na PM.


Lepo receno Axel...
btw: Prepoznajem TuT, za Wiki, lepo prevedeno...
Dosta ce mi pomoci, hvala Tony.


Uhhh.. Hvala puno...

Tesko ali korisno ;).
Jerry_Mortinson || River Side Member ||


Dobar je tut ovo su baš one osnove!