Jump to content

Search the Community

Showing results for tags 'parametry'.

  • Search By Tags

    Oddělujte čárkami
  • Search By Author

Content Type


Fórum

  • Obecné
    • Všeobecné
    • Všechno možné
  • Programování
    • Poradna
    • Návody
    • Tvorba
    • Hledám programátora
  • Herní oblast
    • Poradna
    • Jak na to?
    • Herní kontext
    • Herní zážitky
    • Komunita
  • Grafika
    • Poradna
    • Návody
    • Tvorba
  • Ostatní
    • Hardware a software
    • Hledám/nabízím
    • Archiv
    • 3D Tisk

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Web


Facebook


Jabber


Skype


Steam


Twitter


Github


Pastebin

Found 2 results

  1. Obtížnost: Osnova: 1. Úvod, co je to funkce; 2. Definice funkce a její části; 3. Parametry; 4. Návratová hodnota; 5. Závěr. 1. Úvod, co je to funkce Zdravím, tímto návodem konečně dokončím šňůru návodů pro začátečníky. Posledním tématem, které jsme ještě nestihli probrat, jsou funkce. O čem je řeč? Funkce jsou takové části kódu, které lze volat v různých částech skriptu. Někdy se lze také setkat s pojmem podprogram (ačkoliv to není to samé – podprogramem mohou být i metody, ale to se nás ani Pawn netýká). Účel je jasný – abychom nemuseli psát tentýž kód na více místech, napíšeme jej jen jednou a voláme jej tam, kde potřebujeme. Přináší nám to hned několik benefitů – kratší a přehlednější kód, při úpravě kódu jej stačí upravit na jednom místě, totéž platí pro opravy chyb. Počas skriptování SA:MP skriptů se setkáváme s funkcemi nepřetržitě, jmenovitě například funkce GetPlayerName, SendClientMessage, strval, ale i OnPlayerConnect či OnFilterScriptInit. 2. Definice funkce a její části Když už máme představu, co to funkce je, měli bychom si ukázat, jak ji vytvořit. Každá funkce má svůj název (identifikátor), dále pak parametry, o kterých si řekneme za chvíli, tělo, do kterého vkládáme kód, a jako poslední návratovou hodnotu (i když tu nemusí mít nezbytně, o tom za chvíli). Ukažme si to na kódu: Secist(cislo1, cislo2) { new suma; suma = cislo1 + cislo2; return suma; } Teď si určíme jednotlivé části funkce: – identifikátor: Secist – parametry: cislo1 a cislo2 – tělo funkce: všechno mezi složenými závorkami {} – návratová hodnota: return suma; Jak je vidět, jako první se uvádí identifikátor, poté následují parametry ohraničené kulatými závorkami, následně se píše tělo kódu do složených závorek a do těla se uvádí návratová hodnota příkazem return. Výše uvedená funkce slouží k součtu dvou celých čísel. 3. Parametry Díky parametrům můžeme funkci předávat vstupní hodnoty a/nebo ovlivňovat to, jak se bude chovat. U naší sčítací funkce parametry slouží k předání sčítanců. Ale například funkce strcmp má parametr ignorecase, který nám určuje, zda má funkce ignorovat rozdíl mezi velkými a malými písmeny. Tento parametr ovlivňuje chování funkce. Parametry funkcí v Pawn mohou být různého datového typu (tedy celá čísla, desetinná čísla, logické hodnoty, řetězce atd.) a může jich být libovolný počet. Jsou funkce, které nemají žádné parametry (kulaté závorky ale musíme uvést vždy – ()), jsou takové, které jich mají i 10. Zde je pár funkcí na ukázku, každá s jiným počtem parametrů (všechny lze dohledat na SA:MP wiki): GetTickCount(); //funkce bez parametrů SendClientMessage(playerid, color, const message[]); //funkce se 3 parametry AddPlayerClass(modelid, Float:spawn_x, Float:spawn_y, Float:spawn_z, Float:z_angle, weapon1, weapon1_ammo, weapon2, weapon2_ammo, weapon3, weapon3_ammo); //funkce s 11 parametry Lze si všimnout, že u některých se objevují věci jako Float:, [] apod. Právě tyto, prozatím tomu říkejme "věci", nám určují, jaký datový typ bude daný parametr mít. Seznam nejčastěji používaných datových typů: playerid // když neuvedeme nic, bere to jako celé číslo Float:x // Float: nám značí desetinné číslo bool:ignorecase // bool: nám značí logickou hodnotu (true/false) message[] // hranaté závorky znamenají řetězec (nebo pole, viz předchozí návody) Zbývá nám uvést si, jak takové parametry dosazovat při volání funkce. Jednoduše za ně dosadíme skutečné hodnoty (přesněji argumenty) v tom pořadí, v jakém jsme je definovali: GetTickCount(); //nic se nemění SendClientMessage(0, 1, "Ahoj, světe!"); //dosazení argumentů (skutečných hodnot) Nad rámec návodu (pro zvídavé): 4. Návratová hodnota Na začátku jsme řekli, že funkce má také návratovou hodnotu. Přesněji řečeno, může mít, ale nemusí. Přesně tak, funkce žádnou návratovou hodnotu mít nemusí. V některých jazycích se pak funkce bez návratové hodnoty nazývá procedurou. V kódu naší sčítací funkce je vidět, že hodnotu vrátíme příkazem return. Ve funkci můžeme tento příkaz použít vícekrát (často to souvisí s podmínkami a větvením), ale pravidlem je, že musí vždy vrátit hodnotu stejného datového typu. Kompilátor nám neumožní vrátit jednou celé číslo a jednou řetězec, to prostě nejde. Když už jsme zmínili datové typy, je třeba si dávat pozor na jednu věc. Pokud vracíme hodnotu jinou než celé číslo či řetězec, musíme před identifikátor uvést příslušný tag (teď už nepíši "věc", ale tag). Upravme si tedy naši funkci pro sčítání dvou desetinných čísel: Float:Secist(Float:cislo1, Float:cislo2) // před názvem nám přibyl tag Float { new Float:suma; suma = cislo1 + cislo2; return suma; } Zde je vidět, že před názvem nám přibylo Float:. Je to nutné pro správný chod funkce. Kdybychom vraceli např. logické hodnoty, byl by tam tag bool:. A jak je to tedy s funkcemi (procedurami, jestli chcete), které nic nevracejí? Jsou dvě možnosti, buď uvedeme prázdný return – return; – nebo neuvedeme nic. Je to jen na vás, běžná je druhá varianta (neuvádět nic). Ukázka: Vypis(const message[]) { print(message); return; } Vypis2(const message[]) { print(message); } 5. Závěr A tím jsme se dostali jak k závěru tutoriálu, tak k závěru celé série. Děkuji všem, kteří si návod přečetli, a obdivuji všechny, kteří prošli celou sérií. Doufám, že jste se dozvěděli něco nového, pokud ne, alespoň jste si to zopakovali. Prozatím neplánuji začínat další sérii návodů, ale je možné, že se sem tam něco objeví. Ještě jednou děkuji a platí to, co vždycky – pokud jste našli nějakou chybu či nesrovnalost nebo se jen chcete na něco zeptat, zanechte mi vzkaz pod tímto příspěvkem.
  2. sscanf2 ***** Zdravím vás u dalšího návodu, konkrétně o velice populárním a dost často používaném pluginu a to sscanf. Jde o plugin, který mnoha uživatelům vypomáhá při tvorbě více parametrových příkazů či u více informačních údajů(například inputtext) v samp. Obsah Ukázka použití Specifikátory Integer String Pole Enum Velké specifikátory Integer String Pole Enum Použití Změnit hráčovi počet životů Zabanovat hráče s důvodem Nahrát více údajů v jednom souboru Download Závěr Ukázka použití Hodně uživatelů využívá tuhle funkci hlavně v podmínkách v příkazech, například: if (sscanf(params, "ui", ID, Penize)) return SendClientMessage(playerid, -1, "Použití: /prachy [ID/Jméno hráče] [Počet]"); Jak to funguje? Vezme údaje ze params, a z celého řetězce zjistí, kde tam jsou dané datové typy, a to u nebo-li string(číslo nebo nick hráče, či jeho součást) a i nebo-li integer, a dosadí do daných proměnných(ID a Peníze), a podmínka nám vrací true/false dle toho, zda při rozdělovaní (ne)vzniknou nějaké komplikace, například jeden z údajů chybí, nebo nenašel v řetězci daný datový typ(například místo čísla aka peněz napíšete nějaký string. Funkce to vyhodnotí jako text, nikoliv číslo a chyba). V případě, že jste to nepochopili, můžeme si to ukázat na jiném příkladě. Jelikož sscanf2 je funkce, lze jí jednoduše používat i bez podmínek: new String[15] = "abcd", Cislo = 0; sscanf("Potrebuji 1000", "si", String, Cislo); printf(" %s %i", String, Cislo); Právě jsme si deklarovali 2 proměnné a to String a k němu jsme si přiřadili hodnotu "abcd" a proměnnou Cislo s přiřazenou hodnotou 0. Nyní využijeme fci sscanf, aby vzal daný řetězec a to Potrebuji 1000 a rozdělil je do těchto 2 proměnných. Jak si můžete všimnout, obsahuje 2 datové typy a to string a integer. Takže jelikož první údaj je string tak logicky první specifikátor(o nich později) bude s, a druhé je číslo, takže specifikátor bude i. Nyní se nám za proměnné dosadí oba údaje a do konzole se nám vypíše Potrebuji 1000, a ne abcd 0. Specifikátory Nebudu tu vypisovat všechny specifikátory, které sscanf obsahuje, ale jen prozatím ty, které uživatelé používají asi nejčastěji: Specifikátor Jméno Příklad i, d Integer 4, 72, -1024 [/td] --> s String Ahoj, Admin, sb75c4 l Boolean true, false f Float 0.5, 33.1, -99.9 h, x Hex FF, 0xAD35 u Jméno/ID hráče a botů SkiBig18, 2 r Jméno/ID hráče SkiBig18, 2 Integer Specifikátor se značí písmenkem i nebo d. Nejjednoduší specifikátor. Jde rozdělit 2 nebo i více řad čísel do daných proměnných, například: new Cislo1 = 0, Cislo2 = 0; sscanf("100 200", "ii", Cislo1, Cislo2); printf("%i %i", Cislo1, Cislo2); /* Vypíše 100 200 */ Není problém ani s řadou čísel, jen si musíte hlídat počet íček: new Cislo[6]; sscanf("1 4 9 2 -1 5", "iiiiii", Cislo[0], Cislo[1], Cislo[2], Cislo[3], Cislo[4], Cislo[5]); printf("%i %i %i %i %i %i", Cislo[0], Cislo[1], Cislo[2], Cislo[3], Cislo[4], Cislo[5]); V případě, že vynecháte jedno z íček, sscanf poslední hodnotu specifikuje jako 0 a také jí dosadí. To stejné platí i u stringu: sscanf("1 4 9 2 -1 5", "iiiii", Cislo[0], Cislo[1], Cislo[2], Cislo[3], Cislo[4], Cislo[5]); printf("%i %i %i %i %i %i", Cislo[0], Cislo[1], Cislo[2], Cislo[3], Cislo[4], Cislo[5]); /* Vypíše 1 4 9 2 -1 0 */ Lze nahradit písmeno i také písmenem d, výsledek i efekt bude naprosto stejný: sscanf("1 4 9 2 -1 5", "dddddd", Cislo[0], Cislo[1], Cislo[2], Cislo[3], Cislo[4], Cislo[5]); printf("%i %i %i %i %i %i", Cislo[0], Cislo[1], Cislo[2], Cislo[3], Cislo[4], Cislo[5]); /* Vypíše 1 4 9 2 -1 5 */ String Specifikátor se značí písmenkem s. Další nejčastěji používaný specifikátor. Používá se hlavně v příkazech pro důvody. Ale sscanf2 nabízí více možností práce se stringem. Jak jsem již na začátku ukazoval, kód: sscanf("Potrebuji 1000", "si", String, Cislo); Vypíše Potrebuji 1000. Ale co, když chceme do první proměnné přidat ještě slovo? sscanf("Potrebuji ihned 1000", "s[10]i", String, Cislo); Tak selže dosazování, jelikož slovo ihned není číslo, a po slově Potrebuji doplní nulu a tím končí. Řešení je prosté. Stačí buď přidat další specifikátor: new String[2][10], Cislo; sscanf("Potrebuji ihned 1000", "s[16]s[6]i", String[0], String[1], Cislo); printf("%s %s %i", String[0], String[1], Cislo); /* Vypíše Potrebuji ihned 1000 */ A nebo vynechat číslo a nechat jen jeden specifikátor pro celý text: new String[16]; sscanf("Potrebuji ihned", "s[16]", String); print(String); /* Vypíše Potrebuji ihned */ Ale problém je teď, že specifikátor vezme celý text, nebo-li všechno po slovech Potrebuji ihned(pokud samozřejmě bude mít větší délku). V případě, že potřebujeme jen samostatně jediné slovo, stačí přidat po specifikátoru mezeru: new String[16]; sscanf("Potrebuji ihned", "s[16] ", String); print(String); /* Vypíše Potrebuji */ Pole Specifikátor se značí písmenkem a<>. Práce s polem u sscanf je podobné jako stringu, s tím rozdílem, že velikost pole nepoužíváme jako délku, ale k dosazení počtu prvků, a za každý prvek se dosadí daná hodnota v poli určité proměnné, například: new Pole[5]; sscanf("1 3 8 6 2", "a<i>[5]", Pole); printf("%i %i %i %i %i", Pole[0], Pole[1], Pole[2], Pole[3], Pole[4]); /* Vypíše 1 3 8 6 2 */ Jak si můžete všimnout, specifikátory pro jediné pole jsou 2 a to a(array v překladu pole), a i jako integer. Aby si sscanf nepletlo pole a velikost retězce, využíváme na začátek specifkátoru pro pole, jiné závorky, a to <>. Specifikátor i pak obsahuje datové typy pole nebo-li čísla. A nakonec [5] je maximální počet buněk v poli. Samozřejmě lze kombinovat i jiné datové typy v poli, například string: new String[3][3 + 1]; sscanf("Abc Ab A", "a<s[4]>[3]", String); printf("%s %s %s", String[0], String[1], String[2]); /* Vypíše Abc Ab A */ Jak to funguje tady? Deklarovali jsme si 3 řetězce s počtem 4 znaků (3 + nul. znak). Za každý řetězec dosadí specifická písmena. Je to úplně stejné jako bychom retězci0( String[0] ) přiřadili hodnotu "Abc", řetězci1( String[1] ) hodnotu "Ab" a řetězci2( String[2] ) hodnotu "A". Enum Specifikátor se značí písmenkem e<>. Tento dodatek se považuje za nejlepší dodatek v sscanf. A ani se nedivím, jelikož vám umožní měnit výčet hodnot dokonce v samotném enumu. A jako u pole i zde platí, že lze přepsat všechny datové typy. Ale je to pár rozdílů, jeden z nejrelevantnějších je, že musíte vypsat všechny specifikátory všech datových typů, co enum obsahuje(logicky, jinak by sscanf nevěděl, jakou proměnnou má přesně v enumu přepsat). Ukážeme si to na příkladu: enum enum_PlayerInfo { e_AdminLevel, e_VipLevel, e_VipBodu, } new e_Enum[enum_PlayerInfo]; sscanf("5 1 1000", "e<iii>", e_Enum); printf("%i %i %i", e_Enum[e_AdminLevel], e_Enum[e_VipLevel], e_Enum[e_VipBodu]); /* Vypíše 5 1 1000 */ Zde jsem si deklarovali proměnnou s výčtem hodnot, který obsahuje AdminLevel, VipLevel a počet bodů. Sscanf nám zjistí ze všech specifikátorů ve specifikaci struktury v enumu(nebo-li v <>), že jde o čísla a tak přepíše hodnoty. Ano, práce s polem je mu velice podobná a teď zkusíme zapojit více datových typů a všem nastavíme nějakou hodnotu: enum enum_Info { e_Integer, e_String[24], Float: e_Float, e_Char } new e_Enum[enum_Info]; sscanf("10 Ahoj 12.33 c", "e<is[24]fc>", e_Enum); printf("%i %.2f %s %c", e_Enum[e_Integer], e_Enum[e_Float], e_Enum[e_String], e_Enum[e_Char]); /* Vypíše 10 12.33 Ahoj c */ Velké specifikátory V případě, že vložíme prázdný řetězec(či neúplný), můžeme mu při rozdělení přidat i tzv. "defaultní hodnoty", které pak dosadí, nejjednodušší příklad: Integer new Cislo; sscanf("", "I(10)", Cislo); printf("%i", Cislo); /* Vypíše 10 */ Specifikátor se značí písmenkem I nebo D. Jak si můžeme všimnout, sscanf dostal prázdný řetězec na rozdělení. Tak jak je možné, že se nám do konzole odešle 10? Je to prosté: U specifikátorů datových typů, jsme zaměnili malé i za velké I, což je znamení pro sscanf, že v případě, že tam hodnotou nenajde v řetězci, ať tam doplní jinou, a ta hodnota se přidává do kulatých závorek (). Samozřejmě, lze nastavit defaultní hodnoty i více prom. například: new Cislo1, Cislo2; sscanf("", "I(10)I(20)", Cislo1, Cislo2); printf("%i %i", Cislo1, Cislo2); /* Vypíše 10 20 */ String Specifikátor se značí písmenkem S. Tady je to zajímavější, jelikož defaultní hodnotu u stringu nemusíme psát do uvozovek: new String[4 + 1]; sscanf("", "S(Ahoj)", String); print(String); /* Vypíše */ Samozřejmě nesmíme zapomenout na délku stringu, jelikož nám to hodí varování. Doplňujeme zásadně až za defaultní hodnotou: new String[4 + 1]; sscanf("", "S(Ahoj)[5]", String); print(String); /* Vypíše Ahoj */ Pole Specifikátor se značí písmenkem A<>. Ani tady není extra rozdíl. Může se hodit při doplňování hodnot, například: new Pole[3]; sscanf("1 2", "A<i>(3)[3]", Pole); printf("%i %i %i", Pole[0], Pole[1], Pole[2]); /* Vypíše 1 2 3 */ Všimněte si ale, že nesmíme přepsat specifikátor integeru, v poli na velké písmenko ale musíme celé pole. I tady je funkčnost jednoduchá. Pole, které jsme si deklarovali má 3 prvky. My mu ale doplníme jenom 2. Díky velkému písmenku A informujeme sscanf, že tam nebudou všechny údaje, a tak poslednímu ať defaultně přiřadí hodnotu 3. A co, když tam nebudou například 2? Postup je stále stejný: sscanf("1", "A<i>(1, 2)[3]", Pole); A jak postup, tak výsledek bude stejný. Sscanf dostane na rozdělení pouze jeden údaj ze 3, které mají být správně v poli, a tak vezme defaulní hodnoty a doplní je. Ale co, když nastavíme defaulní hodnotu pouze 1 na 2 chybějící prvky?: sscanf("1", "A<i>(2)[3]", Pole); Tady sscanf nemá moc na vybranou. I když jeho primárním cílem bude doplnit všechny hodnoty do pole, dostane jen jednu defaultní, a zapracuje velice zajímavě: vezme tu jedinou defaultní a doplní je do všech prvků v poli, takže ve výsledku se nám do konzole vypíše 1 2 2 Enum Specifikátor se značí písmenkem E<>. Tady je problém, že uživatel ne jen, že musí přidávat všechny specifikátory ve výčtu, ale také ještě v případě práce s defaultními hodnotami v enumu musí vypsat k každému údaji defaultní hodnotu, i když už nějakou má, například: sscanf("11", "E<iii>(11, 22, 33)", epromenna); printf("%i %i %i", epromenna[e_cislo], epromenna[e_cislo2], epromenna[e_cislo3]); /* Vypíše 11 22 33 */ Jak si můžete všimnout, v řetězci je 11, ale stejně jí musíme přidat do defaultních hodnot. Na závěr kapitoli něco trošku těžšího: sscanf("", "E<s[5]fs[6]ii>(Ahoj, 11.2, Scydo, 11, 22)", epromenna); print(epromenna[e_String]); printf("%.1f", epromenna[e_Float]); print(epromenna[e_String2]); printf("%i", epromenna[e_Integer]); printf("%i", epromenna[e_Integer2]); /* Vypíše: Ahoj 11.2 Scydo 11 22 */ Použití Změnit hráčovi počet životů Zabanovat hráče s důvodem Nahrát více údajů v jednom souboru Download To už je složitější, jelikož i když se vydala nová verze, spousty uživatelů hlásí, že buď je tam něco nefunkční a nebo samotná verze nefunguje. Proto jsem vám pro jistotu nahrál verzi sscanfu, kterou používám já a použil jsem ho i na kódy v tomto návodě, a je plně funkční: https://uloz.to/!vV4WzRFEG/sscanf2-zip Ihned na začátek zdrojového kódu samozřejmě nesmíte zapomenou sscanf vůbec nahrávat: #include <sscanf2> A do konfigurace serveru do řádku pro nahrávání pluginů na Windows vepíšete: plugins sscanf V případě Linuxu: plugins sscanf.so Závěr Naschvál jsem vynechal spousty ještě dodatků v sscanf2, například "quite" stringy, jelikož nevidím moc lidí, co by to tady využívalo. A na závěr bych chtěl dodat, že některá teoretická vysvětlení se mohou zdát neúplná, pozměněná a nebo trošku špatná. Důvodem je, že zcela správnÁ vysvětlení by prostý začátečník nebo i čtenář nepochopil. Samozřejmě, pokud mám některé hrubější chybu v kódě nebo v teorii, jak mi napište. Ověřený návod Tento návod prošel validací, a lze ho proto považovat za ověřený.
×
×
  • Create New...