Počítačové hry Skriptování
Obsah přednášky
I
Skriptování
I
Příkazové skripty
I
Procedurální jazyky
I
Lua a ostatní
Literatura a odkazy
I http://www.lua.org/ I http://www.python.org/
I Dalmau. Core Techniques and Algorithms in Game Programming. 2003 I Varanese. Game Scripting Mastery. 2003
Příkládek na začátek – RPG I
Věc struct Item { string Name ; ItemTypeEnum Type ; int Price ; double Power ; }
I
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; ...
I
Pokud nevyhovuje, musím přepsat a PŘELOŽIT
Externí soubor
I
Možnost uložit data do externího souboru Heal Potion lvl 1 Heal 10 .1
I
Co když chci složitější logiku? I
MR funguje jen pro kouzelnice s levelem 5 a výš enum ItemTypeEnum = {... , Magic_Wizardress_Above_Level_5 , ... }
I
Potřeba komplexnějšího formátu
K čemu skriptování
I
Úplné oddělení enginu a dat I I I I
I
grafika audio ... obsah
Bezpečnost I
chyba ve skriptu by neměla být kritická pro zbytek
Způsoby skriptování
I
Použitý jazyk I I I
I
příkazové skripty (jednoduchá syntax, velmi omezené možnosti) procedurální/objektové jazyky dynamické moduly (pozor na bezpečnost)
Způsob spuštění I I
interpretovaný jazyk kompilovaný jazyk
Princip virtuálního stroje
I
SW implementace procesoru I I I
vlastní sada instrukcí běží uvnitř hostitelské aplikace komunikace s nižší vrstvou na základě rozhraní HDD Script VM Aplikace OS CPU
VM loader
Využití skriptů
I
RPG I I I I
I
FPS I I
I
vyprávění příběhu NPC zbraně a předměty nepřátelé logika světa AI
...
Příkazové skripty
I
Příkaz I I I I
I
Výhody I
I
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 snadná a rychlá implementace
Nevýhody I
omezenost
Struktura VM
I
Výčet (op. kódy) jednotlivých příkazů enum OpCodes { NPCTalk = 1 , PlayerTalk = 2 , ...}
I
Struktura pro uložení příkazu struct Command { OpCodes opCode ; object [] params ; }
I
Metody pro načtení a spuštění skriptu
Struktura VM
I
Načtení foreach ( line in script ) { part = Split ( line ); command = new Command (); command . opCode = Con ve rt Te xt To Op Code ( part [0]); switch ( command . opCode ) { case OpCodes . NPCTalk : command . params [0] = part [1]; ... } commandStack . Push ( command ); }
Struktura VM
I
Spuštění foreach ( command in commandStack ) { switch ( command . opCode ) { case OpCodes . NPCTalk : C r eat eNPCText B ub ble ( command . params [0]); AnimateNPCMouth ( command . params [0]); MakeFunnyNPC Sounds (); ... } 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
I
Lepší kontrola chování
I
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
I
Jazyky se složitou strukturou I
většinou založeny na C
I
Nutnost porozumět jazyku a přeložit do jazyka VM
I
VM spouští přeložený kód
Překlad jazyka
I
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
I
Front End I
I
Back End I
I
Analýza kódu a vytvoření i-kódu Optimalizace a vytvoření low-level kódu
Rozdělení umožňuje snadnou náhradu jedné či druhé části I
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
I
Nelze volat metody přímo I I
I
kódy běží na jiném „procesoruÿ nesdílejí stejnou paměť
Export funkcí do skriptu I
zaregistrování ukazatele na funkci VM.RegisterFunction("name",functionInfo)
I
Import funkcí do jazyka I
zavolání VM funkce VM.Call(function)
Jazyk Lua
I
Jednoduchý jazyk a skriptovací systém I
I
syntaxe je mix mezi C, Pascalem. . .
Knihovna Lua I
nabízí základní operace s VM I I
I I
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 I
LuaInterface
Konstrukce jazyka Lua
I
Komentáře I I
pouze jednořádkové -- toto je komentář
Konstrukce jazyka Lua
I
Proměnné I I I
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 ;
Konstrukce jazyka Lua
I
Datové typy I
Čísla I
I I
Řetězce Funkce I
I
I
ukazatel na funkci
Tabulky I
I
desetinná nebo celá - nerozlišuje se
komplexní struktura
Uživatelská data I
speciální typy odpovídající ukazatelům
I
neinicializovaná proměnná
nil
Konstrukce jazyka Lua
I
Tabulky I I I I I
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
I
Operátory I
aritmetické I
I
relační I
I
+, -, =, *, /, ^, .. ==, ~=, <, >, <=, >=
logické I
and, or, not
Konstrukce jazyka Lua
I
Podmínky if výraz then blok ; elseif výraz then blok ; else blok ; end
Konstrukce jazyka Lua I
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
I
Funkce I I
proměnné jsou globální, pokud se nepoužije local na funkce se lze odkazovat reference = Funkce; reference();
I
reference může být přiřazena i elementu tabulky I
náhrada OOP
function Funkce ( parametr , parametr ,...) return hodnota end
Konstrukce jazyka Lua
I
Export funkcí I I I I
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
I
Import funkcí I I I
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
I
Přístup ke globálním proměnným I I I
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
I
Pro .NET existuje LuaInterface I I
obaluje inteligentně funkce Lua export funkcí pomocí RegisterFunction I
I I
na globální proměnné lze přistupovat přes indexer instance import funkcí pomocí delegátů delegate GetFunction(...) I
I
automaticky se stará o parametry
funkce se pak volá přímo
Ukázka spojení Lua a .NET I
http://www.gamedev.net/reference/articles/article2275.asp
Konec
Konec