Počítačové hry Skriptování Obsah přednášky Skriptování Příkazové skripty Procedurální jazyky Lua a ostatní
Literatura a odkazy http://www.lua.org/ http://www.python.org/ Dalmau. Core Techniques and Algorithms in Game Programming. 2003 Varanese. Game Scripting Mastery. 2003 Příkládek na začátek RPG Věc struct Item { string Name ; ItemTypeEnum Type ; int Price ; double Power ; Naplnění místnosti Item [] items = new Item [128];... items [0]. Name = " Heal Potion lvl 1"; items [0]. Type = ItemTypeEnum. Heal ; items [0]. Price = 10; items [0]. Power =.1;... Pokud nevyhovuje, musím přepsat a PŘELOŽIT
Externí soubor Možnost uložit data do externího souboru Heal Potion lvl 1 Heal 10.1 Co když chci složitější logiku? MR funguje jen pro kouzelnice s levelem 5 a výš enum ItemTypeEnum = {..., Magic_Wizardress_Above_Level_5,... Potřeba komplexnějšího formátu K čemu skriptování Úplné oddělení enginu a dat grafika audio... obsah Bezpečnost chyba ve skriptu by neměla být kritická pro zbytek
Způsoby skriptování Použitý jazyk příkazové skripty (jednoduchá syntax, velmi omezené možnosti) procedurální/objektové jazyky dynamické moduly (pozor na bezpečnost) Způsob spuštění interpretovaný jazyk kompilovaný jazyk Princip virtuálního stroje SW implementace procesoru vlastní sada instrukcí běží uvnitř hostitelské aplikace komunikace s nižší vrstvou na základě rozhraní VM loader Script VM Aplikace OS CPU HDD
Využití skriptů RPG vyprávění příběhu NPC zbraně a předměty nepřátelé FPS logika světa AI... Příkazové skripty Příkaz symbolické jméno označující funkci enginu nebo akci může obsahovat parametry Příkaz param1 param2... je závislý na konkrétní aplikaci Výhody snadná a rychlá implementace Nevýhody omezenost
Struktura VM Výčet (op. kódy) jednotlivých příkazů enum OpCodes { NPCTalk = 1, PlayerTalk = 2,... Struktura pro uložení příkazu struct Command { OpCodes opcode ; object [] params ; Metody pro načtení a spuštění skriptu Struktura VM Načtení foreach ( line in script ) { part = Split ( line ); command = new Command (); command. opcode = ConvertTextToOpCode ( part [0]); switch ( command. opcode ) { case OpCodes. NPCTalk : command. params [0] = part [1];... commandstack. Push ( command );
Struktura VM Spuštění foreach ( command in commandstack ) { switch ( command. opcode ) { case OpCodes. NPCTalk : CreateNPCTextBubble ( command. params [0]); AnimateNPCMouth ( command. params [0]); MakeFunnyNPCSounds ();... stack. Push ( command ); Ukázka RPG dialogu NPCTalk " Tak co mladej? Co to bude?" PlayerTalk "He?" NPCTalk " Plazmatickej anihilátor? Iontovej kvazifikátor?" PlayerTalk " Eee?" NPCTalk "(To je zas materiál...) Zatim si vem tohle!" NPCAnim GiveItem GetItem TinOpener NPCTalk "S tim si snad neublížíš... "
Přidání podmínek Lepší kontrola chování Příkaz ve tvaru: rule : condition => command command... Ukázka RPG dialogu rule : visit greater 0 => NPCTalk "To seš zase ty? Tak co to bude?" PlayerTalk "já... JÁ BYCH CHTĚL TEN KVAZIFIKÁTOR? ( myslim )" NPCTalk " Dobrá volba!" PlayAnim GiveBigItem GetItem Quasificator rule : visit equal 0 => NPCTalk " Tak co mladej? Co to bude?" PlayerTalk "He?" NPCTalk " Plazmatickej anihilátor? Iontovej kvazifikátor?" PlayerTalk " Eee?" NPCTalk "(To je zas materiál...) Zatim si vem tohle!" PlayAnim GiveSmallItem GetItem TinOpener NPCTalk "S tim si snad neublížíš... " Increase visit
Procedurální skripty Jazyky se složitou strukturou většinou založeny na C Nutnost porozumět jazyku a přeložit do jazyka VM VM spouští přeložený kód Překlad jazyka Předmět FJP :-) 1. Lexikální analýza 2. Parsování/Syntaktická analýza 3. Sémantická analýza 4. Vytvoření intermediate kódu 5. Optimalizace 6. Assembler
Front End a Back End Front End Analýza kódu a vytvoření i-kódu Back End Optimalizace a vytvoření low-level kódu Rozdělení umožňuje snadnou náhradu jedné či druhé části např. místo C stylu použít Pascalský jazyk Ukázka RPG dialogu run () { if( visit ==0) { NPCTalk (" Tak co mladej? Co to bude?");... visit =1; else { answer = NPCAsk ("To seš zase ty? Tak co to bude?", "er... "," kvazifikátor "); if( answer ==" kvazifikátor ") { PlayerTalk ("já... JÁ BYCH CHTĚL TEN KVAZIFIKÁTOR?"); NPCTalk (" Dobrá volba!"); PlayAnim ( GiveBigItem ); GetItem ( Quasificator ); hasweapon = true ; else { NPCTalk (" Napřed se nauč s tim co máš!");
Integrace scriptů do programu Nelze volat metody přímo kódy běží na jiném procesoru nesdílejí stejnou paměť Export funkcí do skriptu zaregistrování ukazatele na funkci VM.RegisterFunction("name",functionInfo) Import funkcí do jazyka zavolání VM funkce VM.Call(function) Jazyk Lua Jednoduchý jazyk a skriptovací systém syntaxe je mix mezi C, Pascalem... Knihovna Lua nabízí základní operace s VM inicializace, ukončení, nahrání a spuštění skriptu interface pro import a export metod součástí je i compiler navázání na.net LuaInterface
Konstrukce jazyka Lua Komentáře pouze jednořádkové -- toto je komentář Konstrukce jazyka Lua Proměnné netypované nemusí být nutně deklarované (lepší pokud jsou) identifikátory má stejný tvar jako v C x,y =5,3; t=" ahoj "; x,t=t,x;
nil neinicializovaná proměnná Konstrukce jazyka Lua Datové typy Čísla desetinná nebo celá - nerozlišuje se Řetězce Funkce ukazatel na funkci Tabulky komplexní struktura Uživatelská data speciální typy odpovídající ukazatelům Konstrukce jazyka Lua Tabulky asociativní pole standardně indexovaná od 1 mohou být heterogenní indexy mohou být řetězce přístup přes. Item = {; Item [" name "] = " Heal Potion lvl 1"; Item. type = " Heal "; Item. Price = 10; Item. Power = 1.;
Konstrukce jazyka Lua Operátory aritmetické +, -, =, *, /, ^,.. relační ==, ~=, <, >, <=, >= logické and, or, not Konstrukce jazyka Lua Podmínky if výraz then blok ; elseif výraz then blok ; else blok ; end
Konstrukce jazyka Lua Cykly while výraz do blok ; end for index = start, stop, step do blok ; end for klíč, hodnota in tabulka do blok ; end repeat blok ; until výraz Konstrukce jazyka Lua Funkce proměnné jsou globální, pokud se nepoužije local na funkce se lze odkazovat reference = Funkce; reference(); reference může být přiřazena i elementu tabulky náhrada OOP function Funkce ( parametr, parametr,...) return hodnota end
Konstrukce jazyka Lua Export funkcí nastavit k jakému skriptu se vztahuje spojit názvem dodat ukazatel na funkci v C se předávání parametrů zajišťuje přes zásobník Lua lua_register ( pluastate, název, ukazatel ) Konstrukce jazyka Lua Import funkcí umístit adresu funkce do zásobníku do zásobníku Lua umístit parametry zavolat funkci lua_getglobal ( pluastate, název ); lua_pushnumber ( pluastate, parametr ); lua_call ( pluastate, početvstupů, početvýstupů );
Konstrukce jazyka Lua Přístup ke globálním proměnným umístit proměnnou do zásobníku přečíst zásobník odebrat ze zásobníku lua_getglobal ( pluastate, název ); lua_tonumber ( pluastate, 1); lua_pop ( pluastate, 1); Lua a.net Pro.NET existuje LuaInterface obaluje inteligentně funkce Lua export funkcí pomocí RegisterFunction automaticky se stará o parametry na globální proměnné lze přistupovat přes indexer instance import funkcí pomocí delegátů delegate GetFunction(...) funkce se pak volá přímo Ukázka spojení Lua a.net http://www.gamedev.net/reference/articles/article2275.asp
Konec Konec