Univerzita Karlova v Praze

Matematicko-fyzikální fakulta

BAKALÁŘSKÁ PRÁCE

Jan Pešek

Framework pro strategické webové hry

Katedra softwarového inženýrství

Vedoucí bakalářské práce: Mgr. Miroslav Čermák

Studijní program: Informatika

Studijní obor: Obecná informatika

Praha 2013 Rád bych zde poděkoval svému vedoucímu ročníkového projektu a bakalářské práce Mgr. Miroslavu Čermákovi, za jeho podporu, připomínky, odborné rady a vstřícný přístup během zpracování této práce. Dále bych chtěl poděkovat mému příteli Petru Šiškovi za vytvoření ilustrací pro vzorovou hru. Prohlašuji, že jsem tuto bakalářskou práci vypracoval samostatně a výhradně s použitím citovaných pramenů, literatury a dalších odborných zdrojů.

Beru na vědomí, že se na moji práci vztahují práva a povinnosti vyplývající ze zákona č. 121/2000 Sb., autorského zákona v platném znění, zejména skutečnost, že Univerzita Karlova v Praze má právo na uzavření licenční smlouvy o užití této práce jako školního díla podle §60 odst. 1 autorského zákona.

V Praze dne ...... Jan Pešek Název práce: Framework pro strategické webové hry

Autor: Jan Pešek

Katedra: Katedra softwarového inženýrství MFF UK

Vedoucí bakalářské práce: Mgr. Miroslav Čermák, Katedra softwarového inženýr- ství MFF UK

Abstrakt: Tato bakalářská práce popisuje softwarový projekt, který umožňuje tvorbu internetových tahových her v internetovém prohlížeči s důrazem na upra- vitelnost, tzv. framework. Výsledná aplikace umožňuje snadnou tvorbu tahové hry pro dva hráče, a poskytuje mechanismy pro pokročilou konfiguraci prostřed- nictvím modulů naprogramovaných uživatelem. Součástí projektu je vzorová hra s předdefinovanými daty, ukázkovými moduly a grafickou úpravou. V práci jsou zhodnoceny současné technologie použitelné pro vývoj interaktivních interneto- vých aplikací a diskutovány některé klíčové problémy, na které se při vývoji apli- kace naráží. Dále je v textu popis implementace celého projektu, zejména struk- tura aplikace a databázový a objektový návrh. V práci je dále dokumentace k programu zahrnující názorný návod pro tvorbu vlastních modulů.

Klíčová slova: PHP, framework, webová strategie

Title: Framework for internet strategy & heroes

Author: Jan Pešek

Department: Department of Software Engineering, Charles University in Prague

Supervisor: Miroslav Čermák, M.Sc., Department of Software Engineering, Char- les University in Prague

Abstract: This bachelor’s thesis describes a software project framework that ena- bles the user to create an online turn-based game inside an internet browser, focusing on customizability. The framework allows the user to create a game for two players and enables him to implement advanced configuration of the game by programming additional modules. Part of the project is a model game with predefined data, example modules and graphic representation. The text contains an evaluation of current available technologies usable for developing interactive online applications, along with discussion of some key problems that show up during developing such application. The text includes description of project im- plementation, the structure of the application, database and object design and application documentation with a manual for creating customized modules.

Keywords: PHP, framework, web strategy Obsah

Úvod 4 0.1 Strukturapráce ...... 4

1 Analýza projektu 6 1.1 Cílprojektu...... 6 1.2 Existujícíprojekty ...... 7 1.2.1 Modulargaming ...... 7 1.2.2 NowhereEngine...... 7 1.2.3 DotKwebengine ...... 8 1.2.4 NewWorldsEngine...... 8 1.2.5 Shrnutí ...... 8 1.3 Volbatechnologií ...... 9 1.3.1 Kritériavolby ...... 10 1.3.2 Programovacíjazyk...... 11 1.3.3 Databáze ...... 13 1.3.4 PhPFramework...... 14 1.3.5 Uživatelskérozhraní ...... 16 1.4 Klíčovéproblémy ...... 17 1.4.1 Členěníaplikace...... 17 1.4.2 Komunikace klient-server ...... 17 1.4.3 Načítání přídavných modulů ...... 23 1.4.4 Zobrazeníbitevníplochy ...... 24 1.4.5 Viditelnost vnitřních proměnných v objektovém návrhu.. 26 1.4.6 Hledánínejkratšícesty ...... 27

2 Struktura aplikace 28 2.1 Entityframeworku ...... 28 2.1.1 Struktura dle funkčních částí ...... 29 2.1.2 Struktura dle použitých technologií ...... 31 2.1.3 Struktura dle objektového návrhu ...... 31

1 3 Implementace 32 3.1 Databázovýmodel ...... 32 3.1.1 Procedury ...... 36 3.2 Objektovýmodel ...... 37 3.2.1 Třídy poskytované frameworkem ...... 38 3.2.2 User ...... 38 3.2.3 Battle ...... 39 3.2.4 Army ...... 40 3.2.5 Unit ...... 41 3.2.6 Hero ...... 45 3.2.7 Weapon, Armor, Formation, Race, UnitType, School . . . 46 3.2.8 Schopnostihrdiny...... 47 3.2.9 Ostatnítřídy ...... 48 3.3 Zobrazovacívrstvaaplikace ...... 49 3.3.1 Uživatelskérozhraníbitvy ...... 49 3.3.2 Uživatelské rozhraní správní části hry ...... 52 3.4 Komunikacevreálnémčase ...... 52 3.4.1 Frontačinností ...... 53

4 Administrátorská dokumentace 54 4.1 Instalace...... 54 4.2 Konfigurace ...... 55 4.3 Programátorskéúpravy...... 55 4.3.1 Načítánívlastnítřídy...... 55 4.3.2 Tvorbavlastníjednotky ...... 56 4.3.3 Tvorba vlastní hrdinovy schopnosti ...... 57 4.3.4 Tvorba vlastního zvláštního výcviku ...... 59 4.3.5 Úpravahrdiny...... 59 4.4 Používánísystémuzpráv ...... 62 4.5 Přidání dalších událostí pro schopnosti či zvláštní výcviky .... 63

5 Herní dokumentace 65 5.1 Správa uživatelského účtu ...... 65

2 5.2 Správaarmády ...... 65 5.3 Správabitvy...... 67 5.4 Bitva...... 68

6 Obsah přiloženého DVD 71 6.1 Virtuálnístroj...... 71

Závěr 73

Literatura 75

3 Úvod

Význam internetových aplikací stále roste - mnoho desktopového softwaru se pře- souvá do podoby internetových aplikací běžících pouze ve webovém prohlížeči. Software on-line představuje pro uživatele nemalé výhody, především možnost rychlého spuštění bez jakékoli instalace a přístup k aplikaci z libovolného za- řízení. Jak se zvětšuje počet online aplikací, zvyšuje se i kvalita webových prohlížečů a tím se opět zvyšují možnosti pro vývoj těchto aplikací. Z těchto důvodů jsem si zvolil jako téma této práce vývoj online herního frameworku pro tvorbu strategických tahových her pro dva hráče. Framework pro tvorbu her jsem zvolil jednak z důvodu pokrytí širokého spektra problémů, na něž se při vývoji internetové aplikace dá narazit (především problémy komunikace server-klient a klient-klient), a jednak z důvodu mé osobní náklonnosti k tomuto tématu. Cílem práce je analýza možností vývoje on-line herního frameworku a jeho návrh, následná implementace a tvorba ukázkové hry. V práci jsou diskutovány klíčové problémy, na něž se při vývoji herního frameworku naráží, a porovnávána možná řešení. Nejlépe vyhovující řešení těchto problémů jsou pak implementována do navrženého frameworku a implementace je popsána podrobněji. Výsledný framework musí především poskytovat možnost snadné tvorby vlast- ní hry. Požadavkem je rovněž rozšiřitelnost, aby se hra postavená nad framewor- kem dala libovolně měnit.

0.1 Struktura práce

Práce začíná v 1. kapitole analýzou problému. Stanovuje cíl projektu a předsta- vuje ostatní obdobné projekty, obsahuje porovnání možných použitelných tech- nologií a popisuje klíčové problémy, na něž se při návrhu projektu naráží. Druhá kapitola popisuje strukturu aplikace a navrhuje možné členění z růz- ných pohledů. Ve třetí kapitole se nachází popis konkrétní implementace zahrnující návrh databáze s popisem všech tabulek a procedur a objektový model popisující nej-

4 důležitější třídy návrhu. Kapitola dále představuje základní rysy implementace zobrazovací vrstvy aplikace a nakonec představuje řešení komunikace v reálném čase. Čtvrtá kapitola prezentuje programátorskou dokumentaci frameworku, po- pisující jednak instalaci a konfiguraci hry, a jednak na konkrétních příkladech ukazuje, jak upravovat některé herní entity a herní mechanismy samotné. V páté kapitole se nachází uživatelská dokumentace vzorové implementované hry, vysvětlující, jak začít hrát. Šestá kapitola popisuje obsah přiloženého DVD. V závěru je zhodnocení celé práce s naznačením možností dalšího rozvoje.

5 1. Analýza projektu

Tato kapitola je zaměřena na vytyčení konkrétního cíle projektu, zhodnocení obdobných projektů, představení možných technologií a jejich vlastností a diskuse klíčových problémů, jež se při tvorbě herního frameworku vyskytují.

1.1 Cíl projektu

Jak již bylo řečeno v úvodu, cílem této práce je vytvořit framework pro tvor- bu webových tahových her, v nichž dochází ke střetu dvou hráčů prostřednic- tvím konfigurovatelných armád. Principem takové hry je střet dvou protihráčů prostřednictvím jejich armád. Framework definuje základní entity hry - armá- du, jednotku, bitvu, hrdinu. Poskytuje mechanismy pro interakci těchto objektů a možnost jejich úprav. Důležitými cíly frameworku jsou rovněž jeho upravitel- nost a rozšiřitelnost. Upravitelnost probíhá jednak na úrovni změny dat - tedy při konfiguraci hry se do databáze nahrají jiné texty a hodnoty, na stanovená místa na serveru obrázky. Další úrovní upravitelnosti je pak programování nových funkcí - speciál- ních jednotek či schopností, jež spočívá ve vytvoření nové třídy pro tento prvek, a následně vytvoření záznamu v databázi. Poslední úrovní je pak přeprogramová- ní samotných herních mechanismů - framework sám poskytuje vztahy zajišťující herní funkčnost, nicméně každý uživatel frameworku si tyto vztahy může přepsat dle svého uvážení. Pro nastavení parametrů hry poskytuje framework uživatel- sky přívětivé administrační rozhraní, ostatní úpravy se pak musí provádět přímo prostřednictvím editoru kódu. Rozšiřitelnost se částečně kryje s upravitelností, ale přidává i další hledisko - rozšiřitelnost na různé technologie, jež může přinést výhody v podobě efektiv- ního využití zdrojů. Framework je potřeba tvořit s ohledem na možnosti využití různých technologií, jež mohou omezovat přenositelnost, příp. jež zatím nejsou v použitelném stádiu vývoje. Filozofií je tedy snažit se základní funkčnost fra- meworku udržet pokud možno co nejpřenositelnější (ve smyslu minima omezení požadavků nad rámec obvyklého webového serveru), ale zároveň ponechat mož-

6 nost snadného nasazení a využití specializovaného softwaru, pokud je k dispozici.

1.2 Existující projekty

Obdobných projektů, tedy herních webových frameworků, není příliš mnoho, vy- jma frameworků pro tvorbu velmi jednoduchých (tzv. ”casual”) her, které jsou ve srovnání s FISH jednoduché a nabízejí jenom velmi omezenou funkčnost. Klíčovou myšlenkou frameworku je, kromě poskytování základního herního mechanismu, jeho snadná rozšiřitelnost, modularita - musí zde být možnost do- programovávat libovolné funkce všem objektům (jednotkám), možnost konfiguro- vat jednotky, mapy či kouzla (vyplňováním předdefinovaných atributů, tedy bez samotného programování), možnost pohodlně měnit grafickou stránku a nakonec poskytovat dojem bitvy v reálném čase. Z tohoto pohledu lze taky posuzovat ostatní projekty, jež jsou zmíněny dále v této kapitole. Tyto projekty slouží jako referenční projekty, ze kterých se vychází při tvorbě tohoto frameworku, a zároveň jako projekty, jejichž chyb je třeba se vyvarovat.

1.2.1 Modular gaming

Vývoj frameworku Modular Gaming je zastaven, k dispozici je aktuálně vývojář- ská verze 0.6. Tento projekt je založen na PhP frameworku a využívá databázi MySQL. Projekt má naprosto nedostatečnou (prakticky žádnou) doku- mentaci, vytváření vlastní hry je tak velice obtížné, a není k dispozici ani žádné administrační rozhraní. Framework nemá žádný grafický model, tvoří se v něm tedy čistě textové hry a rovněž ani nedisponuje žádnou formou dojmu bitvy v reálném čase. [3]

1.2.2 Nowhere Engine

Nowhere Engine má podobné cíle jako tento projekt, nicméně implementace je za- staralá. Dojem hry v reálném čase je řešen periodickým zasíláním GET požadavků na server (každých 200ms). Kód není objektový, není nijak oddělena prezentač- ní a výpočetní část, Html část zůstala v podobě z roku 2005, kdy vývoj tohoto

7 frameworku začal. Velmi pěkně je zde však uděláno administrační rozhraní, po- skytující i neprogramátorovi možnost zcela jednoduše vytvářet nejen veškeré herní předměty, ale především vlastní mapy, pomocí jednoduchého grafického editoru ve stylu známé hry Heroes of Might and Magic. Nowhere engine je napsaný v PhP a využívá databázi MySQL. [4]

1.2.3 DotK web engine

Vývoj projektu DotK je zastaven od roku 2009. Má rozsáhlý JavaScriptový engine postavený nad frameworkem Prototype zajišťující mj. asynchronní komunikaci mezi klientem a serverem, hledání nejkratší cesty či zobrazení celé mapy. Na rozdíl od ostatních zde zmiňovaných frameworků není grafika map (terén) automaticky generovaný, ale využívá předem připravených obrázků. Efekt reálného času je zde opět dosažen opakovaným odesíláním HTTP požadavků na server. DotK je napsaný v PhP a používá databázi Firebird. [5]

1.2.4 New Worlds Engine

Tento engine je zdařilý z hlediska rozšiřitelnosti - skutečně se jedná pouze o en- gine, jenž načítá všechny herní funkce jako moduly, které jsou navíc velmi dobře zdokumentované, prezentační vrstva je oddělena od aplikační, a tak lze také rela- tivně snadno tvořit líbivý uživatelský interface. Tím však klady končí - framework jako takový nemá grafický model a nefunguje v reálném čase. Ačkoliv dokumen- tace k modulům je dobrá, moduly nemohou ovlivňovat samotný průběh hry, ale pouze přidávat další prvky v souladu s pevně daným herním mechanis- mem, tedy předměty a kouzla. NW engine je napsaný v PhP a používá databázi MySQL. [6]

1.2.5 Shrnutí

Je vidět, že ostatní projekty jsou buď již zastaralé, nebo jsou zaměřeny na jiné cíle, než jsou cíle projektu FISH. Ačkoli některé z těchto projektů mají mož- nost programování vlastních funkcí, jsou buďto velice omezené na programování jednoduchých akcí v pevně stanovenou událost, nebo naprosto postrádají gra-

8 fický prezentační element, či trpí naprostým nedostatkem dokumentace (a tedy k pře- či připrogramování funkcí jsou prakticky nepoužitelné). Souhrn výhod je v tabulce 1.1.

Tabulka 1.1: Porovnání referenčních projektů Framework Modularita Hratelnost Technologie Modular Gaming Nedostatečná do- Pouze textové hry PhP, MySQL, kumentace Kohana Nowhere Engine Vytváření veš- Dojem hry v re- PhP, MySQL kerých herních álném čase dosa- předmětů vč. žen obnovováním map okna DotK web engine Vše pouze pře- Dojem hry v re- PhP, Firebird programováním álném čase dosa- žen obnovováním okna New Worlds engi- Velmi dobře ře- Nemá grafickou PhP, MySQL ne šené moduly pro reprezentaci, ne- herní předměty funguje v reálném čase

Nejčastější chybou návrhu je tedy nedostatečná modularita, ze které plyne špatná možnost provádění úprav ve frameworku. Dalším častým problémem je nedostatečná dokumentace znemožňující úpravu vlastních her. Toto jsou chyby, jichž by se měl projekt FISH vyvarovat. Naopak jako reference se ze zmíněných projektů dá vzít především adminis- trační rozhraní z Nowhere Engine, kde se celá hra dá přehledně upravovat pomocí intuitivních tabulek s daty, z projektu New Worlds Engine je pak možné převzít inspiraci při návrhu načítaných modulů - moduly jsou zde kompletně oddělené části kódu, jež stačí nahrát na patřičné místo do adresářové struktury a o nic víc se není třeba starat, systém je automaticky načte a poskytuje o nich i přehledné informace (informace o všech načtených modulech včetně verze, v příp. problému s načítáním i chybové hlášení).

1.3 Volba technologií

Základním kritériem pro volbu technologie je fakt, že aplikace poběží prostřed- nictvím webového prohlížeče. Požadavek na serverovou část je pak co nejmenší

9 odchylka od standardních webových serverů, aby framework bylo možné nain- stalovat bez použití neobvyklých řešení. Tím prakticky odpadá možnost použití klasických jazyků jako C++ či C#. V této kapitole jsou diskutovány části aplikace dle možných technologií a tyto technologie vzájemně porovnány.

1.3.1 Kritéria volby

Kritéria pro rozhodování o použití jednotlivých technologií jsou zejména násle- dující:

• široká podpora (ve smyslu dobré dokumentace, množství dostupných ma- teriálů na internetu či knižně a aktivní internetové komunity),

• výkon (je třeba, aby jeden server zvládl bez problémů obsluhovat řádově stovky hráčů zároveň),

• robustnost (framework musí být schopen se zotavovat z různých výjimek či chyb bez ztráty dat, musí zvládat ”nepříznivé” uživatelské vstupy a musí být stabilní),

• licence (preferovanou licencí je obecně open source - pro konkrétní licenci pak platí pravidlo ”čím liberálnější, tím lépe”, nicméně toto není zásadní požadavek),

• portabilita (ideálně aby bylo framework možno jednoduše nasadit na libo- volný webový server - obecně by projekt neměl záviset na jedné konkrétní technologii či platformě, ne vždy se však lze tomuto kompletně vyvarovat - požadavkem tedy je co nejmenší závislost na specifických technologiích),

• škálovatelnost (vzít v úvahu možné rozšiřování pro řádově násobné množ- ství hráčů, kdy se servery mohou doplňovat o technologie pro zvýšení vý- konu, jako rozsáhlejší cachování či nasazení frameworku na více serverů paralelně).

Dále je třeba zvážit vývojářské prostředí a programátorské zkušenosti. Zají- mavým hlediskem také je, kolik a které z ostatních projektů danou technologii využívají.

10 1.3.2 Programovací jazyk

Pro serverovou část aplikace jsou z nejvyužívanějších jazyků k dispozici PhP, Ruby on Rails (resp. Ruby), JavaServer Pages, ASP .NET, Python, JavaScript a Scala.

• PhP [9] má dobrou podporu (velmi aktivní internetová komunita), je snad- no rozšiřitelné a škálovatelné, jedná se o open source a je možné jej provozo- vat jak na Windows, tak na Linux. Je k dispozici velké množství funkčních frameworků. V PhP je napsán například Facebook, Wikipedia či Yahoo, všechny herní frameworky zmíněné výše a nepočítaně stránek na internetu.

• Ruby on Rails [10] je framework postavený na jazyku Ruby. Je vydáva- ný jako open source, je kolem něj velmi živá komunita, je však zpravidla užíván pouze na Unixových systémech. V Ruby on Rails je napsaná např. uživatelská část Twitteru či on-line tv služba Hulu.

• JavaServer Pages [11] je poměrně výkonná, není však příliš používaná a nemá tak rozsáhlou podporu. V Javě je částečně napsán např. Twitter či eBay.

• ASP .NET [12] má velkou podporu, přináší však závislost na platformě Windows. Výhodou je naopak velmi dobré vývojářské rozhraní. Je v něm napsán např. Bing.

• V Pythonu [13] je nejpoužitelnějším řešením framework Django. Framework má dobrou podporu cachování, sám o sobě však zaostává rychlostí, a je zde problém omezení na servery se zkompilovanou podporou Pythonu. Nejčastě- ji se používá v kombinaci se serverem Apache s nainstalovaným mod python, který zapouzdřuje interpret Pythonu přímo do Apache, s pomocí CGI či nej- novější FastCGI. Jediná metoda, kterou oficiální dokumentace doporučuje je použití FastCGI na serveru apache v podobě mod fcgid, jež ovšem přináší závislost na tomto modulu. [18] Python využívá například Google.

• JavaScript [14] je možné použít pro programování serverových aplikací s využitím serveru Node.js [17] (a dalších, nicméně Node.js je v současné

11 době nejrozšířenější). Toto má velkou výhodu v možnosti aktivně zasílat data klientovi i bez jeho požadavku, na druhou stranu použití Javascriptu na serveru není příliš výhodné řešení kvůli omezením daným tímto jazykem, jako je např. absence tříd a klasické dědičnosti (řešené zde pomocí tzv. prototypů). Dalšími zápory jsou špatná přenositelnost a rovněž fakt, že Node.js samotný zatím nebyl vydán ve stabilní verzi.

• Scala [15] je málo využívaný mladý jazyk, jehož hlavní požadavek při ná- vrhu je škálovatelnost. Má stejnou syntaxi jako Java, nicméně je značný nedostatek dokumentace a podpory, kolem tohoto jazyku neexistuje prak- ticky žádná komunita, příliš se nevyužívá a přenositelnost je zde problém. Využívá ho např. Twitter.

• Phalanger [16] je implementace PhP pro prostředí .Net. To má oproti obvyklému přístupu runtime interpretace výhodu zlepšení výkonu, jedno- duššího a bezpečnějšího testování (kompilátor odhalí všechny možné vý- jimky předem), navíc přidává možnost provázat program s částmi v jiných .Net jazycích. K běhu je však potřeba Phalanger nainstalovaný na serveru s Windows a IIS minimálně verze 7.

Hlavní výhody a nevýhody zmíněných jazyků shrnuje tabulka 1.2. Výslednou volbou je PhP, i s ohledem na zkušenosti s tímto jazykem. Ve srov- nání s ostatními zmíněnými jazyky PhP v ničem příliš nezaostává, je snadno přenositelné mezi Windows i Linux, dokáže spolupracovat se všemi používanými databázemi, má dobře dostupnou kvalitní dokumentaci, dobře se ladí. V kombi- naci s http serverem Apache je pak možné využít mnoho pokročilejších funkcí pro škálování a cachovaní ([1]). Naopak žádný z jiných jazyků PhP v ničem výrazně nepřevyšuje (snad až na Node.js, který díky možnosti autonomního zasílání dat klientovi převyšuje všechny ostatní zmíněné technologie). PhP je široce rozšíře- no na všechny typy webových projektů, od nejmenších stránek po opravdu velké weby, což svědčí o jeho použitelnosti. Opravdu velké stránky používají kromě zmíněných jazyků vždy i nějaký další, např. Facebook využívá PhP v kombinaci s C a C++. Facebook rovněž napsal překladač Hip Hop, jež překládá PhP do optimalizovaného C++ pro zrychlení kódu (Facebook proklamuje snížení nároků

12 Tabulka 1.2: Porovnání možných programovacích jazyků Technologie Výhody Nevýhody PhP Podpora, jednodu- Samo o sobě nepodporu- ché nasazení, licence, je cachování, výkon množství dostupných knihoven Ruby on Rails Podpora, licence Závislost na Unixových systémech JavaServer Pages Výkon Vyžaduje specifický soft- ware na serveru (ser- vlet), menší podpora ko- munity ASP.NET Podpora, jednoduché Závislost na platformě nasazení Windows Python Podpora Závislost na serveru Apache s podporou Pythonu JavaScript Možnost zasílání dat kli- Závislost na specifickém entovi bez jejich vyžádá- serveru (např. Node.js) ní, licence Scala Škálovatelnost, výkon Závislost na specifickém serveru, nepříliš velká podpora na CPU až o 50%, v závislosti na stránce), což je jedna z možností potenciálního budoucího rozvoje. Jinou možností je využití projektu Phalanager, kdy kód (či jeho části) mohou běžet zkompilovaně na Windows serverech.

1.3.3 Databáze

Databáze je nedílnou součástí projektu, měla by být dostatečně rychlá, bezpečná, podporovat integritní omezení a rozumně rychlé uložené procedury. Databázový- mi systémy nejčastěji používanými v prostředí webu jsou především MySQL, PostgreSQL, Firebird, Oracle, MS SQL a SQLite.

• Oracle [20] a MS SQL [19] jsou sice výkonné databáze poskytující velkou řadu funkcí, s dobrou schopností replikace a load balancingu, nejsou však vhodné kvůli komerční (drahé) licenci.

• SQLite [21] je designována jakožto velmi jednoduchá malá databáze bez pokročilejších funkcí, jež se odlišuje svoji filozofií - nefunguje jako klasic-

13 ká klient-server aplikace, ale jedná se o malou knihovnu, jež se přilinkuje k aplikaci a dá se ovládat pomocí jednoduché rozhraní. Při větším množství požadavků ale zaostává výkonem a škálovatelností. Pro takto velký projekt již není vhodná.

• MySQL [22] je v kombinaci s PhP zdaleka nejpopulárnější, nicméně pod- porou standartů SQL zaostává za PostgreSQL i Firebird. Navíc má dvojí licencování, nejedná se tedy přímo o open source, a budoucnost licencová- ní pod vedením firmy Oracle je v současné době nejistá. Má velmi dobrou podporu a využívá jej např. Facebook.

• PostgreSQL [23] je známé pro svou spolehlivost, podpory velkého množ- ství integritních omezení či velmi dobré podpory transakcí. Podporuje rov- něž komplexní možnosti konfigurace databázového systému, jež se dají vyu- žít např. pro load balancing či replikaci. Poskytuje možnost psaní uložených procedur kromě pl/pgsql rovněž v C, Perlu či Pythonu. Má přehlednou do- kumentaci (včetně podrobného popisu ladění výkonu dotazů), dobrou pod- poru od komunity a je vydávána již od roku 1984 pod licencí BSD/MIT. Využívá jej např. Yahoo.

• Firebird [24] svými rysy připomíná PostgreSQL (mj. např. podporuje pro- cedury v pl/pgsql). Oproti němu však zaostává v podpoře a rozšířenosti.

Jako nejlepší databáze pro framework se tedy jeví PostgreSQL, díky své sta- bilitě, rychlosti, podpoře a licenci ([2]).

1.3.4 PhP Framework

PhP framework je vhodné využít především kvůli množství nástrojů, jež automa- ticky poskytuje. Není třeba znova programovat vrstvy pro přístup do databáze, navrhovat vlastní MVC model či šablonovací systém. Ideální framework by měl být rychlý, poskytovat velké množství funkcí, měl by mít kompletní přehlednou dokumentaci a množství dalších zdrojů (návodů, knížek) a živou internetovou komunitu, měl by být bezpečný a otevřeně licencovaný. Nejpoužívanější, nejpod- porovanější a nejvýkonnější PhP frameworky jsou především následující:

14 • CakePhP [25] vynucuje model MVC, podporuje vývoj pomocí konzole, používá techniku scaffolding (rychlé navrhování, resp. automatické genero- vání základu webu), obsahuje vestavěné nástroje pro jednotkové testy, má dobrou online podporu. Zaostává v množství funkcí i rychlosti, nicméně běží i na PhP 4.

• Nette [26] je velmi výkonný framework českého původu obsahující pokročilé funkce pro zabezpečení a výborné ladící nástroje. Je rozšířen především v ČR, což již z principu trochu omezuje velikost komunity.

• CodeIgniter [27] je velmi jednoduchý, vhodný spíše pro menší weby, na větších projektech zaostává výkonem i absencí pokročilejších funkcí. Vynu- cuje použití návrhového vzoru MVC.

• Kohana [28] vychází z CodeIgniter, avšak dnes je již plnohodnotným sa- mostatným frameworkem. Kohana je oproti CodeIgniter robustnější, je celá napsaná v PhP 5.3, díky čemuž poskytuje některou pokročilejší funkciona- litu, opět využívá vzoru MVC a ačkoliv na tom má být výkonově lépe než CodeIgniter, stále zde platí vhodnost spíše pro menší a střední projekty.

• Yii [29] je PhP framework velmi vhodný pro rapid development, jelikož poskytuje řadu generátorů, pomocí nichž je velmi jednoduché navrhnout i poměrně komplexní webové aplikace. Má poměrně velké množství funkci- onality obsažené v pluginech, vyžaduje MVC, je velmi rychlý. Ze zde zmiňo- vaných frameworků je nejmladší, nicméně již má velmi rozsáhlou komunitu a množství dostupných materiálů.

• Zend PhP Framework [30] je známý pro svou stabilitu, je velmi rozšířený pro enterprise nasazení na opravdu velkých projektech, umožňuje vysokou míru přizpůsobení a obsahuje mnoho vestavěných nástrojů pro existující webové služby, lokalizaci či jednotkové testy. Model MVC je podporovaný, nikoli však vyžadovaný. Mnoho funkcionality je možné přidat pomocí řady kvalitních pluginů (některé jsou nicméně placené). Vyžaduje PhP verze ale- spoň 5.2.3, má kvalitní podporu ORM Doctrine. Vyžaduje server Apache zkompilovaný s podporou Zendu.

15 • [31] je obdobně jako Zend určen primárně pro enterprise nasazení a svými vlastnostmi se od ZF mnoho neliší, mj. rovněž obsahuje kvalitní podporu ORM Doctrine, MVC podporuje, ale nevyžaduje. Pluginy dostup- né přes oficiální distribuční kanál se však velmi liší kvalitou (na rozdíl od Zend, kde je každý vkládaný kód kontrolován vývojářským týmem).

Tabulka 1.3: Porovnání možných PhP frameworků Název Výhody Nevýhody CakePhP Scaffolding, jednotkové Rychlost, omezené testy, stačí PhP4 množství vestavěných funkcí Nette Rychlost, zabezpečení, Omezené množství ve- ladící nástroje stavěných funkcí CodeIgniter Jednoduchost Rychlost, omezené množství vestavěných funkcí Kohana Jednoduchost Rychlost Yii Scaffolding, množství - funkcionality Zend Stabilita, rychlost Dokumentace, doporu- čené použití přináší zá- vislost na Zend Server Symfony Stabilita, množství Dokumentace, výkon funkcí

Jako nejvhodnější pro projekt FISH se jeví framework Yii - je velmi rychlý, moderní, nemá problém ani s většími projekty a má velmi rozsáhlou množinu funkcí. Má velmi dobrou dokumentaci, živou komunitu a velké množství dostup- ných materiálů.

1.3.5 Uživatelské rozhraní

Uživatelské rozhraní bude napsané v HTML a CSS, pro interakci s uživatelem pak bude četně využíván také JavaScript. JavaScript je široce podporovaný, výkonný (v moderním prohlížeči) a umožňuje v prohlížeči jednoduše vytvářet interaktivní aplikace připomínající desktopové aplikace. Alternativou je rozhraní ve Flashi, nicméně pro tuto úlohu se Flash nejeví jako dobrá volba pro jeho velikost, licenci a potřebu nainstalovaného přehrávače u klienta [35].

16 JavaScriptový framework

JavaScript bude potřeba v uživatelském rozhraní bitevní plochy především pro zasílání asynchronních požadavků na server, pro interaktivní menu, zobrazování podrobných informací o jednotkách a pro vyhledávání nejkratší cesty. Vhodnou volbou je určitě využít některý framework, který poskytuje velké množství funk- cionality zdarma. Frameworků existuje mnoho, hlavními kritérii pro jeho volbu jsou rychlost, velikost, množství podporovaných funkcí (příp. i ve formě pluginů), dobrá dokumentace a podpora komunity. Z existujících frameworků nejlépe vy- chází framework jQuery, jenž je dostatečně malý a rychlý, má velmi dobrou doku- mentaci a jednoduché API, obrovskou aktivní on-line komunitu a velké množství dostupných pluginů [32], [33], [34].

1.4 Klíčové problémy

V této kapitole je představeno několik nejzásadnějších problémů, se kterými je nutné se při návrhu vypořádat, a možných přístupů k řešení s hodnocením kladů a záporů každého řešení.

1.4.1 Členění aplikace

Aplikace se bude držet zaběhlého modelu Model-View-Controller, resp. Model- View-Presenter, bude tedy oddělena logika reprezentace dat (model), vrstva pro práci s těmito daty (controller) a vrstva sloužící pouze k zobrazení. Rozdíl Presen- teru oproti Controlleru je, že Presenter je exkluzivní člen mezi View a Modelem. Všechna data tedy procházejí přes něj.

1.4.2 Komunikace klient-server

Komunikace klient server je klíčová, jelikož se může stát úzkým hrdlem celé apli- kace, pokud se bude přenášet příliš mnoho dat. Komunikace se dá rozdělit na dvě skupiny: pro hrajícího klienta a přihlížejícího klienta. Hrající klient je hráč, který je právě na tahu, a tedy provádí určité změny se svojí armádou (např. pohybuje oddíly). Přihlížející klient je protihráč, který pouze sleduje tahy hrajícího hráče.

17 Jsou zde čtyři hlavní požadavky:

• bezpečnost (jak z hlediska potenciálního napadení útočníkem, jež může serveru podstrčit falešná data o svém tahu, tak z hlediska ztráty dat, kdy v případě nějaké chyby musí server hru vždy zachovat v konzistentním stavu a přitom neztratit žádné tahy, resp. jich ztratit minimum),

• omezení počtu http požadavků (tedy nezasypávat server zbytečnými dotazy, což by mohlo být příčinou zahlcení serveru v případě velkého počtu hráčů),

• minimalizace práce serveru (z hlediska prováděných výpočtů a počtu databázových dotazů, které je třeba rozumně agregovat),

• snadná nasaditelnost (tedy zachovat nezávislost na řešení založeném na konkrétní platformě či technologii, příp. alespoň nabízet alternativy).

Pro komunikaci klienta se serverem či obou klientů mezi sebou lze využít následující technologie.

Flash

Flash se za určitých podmínek dá využít pro navázání přímého peer to peer spo- jení mezi hrajícím a přihlížejícím klientem. To je zdaleka nejefektivnější řešení z hlediska zátěže serveru, zásadním problémem je ale právě absence serveru, a to především z důvodu zabezpečení - při tomto řešení je celá aplikace provozo- vána na klientovi, na server se odešle až výsledek celé bitvy (tzn. informace o vítězi). Aplikace na klientovi se dá rozebrat (např. pomocí SWF decompileru ne- bo podstrkávání globálních proměnných v prohlížeči) a serveru podstrčit falešné výsledky (případně druhému klientovi). Tedy potenciální útočník může například odstranit limit pohybových bodů pro své oddíly, a druhý klient nemá jak to ověřit (za předpokladu, že nemá informace o armádě protihráče, což by mít neměl). Další nevýhodou využití flashe je nutnost flash playeru verze 10. Pro navázání P2P spojení je pak nutnost mít server, jež tyto spojení bude zařizovat. Jednou možností je projekt Adobe Cirrus, jež funguje v rámci projektu Adobe Labs, avšak není ve stabilní verzi a pravděpodobně ani nebude, jelikož Adobe namísto

18 rozvoje tohoto projektu propaguje Flash Media Server. Rovněž je otázkou, jak dlouho projekt Cirrus zůstane zdarma (jelikož při navazování se aktivně používají servery Adobe, framework by byl na těchto serverech závislý). Adobe Flash Media Server rovněž není řešením právě pro svoji cenu (i zde existuje development verze pro nekomerční využití, kromě stejné nevýhody spoléhání na řešení třetí strany je zde však omezení na 10 paralelních spojení, přičemž pro takto limitovaný po- čet hráčů se dá aplikace efektivně vytvořit i bez flashe). Nevýhodou je rovněž možné blokování spojení firewallem. Technologie Adobe Cirrus však při implicit- ním nastavení běžně používaných firewallů funguje v drtivé většině případů bez problémů.

Ajaxová aplikace na comet serveru

Využití comet serveru má velkou výhodu z hlediska přenosu dat k přihlížejícímu klientovi. Hrající klient tak provede určitou akci (pohyb oddílu), která se odešle serveru. Server ověří, že akce je legitimní, a po jejím provedení na tuto skutečnost upozorní přihlížejícího klienta. Výhodou je, že server sám kontaktuje přihlížejícího klienta, čímž se šetří přenos dat (podobně jako v předchozím případě). Oproti flashi se ale na server posílají data od přihlížejícího klienta, což je výhoda (kvůli zabezpečení a uložení dat) i nevýhoda (kvůli množství přenášených dat a zátěži serveru). Open source řešení comet serveru je několik, např. Node.js a APE. Nevýhodou je tedy nutnost mít na serveru navíc tyto specializované aplikace, jež simulují live streaming nad protokolem HTTP, případně i specifický http server na specifické platformě.

Ajaxová aplikace na běžném serveru

Na běžném serveru bude část pro hrajícího klienta probíhat obdobně jako v před- chozím případě, s tím rozdílem, že přihlížející klient bude periodicky zasílat dota- zy na server, zda se hrací plocha změnila (tedy zda hrající klient provedl nějakou akci). Z hlediska přenosu dat a zátěže serveru je tato možnost nejhorší, její vý- hodou je však snadné nasazení na libovolný běžný http server. Na rozdíl od chatových aplikací, kde je skutečně nutný real time dojem, na

19 tento framework takové nároky nejsou - pro účel hry je dotaz např. jednou za dvě sekundy postačující.

SPDY

SPDY je technologie firmy Google, která rozšiřuje možnosti protokolu HTTP. Přidává k němu možnosti paralelního přenosu dat na základě jednoho požadavku, kompletní komprimaci HTTP požadavků (na rozdíl od standardní komprimace HTTP, kde se nekomprimuje hlavička požadavku) a především možnost server push, tedy otevírání spojení serverem (nikoliv výlučně klientem, jako u HTTP 1). Protokol jako takový je velmi slibný, a především je zpětně kompatibilní, tedy pokud klient (např. Internet Explorer) nepodporuje SPDY, použije se standardní HTTP. Za pomocí server push by pak bylo možné vytvořit aplikaci podobně jako s využitím comet serveru s tou výhodou, že SPDY je možné jednoduše nainsta- lovat jako modul web serveru Apache. Nevýhodou je, že projekt je ve fázi vývoje a je vypuštěná pouze beta verze, která se nedoporučuje pro produkční nasazení. SPDY má podporu pouze v prohlížečích Chrome a Firefox. Další nevýhodou je fakt, že budoucnost tohoto projektu je nejistá díky možnosti nasazení HTTP 2.0, které přebírá zmíněné vlastnosti od SPDY v prakticky nezměněné podobě, a dá se očekávat větší rozšíření než SPDY díky standardizačním společnostem, jež za ním stojí.

HTTP 2.0

HTTP 2.0 by bylo velmi dobrým řešením, nicméně jedná se zatím pouze o pra- covní návrh, který dosud není implementovaný (ačkoliv nejnovější zprávy říkají, že HTTP 2.0 bude kompatibilní s SPDY).

Možné kombinace

Možnou kombinací je použití flashe pro aktualizaci dat na přihlížejícím kliento- vi, a zasílání asynchronních http požadavků od hrajícího klienta. Tedy vlastně simulovat comet server pomocí flashe - hrající klient provede určitou akci (pohyb

20 oddílu), data o této akci se odešlou na server, zde se vyhodnotí, klientovi se vrátí odpověď, a pokud ta je OK, hrající klient pak flashem přes navázané P2P spoje- ní zašle tyto stejné informace o provedené akci přihlížejícímu klientovi, jež tyto změny pouze zobrazí. Pro zajištění bezpečnosti se pak všechny data o oddílech na začátku každého kola znovu vyžádají ze serveru. Výhoda tohoto řešení je, že ačkoliv nepotřebuje žádný comet server, přihlížející klient nezasypává server zbytečnými dotazy. Sice se zde používá flash, např. řešení Cirrus, nicméně celá aplikace na něm není závislá - tato metoda může fungovat bez flashe jako čistě ajaxová aplikace na běžném serveru (což má rovněž výhodu, pokud by některý z klientů nepodporoval Flash 10, hra může automaticky přejít do dotazovacího režimu), a v aplikaci se tak ponechávají otevřená nouzová zadní vrátka pro případ změny licencování technologie Adobe Cirrus (hra zůstává stále funkční, a případně se podobný objekt dá simulovat pomocí comet serveru bez nutnosti větších změn v aplikaci). Flashový objekt v tomto případě může být ve stránce pouze jako jednopixelové video, jež zůstane uživateli skryto. Možnost úspory samotného serverového času je i v omezení požadavků od hrajícího klienta - ačkoli odesílání informací na server až po ukončení hry je poměrně nebezpečné (viz první řešení), není nutné odesílat každou jednotlivou akci. Je možné udělat jakousi frontu, tedy postup všech akcí, které hráč za kolo udělá, a ty pak odeslat na server najednou. Výhodou je menší množství požadavků na server a zároveň snížení doby provádění těchto akcí na serveru - pro všechny akce stačí např. navázat jedno spojení na databázi, v případě, že hráč třikrát posune stejný oddíl, na serveru se změna uloží pouze jednou atp. Bohužel, tento postup lze realizovat pouze s pohybem - útok vyžaduje provedení skriptu na serveru, navíc přidává parametr náhody (útok jednoho oddílu na jiný nebude mít vždy stejné výsledky), jež by se pak ve frontě ukládané na straně klienta dal snadno falzifikovat ve prospěch útočícího hráče. Zvláštní schopnosti hrdinů pak mohou být naprosto libovolné, naprogramované v PhP, takže zde se opět musí okamžitě kontaktovat server. Implementovat tuto optimalizaci bude nicméně efektivní i za těchto podmínek, jelikož předpokládaný poměr akcí pohybu oddílu vs. ostatních akcí je výrazně vyšší ve prospěch pohybu.

21 Tabulka 1.4: Porovnání možných technologií Technologie Bezpečnost Počet Práce ser- Nasaditel- HTTP veru nost požadavků Flash - odeslání + zanedba- + zanedba- - závislost na informací po telné telná Adobe, klient konci bitvy s flashem Ajax a comet + server kon- data od hra- ověřuje kaž- nutnost co- server troluje každý jícího dý tah met serveru tah Ajax a http + server kon- - data od hra- ověřuje kaž- + běžný web- server troluje každý jícího, přihlí- dý tah server tah žející se dota- zuje SPDY + server kon- data od hra- ověřuje kaž- - webserver a troluje každý jícího dý tah browser s SP- tah DY HTTP2.0 + server kon- data od hra- ověřuje kaž- - pouze ná- troluje každý jícího dý tah vrh, neexistu- tah je řádná im- plementace Kombinace + server kon- data od hra- ověřuje kaž- + obyčejný troluje každý jícího, přihlí- dý tah webserver tah žející nic ne- s možností dělá rozšíření

Zvolené řešení

Výhody a nevýhody jednotlivých řešení jsou shrnuty v tabulce 1.4. Kombinace zmíněná jako poslední se jeví jako nejlepší možnost. Komunikace musí být navržena obecně, tak aby se daly její moduly jednoduše měnit, resp. aby mezi nimi server mohl automaticky přepínat. Tedy pokud bude problém s komunikací přes flash, využije se komunikace pomocí asynchronních požadavků pomocí běžného http protokolu. Zobrazení komunikace při tahu hrajícího, resp. přihlížejícího hráče znázorňují diagramy 1.1, resp. 1.2. Do budoucna pak je možné přidat modul například pro comet server, HTTP 2.0, či libovolnou jinou technologii.

22 Obrázek 1.1: Komunikace se serverem z pohledu klientské části hrajícího hráče

Obrázek 1.2: Komunikace se serverem z pohledu klientské části přihlížejícího hráče

1.4.3 Načítání přídavných modulů

Umožnit snadnou upravitelnost je jedním z cílů frameworku, proto je potřeba, aby framework zahrnoval mechanismus pro snadné načítání přidaných souborů. Každý objekt je obecně reprezentován záznamem v databázi a nějakou třídou. Pro úpravu objektu je pak možné použít úpravu obojího, přičemž musí být k dispozici pohodlné rozhraní pro úpravy dat tak, aby je zvládl i neprogramátor. Načítání programovatelných funkcí musí probíhat automaticky, a musí pře- pisovat standardní funkčnost. Toto se týká typů jednotek, zvláštních výcviků jednotek a hrdinových schopností. Požadavkem je, aby z místa volání daného kódu nebylo třeba rozlišovat, zda připrogramovaný kód existuje nebo nikoliv. Cílem tedy je, aby např. u hrdiny, jehož schopnosti jsou známy, bylo možno pouze vytvořit instanci třídy schopnosti (”ability”), a následně zavolat metodu pro její spuštění (příp. pro zjištění podrobnějších informací, ...). Framework se pak musí sám postarat o to, aby poskytl správnou třídu pro danou schopnost - uživatelský kód, pokud tento existuje, nebo předpřipravený výchozí kód pro běžné zpracování schopnosti. Pro tento typ úlohy se nejlépe hodí návrhový vzor Abstract Factory [36] - tedy

23 existuje abstraktní továrna poskytující produkty, které mají společnou množinu vlastností. Klient se již nemusí starat, který konkrétní produkt dodává relevantní výsledky. Implementace v PhP vypadá takto: základní třída Ability obsahuje statickou metodu getAbility, která přijímá ID schopnosti jako parametr. Tato třída pak zjistí, zda existuje soubor se třídou pro danou konkrétní schopnost (z databáze), pokud ano, vrátí referenci na instanci této třídy, pokud ne, vrátí referenci na obecnou třídu AbilityDB. Třída AbilityDB i každá doprogramovaná abilita musí implementovat interface AbilityInterface jak je naznačeno na obrázku 1.3.

Obrázek 1.3: Schéma tříd pro načtení vlastního skriptu (hrdinovy schopnosti)

Pro typ a zvláštní výcvik jednotky se načítání odpovídajících tříd provádí obdobně.

1.4.4 Zobrazení bitevní plochy

Zobrazovací vrstva celé aplikace musí být nezávislá na zbytku aplikace (toho se dosáhne především využitím návrhového vzoru MVC). Samotná herní plocha (pozadí) bude jeden obrázek. Plocha se bude zobrazovat ve skloněné perspektivě 27,5 ◦ (tento úhel se jeví jako nejvhodnější pro zobrazení 2D plochy, využívá ho většina klasických 2D her). Obrázky budou kompletně předpřipravené, mapa se bude skládat z obrázku a tabulky obsahující údaje o jednotlivých polích (terén, výška). Framework obsahuje editor map s možností upravovat výšku a terén každého políčka.

24 Zobrazení odlišné výšky bude znázorněno odlišným úhlem, jako je to v ukázce na obrázku 1.4 . Zobrazení mapy jako takové v HTML je problematické kvůli zvolenému úhlu 27,5 ◦. Možná jsou tři řešení:

• Mapu otočit o 27,5 ◦ přímo v obrázku a pro mapování políček využít obráz- kovou mapu. Obrázkové mapy mají výhodu podpory (tag map je v HTML již od jeho původních verzí), nedá se s nimi však jednoduše pracovat např. pomocí CSS, zadávání souřadnic je poněkud těžkopádné (pro každou mapu s rozdílnými výškami by musela být vytvořena separátní síť), obrázek navíc musí obsahovat i naznačené čáry mezi políčky.

• Využití skupiny CSS3 vlastností 2D transform. CSS3 umožňuje jednoduše rotovat či zkosit libovolný HTML objekt. Problémem jsou zde vlastnosti izometrie - v jedné úrovni výšky se dá jednoduše zkosit a orotovat tabulka, s více úrovní výšek si toto řešení však již jednoduchým způsobem nepora- dí. CSS3 má podporu pouze v novějších prohlížečích (především Internet Explorer až od verze 9).

• Využití canvasu, neboli kreslícího plátna. Toto se jeví jako velmi efektivní metoda - obrázek bude již v úhlu natočený, do canvasu se pak javascriptem vykreslí patřičné políčka, s nimiž se pak dá dále jednoduše pracovat. Canvas má stejné omezení co se podpory v prohlížečích týče, jako transformace v CSS3.

V tomto případě vychází jako nejlepší z možností využití canvasu - omezení na verzi IE minimálně 9 a lepší je sice poměrně razantní, nicméně výhody can- vasu převažují - canvas je jednoduchý na použití, efektivní a snadno se v něm vykreslují čáry vymezující políčka i s ohledem na různé výšky terénu, s těmito políčky se pak navíc dá libovolným způsobem interagovat (využívat pro pathfin- ding, zvýrazňovat, atp.). V případě nutnosti zobrazování i v nižších verzích IE lze v budoucnu dodělat zobrazení pomocí SVG, k čemuž existují knihovny kreslící do SVG obdobně jako do canvasu.

25 Obrázek 1.4: Vzor bitevní plochy

1.4.5 Viditelnost vnitřních proměnných v objektovém ná- vrhu

V souvislosti s PhP se často diskutuje o jednom z hlavních principů objektově orientovaného programování - zapouzdření vnitřních proměnných třídy. Striktní objektový přístup říká, že proměnná by neměla být viditelná zvenčí, ale přístupná pouze přes metody getX či setX (tzv. gettery a settery). V PhP se tento princip však často nedodržuje, z více důvodů. Jednak z důvodu historického, PhP mě- lo podporu objektů sice již od verze 3, nicméně rozsáhlejší podpory a rozšíření v praxi nastalo až od verze 5. Viditelnost proměnných pak PhP zavedlo až ve verzi 5. Tento projekt se bude držet paradigmatu objektově orientovaného progra- mování i v PhP. Rozdíl ve výkonu volání funkce vs. přímý přístup k veřejné proměnné je od verze 5.3 zanedbatelný (na rozdíl od starších verzí). Na druhou stranu, projekt se nebude držet striktně objektových zásad za kaž- dou cenu - v některých specifických případech může být lepší místo jednoduchých getterů a setterů vytvářet pro manipulaci s daty funkce na míru [45]. Všechny vnitřní proměnné tříd jsou tedy neveřejné, a až na výjimky dostupné přes gettery a settery.

26 1.4.6 Hledání nejkratší cesty

Pro problém nalezení nejlevnější cesty mezi dvěma body v dopředu známém pro- středí existuje mnoho osvědčených algoritmů. Jejich porovnávání na teoretické i praktické hladině je velmi dobře prozkoumané téma. Tento projekt využívá algoritmus A* s maximovou metrikou (heuristikou), jakožto nejlepší algoritmus v porovnání dle efektivity a náročnosti na implementaci ([40], [41]). Algoritmus pro hledání nejkratší cesty je implementován v JavaScriptu na straně klienta.

27 2. Struktura aplikace

Na strukturu aplikace se dá pohlížet z více různých úhlů - možným pohledem je pohled funkční, tedy rozdělení do logických částí dle funkce dané části aplikace, technický - dle různých používaných technologií v té či oné části aplikace či dle objektového návrhu. V této části textu jsou rozebrány všechny tyto pohledy.

2.1 Entity frameworku

Nejprve je třeba definovat základní entity frameworku:

• Bitva je instance jedné konkrétní hry probíhající mezi dvěma hráči. Bitva je sled tahů obou hráčů, jež vyústí ve vítězství či prohru jednoho z nich (příp. kontumaci).

• Armáda slouží jako obálka držící pohromadě jednotky a hrdiny. Armáda je entitou, která vstupuje do bitvy. Každý uživatel může mít libovolné množ- ství armád. Síla armády se dá vyjádřit její cenou (jež je cenou všech oddílů a hrdinů do ní náležejících).

• Oddíl je běžná herní jednotka. V každé armádě jich může být neomezené množství, pro vstup do bitvy zde však musí být minimálně jeden. Oddíl se pohybuje po herní ploše a může být zničen.

• Hrdina je speciální jednotka jež se sama o sobě nevyskytuje v bitvě, vy- skytuje se pouze v záloze (tedy na bitevní ploše není vůbec vidět), nebo se přidruží k libovolnému (vlastnímu) oddílu. Může používat předměty a zvláštní schopnosti (”ability”). Hrdinové získávají nové schopnosti na zá- kladě získaných zkušeností (model známý z řady RPG titulů).

• Hráč, resp. uživatel je poslední zvláštní entitou, představuje reprezentaci uživatele - tedy jakousi nad-entitu pro armády, s pomocí nichž se hráč účastní bitev.

Framework definuje základní vlastnosti všech těchto entit a vztahy mezi nimi, jakožto součást implicitního herního mechanismu. Tyto entity jsou navíc od zákla-

28 du rozšiřitelné pomocí vlastních (naprogramovaných) předmětů, výcviků oddílů či hrdinových schopností.

2.1.1 Struktura dle funkčních částí

Aplikace je navržena dle vzoru Model-View-Presenter. Jedná se o variaci Model- View-Controller, kde View samo zpracovává uživatelský vstup - resp. typicky deleguje uživatelské akce Presenteru; slova Controller a Presenter se však často zaměňují, ať už z důvodu marketingových účelů či neznalosti. Využitá varianta návrhového vzoru MVC je pak tzv. ”Passive View”, kde není vazba mezi View a Model [43] (jak je znázorněno na obrázku 2.1).

Obrázek 2.1: Model-View-Presenter

29 Vzhledem k interaktivnosti aplikace nelze jednoznačně rozlišit, která část mo- delu spadá do které části aplikace z pohledu využití jednotlivých technologií:

• Model je celý napsán v PhP. Obsahuje reprezentaci všech objektů hry (jed- notku, hrdinu, ...), stejně jako všechny správní objekty (např. reprezentaci hráče, ale i objekt pro práci s databází).

• Presenter je částečně v PhP, částečně v JavaScriptu a částečně v Acti- onScriptu (tzn. jeho část je i na straně klienta). Funguje jako mezivrstva mezi Modelem a View - bere tedy data z modelu, vybere způsob zobra- zení a předá data View. Rovněž obsahuje všechny funkce pro manipulaci se zobrazenými daty, stejně jako zajišťuje předávání dat od View zpět k modelu.

• View je čistě v Html a Css (s výjimkou jednopixelového Flashe zajišťují- cího spouštění ActionScriptového kódu). Slouží pouze k zobrazování dat a delegování uživatelských akcí presenteru.

Základní návrh aplikace nad frameworkem Yii navíc přidává tzv. Applicati- on část, která slouží jako obálka kontextu zpracovávaného požadavku [44] (viz obrázek 2.2).

Obrázek 2.2: Standartní Model-View-Controller ve frameworku Yii

Yii používá model MVC, zde nicméně controller může posloužit i jako presen- ter. Passive view se z implicitního modelu Yii zajistí jednoduše nepoužíváním vazby mezi modelem a view.

30 2.1.2 Struktura dle použitých technologií

Strukturování aplikace dle použitých technologií je velmi jednoduché - obrázek 2.3 zobrazuje princip rozdělení částí aplikace dle technologie.

Obrázek 2.3: Způsob rozložení technologií směrem od databáze k uživateli

Databáze obsahuje model hry a správní informace o hráčích a odpovídající data. V PhP je opět model hry, do nějž se data načítají z databáze nebo na vstupu od uživatele a obslužná logika aplikace. Html a CSS zajišťují grafický výstup, JavaScript a Flash je zodpovědný za asynchronní komunikaci se serverem, resp. protihráčem. JavaScript slouží rovněž pro zlepšení uživatelského rozhraní a jsou v něm i jednoduché skripty probíhající na klientské straně, jež slouží především pro šetření výpočetní kapacity serveru (např. pathfinding).

2.1.3 Struktura dle objektového návrhu

Objekty frameworku se dají rozlišit na několik částí, dle jejich funkce:

• Datové reprezentují data načtená z databáze.

• Správní obsahuje všechny objekty starající se o spouštění herních mecha- nismů - např. autentizaci uživatele.

• Herní jsou objekty modelující herní svět, jako například armáda, jednotka či hrdina.

• Administrátorské jsou pomocné objekty sloužící k přípravě hry jako ta- kové.

Entity z kategorie herních objektů jsou jediné entity skutečně modelující her- ní svět, a všechny přímo podléhají pravidlům hry. Zbývající kategorie poskytu- jí pouze pomocné funkce pro chod frameworku. Podrobněji je objektový model zpracován v části 3.2 tohoto textu.

31 3. Implementace

Tato kapitola popisuje základní body implementace aplikace. Rozebírá databá- zový a objektový návrh aplikace i s popisem jednotlivých entit. Dále vysvětluje hlavní části programu sloužící k zobrazování dat uživateli, a představuje imple- mentaci komunikace v reálném čase.

3.1 Databázový model

Tabulky databáze se dají dle významu rozdělit na dvě části – dynamická část pro data uživatelská, měnící se během hry, a statická část pro data herní, jež se mění pouze při konfiguraci hry (typicky při počáteční instalaci frameworku). Tabulky s herními daty začínají prefixem data . Kromě tabulek jsou součástí databáze obslužné procedury pro uživatelské ta- bulky a některé funkce a procedury poskytující funkčnost celé aplikaci. Struktura databáze je na diagramu v obrázku 3.1 a ve formátu PDF na při- loženém DVD v souboru ”Struktura Databáze.pdf”. Následuje stručný popis všech uživatelských tabulek v abecedním pořadí:

• active abilities – každá právě aktivovaná hrdinova schopnost zde má jeden záznam; schopnosti, které fungují permanentně zde tento záznam mají na- pořád, jinak je zde údaj o trvání (sloupec lasts); rovněž udržuje informaci o cíli dané schopnosti (v atributu object, kam se ukládá typ objektu (unit ne- bo army), resp. objectId, kam se ukládá jeho id), a o cílové armádě (sloupec onIdArmy)

• armies - seznam všech armád. Mezi hráči a armádami platí vztah 1:N (platí, že každá armáda je vlastněna právě jedním hráčem, avšak jeden hráč může mít neomezené množství armád); v price je uložena celková cena armády (pro ušetření opakování výpočtu - teoreticky se tato hodnota dá vždy znova spočítat sečtením ceny všech oddílů a hrdinů, nicméně tento výpočet je poměrně náročný, navíc se hodnota mění pouze při editaci armády,tj. poměr počtu změn této hodnoty vůči počtu jejího čtení je velmi výrazně převážen

32 Obrázek 3.1: Struktura databáze

ve prospěch čtení); atribut initiative určuje iniciativu nebo-li pořadí armády v boji (platí pro ní to samé co pro cenu)

• armies races - tabulka relace M:N mezi rasami a armádami, určuje které rasy má která armáda k dispozici (každá armáda má však vždy alespoň jednu rasu)

• battles - obsahuje přehled všech hraných bitev; idUserCreated je id uži- vatele, jenž tuto hru založil (a tedy má i právo ji smazat), atribut turn informuje o aktuálním kole, idArmyA a idArmyB určuje id soupeřících armád, onMove je znak ’a’ či ’b’, jež určuje, která z armád je právě na tahu

• battles land - obsahuje informace o jednotlivých políčkách hracího plánu

33 každé bitvy

• battles msg - tabulka s informačními zprávami o průběhu bitvy, type zde označuje typ akce

• battles units - obsahuje data ve formátu JSON o pozicích všech oddílů v každém kole bitvy; šetří se tak přenášená data a navíc je po skončení bitvy možno zobrazit její průběh

• battles history - údaje o všech odehraných bitvách, čase jejich hraní, počtu odehraných kol s přehledem, jak bitva probíhala - battleLand obsahuje seri- alizované pole terénu (dvojrozměrné pole obsahující typ a výšku terénu pro každé políčko hracího plánu) a unitsPositions obsahuje pole s informacemi o postavení jednotek v každém kole bitvy (ve formátu JSON)

• battles history users - údaje o hráčích, kteří se účastnili již odehraných bitev; pokud je příznak won nastaven na true, značí vítězství tohoto hráče, pokud je příznak unfinished nastaven na true, značí nedohrání hry, na jehož vině je tento uživatel

• heroes – seznam hrdinů; každý hrdina spadá právě do jedné armády a v jed- né armádě může být 0-N hrdinů; každý hrdina patří právě do jedné školy a musí být právě jedné rasy, může být přiřazen nejvýše k jednomu oddílu (nebo také k žádnému)

• heroes abilities – M:N tabulka určující, který hrdina má jaké schopnosti

• heroes slots – M:N tabulka určující, který hrdina má jaké předměty; navíc obsahuje atribut slotNum, který určuje pozici, na jaké hrdina předmět drží

• settings - tabulka sloužící k uložení globálních nastavení frameworku

• units - oddíly armád; každý oddíl musí být členem nějaké armády (nao- pak armáda má neomezené množství oddílů); atribut shield může nabývat hodnoty 0 (žádný), s (malý) a l (velký); movePoints je počet pohybových bodů, trainingTime určuje čas, který oddíl strávil výcvikem, eliminated ur- čuje, zda je oddíl stále schopný bojovat, ammo má hodnotu NULL, pokud

34 oddíl nedisponuje střelnou zbraní, defensesInTurn signalizuje, kolikrát byl na daný oddíl již veden útok v tomto kole

• units training - pomocná tabulka relace M:N mezi jednotkami a zvláštními výcviky

• users - obsahuje seznam všech hráčů

Následující seznam popisuje všechny herní datové tabulky:

• data abilities - všechny herní schopnosti; idGroup určuje skupinu ability v rámci školy, pokud je uvedeno classname, načítá se tato třída schopnosti místo standartní DataAbilityDb, lvl určuje minimální úroveň, na které mů- že hrdina tuto schopnost získat, scope je působnost schopnosti (unit nebo army), lasts určuje, jak dlouhé má schopnost trvání, price je cena seslání v bodech koncentrace, dmg poškození, které schopnost působí, bonusy ur- čují, jak schopnost ovlivňuje jednotlivé parametry oddílu(ů). Fireevent je pole enum, jež určuje, zda a kdy se má schopnost spustit - povolené hodnoty jsou ’a’ (po útoku), ’b’ (před útokem), ’d’ (po obraně), ’e’ (před obranou) a NULL, pokud se schopnost automaticky nemá spouštět vůbec.

• data armors - přehled zbrojí; grp zde určuje skupinu, dle skupin se pak určuje, jaké typy oddílů mohou používat jaké zbroje

• data formations - přehled formací oddílů

• data hero schools - přehled všech škol pro hrdiny

• data hero schools levels - ukazuje, jak se rozvíjí základní vlastnosti hrdiny při postupu na vyšší úrovně, a rovněž určuje, kolik zkušenostních bodů je třeba na kolikátou úroveň

• data items - přehled předmětů, které mohou používat hrdinové

• data items lvlschool - určuje, které předměty může hrdina konkrétní školy používat od které úrovně

• data items slots - definuje M:N vztah mezi předměty a pozicemi (sloty), na které se předmět dá umístit

35 • data map terrains - obsahuje informace o terénech všech map; ty se při založení nové bitvy pouze zkopírují z této tabulky do tabulky battles land

• data races - přehled ras a jejich výhod

• data shops - přehled obchodů, ve kterých si hrdinové mohou kupovat před- měty

• data special trainings - přehled všech zvláštních výcviků, jež mohou využí- vat jednotky

• data terrains - přehled typů terénů použitelných na bitevní ploše, difficulty vyjadřuje náročnost přechodu přes tento typ

• data training - tabulka základního tréninku oddílů, vyjadřuje, jaké má oddíl výhody po jaké době tréninku

• data unit types - přehled typů jednotek

• data unit types armor, data unit types weapon - určují, které typy oddílů mohou používat které skupiny zbrojí, resp. zbraní

• data weapons - přehled zbraní, small shield and large shield určují, zda je k této zbraní možné používat malý a velký typ štítu, weaprange určuje dostřel (pokud se nejedná o střelnou zbraň, hodnota zůstává 1, ammo má pak hodnotu NULL)

Doporučený postup pro úpravy databáze při vytváření vlastních herních prvků je toto schéma neměnit, ale tabulky pouze přidávat.

3.1.1 Procedury

Databáze obsahuje obslužné procedury pro ukončení tahu a pro vytváření uživa- tel.

Ukončení tahu

Následující tři procedury je potřeba zavolat při ukončení tahu:

36 • ARMY RESTORE MOVES obnoví pohybové body na maximum všem oddílům armády, jež právě ukončuje tah.

• BATTLE NEXT ARMY předá tah další armádě v pořadí. Pokud ukon- čuje tah armáda B, nastaví se onMove na armádu A a obráceně.

• BATTLE ABILITIES TIME odmazává z aktivních (z tabulky active - abilities) ty schopnosti, jejichž platnost již byla překročena, resp. snižuje každé kolo životnost těchto schopností o 1. Toto se však musí dít vždy pouze se schopnostmi, které působí na armádu, jež právě ukončuje tah (po- kud hrdina použije schopnost s trváním 4 kol, tato se smaže ve chvíli, kdy armáda tohoto hrdiny od jejího aktivování po čtvrté ukončí tah).

• BATTLE HEROES TRAVEL TIME zmenšuje zbývající čas strávený na cestě všem cestujícím hrdinům

ADD USER

Procedura slouží k přidání uživatele, a zahashování nějakého řetězce algoritmem Md5. Z důvodu zabezpečení se používá tzv. salt, tedy náhodný řetězec, který se přidává k samotnému heslu. Problémem je, že procedura ADD USER je ulo- žena v databázi, tedy pokud útočník získá hashovaná hesla (i se solí každého uživatele), pravděpodobně získá i zdrojové kódy této procedury. Proto je třeba hashovat již na úrovni aplikace, a proceduru ADD USER pak volat již s řetězcem zahashovaným, a v této proceduře ho pouze znovu přehashovat. Kompletní zabezpečení probíhá tak, že se na aplikační úrovni vygeneruje ná- hodný string (salt), tento se zahashuje ve tvaru “heslo-salt ”, a tento výsledek se teprve předá funkci ADD USER, která salt uloží, znovu přehashuje celé heslo i se solí a přidá uživatele. I kdyby se útočník zmocnil databáze, nezjistí původní uživatelské heslo.

3.2 Objektový model

Tato kapitola popisuje celý objektový model, obsahuje podrobné schéma všech používaných tříd, jejich vlastností a metod.

37 3.2.1 Třídy poskytované frameworkem Yii

Framework Yii je postavený na systému tzv. komponent - jeho základem je třída CComponent, od které je zděděno vše. Framework toto ve většině případů respek- tuje, s výjimkou vlastních přeprogramovaných tříd, které nemusí být potomkem ničeho, pouze musí implementovat příslušné rozhraní. Přímo v projektu je rozšířena třída CActiveRecord na FActiveRecord. Třída CActiveRecord ve frameworku Yii představuje základní třídu reprezentující re- lační data, tedy především data uložená v databázi. CActiveRecord sám o sobě poskytuje mnoho metod pro jednoduchou práci s daty v databázi ([52]), např. funkce pro vyhledávání, ukládání a mazání záznamu či validaci vstupů. FActi- veRecord pak předělává systém, jakým se pracuje s gettery a settery - původní systém mapuje databázové atributy na privátní proměnné pomocí magické meto- dy get(), v implementaci FActiveRecord se pak nejprve upřednostňují explicitní gettery. Všechny třídy z modelu frameworku jsou zděděny od třídy FActiveRecord, s výjimkou tříd využívajících načítání pomocí Abstract Factory - Unit, DataA- bility a DataSpecialTraining. V následujícím popisu těchto tříd už tato dědičnost nebude znovu explicitně zmiňována. Další důležitou třídou frameworku je pak CController ([53]), od něhož jsou zděděny všechny controllery. CController poskytuje např. snadné nastavení pří- stupových pravidel nebo ajaxové validace. Dále se pak využívá třída CBaseUserIdentity([54]), jež slouží k ověření uživa- telské identity (pomocí metody authenticate()). Pro budoucí možný překlad textů se využívá zabudovaný mechanismus, kdy se všechny texty píší pomocí metody tvaru Yii::(”kategorie”, ”překládaný text”). Kategorie odpovídá názvu souboru, ve kterém se pak nachází překlady.

3.2.2 User

Třída User representuje jednoho uživatele. Vlastnost privileges představuje práva uživatele, vyjádřena číselně (nejnižší práva mají hodnotu 1, což odpovídá běžnému uživateli). Třída User se stará pouze o zobrazování a načítání uživatelských dat, o při-

38 Obrázek 3.2: Objektový model - User, Battle, Army hlášení a odhlášení se stará třída (přesněji komponenta) CUserIdentity, jež je rozšířením třídy CBaseUserIdentity frameworku Yii [46].

3.2.3 Battle

Battle modeluje právě jednu bitvu. Vlastnost turn určuje, kolikáté kolo se právě hraje, vlastnosti idArmyA a idArmyB obsahují informace o id soupeřících armád. Start() zkontroluje, zda jsou obě armády připraveny k bitvě a předá tah prvnímu hráči, tzn. nastaví příznak started na true. Metoda end() provede řádné ukončení bitvy, především tedy její uložení do historie, smazání nyní již nepotřebných dat, přidělení nabytých zkušeností a pře- vedení armád do stavu, kdy nejsou v žádné bitvě (nastaví u nich hodnotu klíče pro peer to peer komunikaci na prázdnou hodnotu NULL, všem oddílům pak nastaví plný počet životů i munice, zruší jejich případný příznak eliminace a hr- dinům nastaví hodnotu koncentrace na počáteční hodnotu). Vyhodnocení vítěze proběhne buď dle přeživších oddílů armády (poslední armáda, která má přeži- vší oddíl či oddíly, je vítěz), či pokud metoda dostane nepovinný parametr ID ukončující armády, bere tuto armádu jako kontumačního vítěze. IsOver() slouží ke zjištění, zda již nastal konec bitvy (tedy zda zbyla pouze

39 jedna armáda s žijícím oddílem (či oddíly), případně zda zůstala pouze jedna armáda, která nekapitulovala). IsPaused() vrací true, pokud je bitva zapauzovaná. Zároveň kontroluje, zda již neuplynula doba pro odpauzování, a pokud ano, umožní její odpauzování, v závislosti na tom, zda funkci volá pauzující armáda. Pokud uplynul čas pro pauzování s určitým časovým limitem navíc (jako rezerva, např. 5 minut), umožní druhé (nepauzující) armádě ukončit hru pro neaktivitu druhé strany. SetUnitsPosition() přijímá jako parametr pozice oddílů ve formátu JSON, jež uloží do databáze s aktuálním kolem. IsFree() vrací true, pokud je možné do dané hry vstoupit a hrát (tzn. je ve fázi čekání na protihráče), join() pak přidá armádu do hry. Kick() armádu ze hry naopak odstraní, tuto metodu však může používat pouze zakladatel hry.

3.2.4 Army

Třída Army odpovídá jedné armádě - obsahuje informaci o bitvě (idBattle), jež je číslo, ale může mít i hodnotu null (pokud armáda není v žádné bitvě). Dále obsahuje jméno, cenu, hodnotu iniciativy, příznak, zda je armáda právě na tahu a ve vlastnosti defaultStand základní rozestavení oddílů na začátku každé bitvy, uložené ve formátu JSON. Metoda finishTurn() ukončuje tah armády, nejprve kontroluje frontu čin- ností, jíž přijímá jako nepovinný parametr, pomocí metody processQueue (viz kap. 3.4.1). Pokud jsou všechny tahy pohybu validní (což se zkontroluje meto- dou canMove() třídy Unit), uloží nové rozestavení oddílů do databáze pomocí metody setUnitsPosition() třídy Battle. Dále volá databázové procedury BATT- LE NEXT ARMY, BATTLE ABILITIES TIME, ARMY RESTORE MOVES a BATTLE HEROES TRAVEL TIME, čímž předává tah dalšímu hráči, zvyšuje kolo, odmazává aktivní schopnosti, obnovuje pohybové body všech jednotek na maximum a snižuje zbývající nedostupný čas cestujících hrdinů. GetBattleMessages() slouží k vyzvednutí všech zpráv o dané bitvě (jež vrací jako pole objektů typu BattleMsg), setBattleMessage() naopak přidá nový záznam do bitvy. Surrender() slouží k ukončení hry (tzn. vyhrává protihráč). Surrender volá

40 metodu end() dané bitvy a tedy probíhá stejná situace, jako kdyby armáda přišla o všechny oddíly. Pause() slouží k zapauzování hry - hra se automaticky zapauzuje na určitý (krátký) čas, čímž se dá protihráči možnost vyjádřit se k této pauze. Jestliže druhá armáda pauzu odsouhlasí, hra se pauzuje až do doby, kterou tato metoda přijímá jako parametr. Jestliže ji neodsouhlasí, hra pokračuje, a tato armáda se po určitý čas nemůže pauzy znovu dožadovat. Výsledek akce se zapisuje do systému bitevních zpráv. Celý proces pauzování hry tedy probíhá tak, že jedna armáda zavolá meto- du pause() s požadovaným časem, čímž se nastaví pausedTill na požadovaný čas pauzy, pausedProp na aktuální čas zaslání žádosti o pauzu, a propBy na id ar- mády, jež žádost zaslala. Pokud je pauza druhou stranou odsouhlasena, propBy i pausedProp se vynuluje, v opačném případě se vynuluje pausedTill, avšak úda- je o žádosti zůstanou. Pomocí těchto údajů se pak zabrání opakovanému zasílání žádostí o pauzu od jedné armády v krátkém časovém intervalu. Druhá armáda však v tomto intervalu o pauzu požádat může, v tom případě se údaje jednoduše přepíší. CanExit() signalizuje, zda může hráč ukončit hru jinak než kapitulací - tato možnost nastává pouze v případě neaktivity protihráče. Za neaktivitu se považují tři kola bez jediné akce, příp. nedostavení se k zapauzované hře po uplynutí doby na pauzu. ExitGame() pak pouze ukončuje hru, tedy volá metodu end() s parametrem ID armády na instanci dané bitvy. Další procedurou je calculatePrice(), jež vrací cenu armády. Cena armády je rovna součtu cen všech oddílů, hrdinů a poplatku za cenu ras (tyto ceny jsou stanoveny konstantně v konfiguraci). Procedura calculateInitiative() pak vrací hodnotu iniciativy armády, jež je rovna váženému průměru pohybových bodů všech oddílů.

3.2.5 Unit

Unit reprezentuje jeden oddíl armády. Třída Unit slouží pouze jako obálka pro načtení buď implicitní třídy (UnitDB), nebo libovolné vlastní třídy definované atributem className u typu oddílu. Je-

41 Obrázek 3.3: Objektový model - Unit diná metoda getUnit() této třídy vrací patřičnou instanci jednotky. Pro načtení správně třídy je využíván návrhový vzor Abstract Factory, stejně jako u hrdi- nových schopností a zvláštních výcviků. Jak třída UnitDB, tak libovolná vlastní třída musí implementovat interface IUnit. Třída UnitDB, příp. vlastní třída, reprezentuje jednotku armády. Následující popis implementace metod se vztahuje na implicitní třídu UnitDB, vlastní třídy pak mohou být implementovány libovolným způsobem. Attack() provádí útok na jinou jednotku. Metoda přijímá jako parametr ID oddílu, na který se má útok provést. Attack musí kontrolovat, zda má jednotka

42 dostatek pohybových bodů na útok, dostatek munice a zda jednotka, na kterou útok probíhá, je v útočném dosahu. Následně se spočte počet ubraných životů dle následujícího vzorečku:

Ubrané životy = ÚS útočníka − OS obránce + rnd(1-6)

+ počet obran v daném kole + výškový bonus

Pokud se počet ubraných životů rovná nule (příp. je záporný), nic se neděje, jinak se nastaví nový počet životů oddílu. V obou případech se oddílu připočte jednička k počtu obran v daném kole. Pokud je navíc výsledný počet životů menší nebo rovný nule, nastaví se oddílu příznak eliminated na true. Výsledek útočné akce se zapisuje do systému zpráv bitvy a útočícímu oddílu se ubere příslušný počet pohybových bodů. Attack rovněž musí volat schopnosti na obou oddílech, a zavolat metody run() na těch, jež mají typ události odpovídající momentu volání (před útokem, obra- nou, po útoku, obraně). CanMove() slouží k zjištění, zda lze přesunout oddíl na zvolenou pozici. Ja- ko parametr přijímá zvolenou cestu jako seznam souřadnic, přes které se prochá- zí, ve formátu JSON, a požadovanou cenu pohybu (vypočtenou JavaScriptem). Tuto cestu pak pouze zkontroluje podle hracího pole v databázi, a ověří, zda požadovaná cena pohybu se shoduje se skutečnou cenou, a že oddíl má dostatek pohybových bodů na to, aby tuto cestu vykonal. Pokud ano, vrátí true, jinak vrací false. Tato metoda nijak nemění databázi, pouze kontroluje validitu akce pohybu, samotnou změnu dat v databázi provádí metoda finishTurn třídy Army. HasHero() vrací true, pokud je u oddílu právě přítomen nějaký hrdina, ge- tHero() pak vrací instanci tohoto hrdiny (NULL, pokud zde žádný není). GetAttack() vrací údernou sílu oddílu, spočtenou dle následujícího vzorce:

ÚS = Bonus typu oddílu + Bonus zbraně + Bonus rasy +

+ Bonus základního výcviku + Bonus zvláštního výcviku +

+ Bonus formace + Bonus hrdiny

43 GetDefense() vrací obrannou sílu:

OS = Bonus typu oddílu + Bonus zbraně + Bonus zbroje +

+ Bonus štítu + Bonus rasy + Bonus základního výcviku +

+ Bonus zvláštního výcviku + Bonus formace + Bonus hrdiny −

− Postih za počet útoků

Pro vrácení pohybových bodů slouží metody getMovePoints() a getMo- vePointsMax(). Hodnota pohybových bodů je však předpočítána a uložena v databázi. SetMove() nastaví novou hodnotu zbývajících pohybových bodů a rovnou ji uloží do databáze. UpdateUnit uloží změněnou jednotku dle předaných parametrů, pro smazání oddílu je zde deleteUnit. Při vytvoření či editaci oddílu se musí přepočítat iniciativa a cena celé armády (metoda calculateInitiative() třídy ArmyEditor). CalculatePrice vrací cenu oddílu, jenž se spočte dle následujícího vzorečku:

Cena oddílu = Cena typu oddílu + (Cena zbraně + Cena zbroje +

+ Cena štítu) ∗ c + Cena základního výcviku +

+ Cena zvláštního výcviku

c je konfigurovatelná konstanta. CalculateMovePoints() vrací počet pohybových bodů následovně:

Pohyb = c + Bonus typu oddílu + Bonus zbraně + Bonus zbroje +

− Postih štítu + Bonus rasy + Bonus základního výcviku +

+ Bonus zvláštního výcviku + Bonus formace + Bonus hrdiny

44 CalculateMoral() počítá morálku dle vzorce:

Morálka = Bonus základního výcviku + Bonus zvláštního výcviku +

+ Bonus hrdiny

Poslední metoda je pak calculateLifes(), jež pro výpočet používá následující vzorec:

Životy = 5 + Bonus zvláštního výcviku

3.2.6 Hero

Třída reprezentuje jednoho hrdinu armády.

Obrázek 3.4: Objektový model - Hero

Třída reprezentující hrdinu musí implementovat interface IHero. Třída hrdi- ny je vždy pouze jedna (ačkoli může být nahrazena), jelikož vlastní úpravy hrdiny je možné provádět pomocí úprav tříd schopností a předmětů. Obsahuje metody moveToUnit(), jež jako parametr přijímá id jednotky, a slouží k přesunu hrdiny ke konkrétnímu oddílu. Musí nejprve ověřit, zda je oddíl ve stejné armádě jako hrdina. Metoda moveToBackup() naproti tomu vrací hrdinu zpět mezi zálohy. Obě metody pouze mění vlastnost idUnit daného hrdiny (na příslušné id oddílu, či na NULL), musí však navíc kontrolovat, že oddíl má

45 dostatek pohybových bodů na přesun hrdiny, a následně mu počet pohybových bodů snížit. UseAbility() použije schopnost, jejíž id je předáno jako první parametr. Musí zkontrolovat, že požadovaná schopnost je dostupná, následně inicializuje odpovídající třídu dané schopnosti, zavolá na ní metodu run() a odečte příslušný počet bodů koncentrace. Jako druhý nepovinný parametr zde slouží id oddílu, na který má být schopnost použita. Metoda Run() spouští kód schopnosti samotné, pokud nějaký existuje. Jako parametr je předáno pole parametrů, jež závisejí na typu, odkud je metoda vo- lána. Pokud metoda vrátí hodnotu false, pak je přerušeno vykonávání aktuální rodičovské akce (např. pokud je metoda volána před útokem a vrátí false, pak se již tento útok neprovede). Metoda hasAbility() slouží k ověření, zda hrdina disponuje danou schopností (jako parametr se zde předává její id). Standardní sadu vlastností navíc doplňuje vlastnost level - tato vlastnost se neukládá do databáze a dopočítává se až přímo v programu na základě hodnoty experience. Tuto vlastnost tedy stačí inicializovat až ve chvíli, kdy ji někdo žádá - tedy v metodě getLevel(). CalculatePrice() spočte celkovou cenu hrdiny, podle následujícího vzorce:

Cena hrdiny = Paušál + Úroveň ∗ Cena úrovně + Cena předmětů

Paušál a cena úrovně se nastavují v konfiguraci.

3.2.7 Weapon, Armor, Formation, Race, UnitType, Scho- ol

Skupina tříd reprezentujících herní objekty zbraně, zbroje, formace, rasy, typu jednotky a školy pro hrdiny. Tyto třídy slouží jako reprezentace daných objektů hry a jsou si velmi podob- né. Ke každé třídě náleží jeden interface, všechny třídy musí být potomci třídy FActiveRecord.

46 Obrázek 3.5: Objektový model - Weapon, Armor, Formation, Race, UnitType, School

3.2.8 Schopnosti hrdiny

Schopnost je zvláštní akce (např. kouzlo), kterou mohou používat hrdinové. Schopnost může být buď vlastní naprogramovaná, nebo automaticky načítaná z databáze. Toto definuje parametr className - pokud je prázdný, použije se třída DataAbilityDB, jinak se načte specifikovaná třída. Pro načtení patřičné třídy se používá mechanismus Abstract Factory [36] - tedy pro načtení schopnosti se vytvoří instance třídy Ability, jež má statickou metodu getAbility(), jež jako parametr přijímá ID požadované schopnosti. Pro tuto schopnost pak zjistí odpovídající třídu, a vrátí instanci této konkrétní třídy (tedy buď AbilityDB, nebo jinou specifikovanou v className). Třída každé schopnosti musí implementovat interface IDataAbility. Nejdůle- žitější metodou je metoda execute(), jež příjímá nepovinný parametr idUnit, jež určuje id jednotky, na níž se má schopnost použít. Stejným způsobem jsou rovněž řešeny zvláštní výcviky oddílů.

47 Obrázek 3.6: Objektový model - Schopnosti hrdiny

3.2.9 Ostatní třídy

K modelu náleží několik tříd, jež slouží pouze jako reprezentant databázových dat. Do této kategorie spadají třídy BattleHistory (uchovávající informace o ode- hraných bitvách), BattleHistoryUser (informace o hráčích, jež se těchto bitev účastnili, a jejich výsledcích), BattleLand (informace o terénu a výšce políček bitevního pole) a BattleMsg (jeden záznam systému bitevních zpráv). Dále zde jsou třídy Controllerů, především zajišťující operace s již zmíně- nými herními objekty - ArmyController, BattleController, HeroController, Unit- Controller, UserController a navíc SiteController zajišťující přihlašování. Každý controller obsahuje tzv. akce, jejichž názvy odpovídají URL stránky. V akci se zpravidla inicializují potřebné objekty, a následně se volá metoda render(), jež zobrazí patřičnou prezentaci dané akce. Projekt rovněž využívá několik pluginů frameworku Yii, jež přidávají své třídy - jedná se o rozšíření chování ActiveRecord, CAdvancedArBehaviour, jež zajišťuje korektní ukládání objektů, jež mají mezi sebou vztah M:N. Dále se pak jedná o EConfig, jež poskytuje možnost ukládání konfiguračních direktiv do databáze a jejich cachování, KEmail, jenž poskytuje rozšířenou funkčnost pro zasílání e-mailů a JSTrans, jenž umožňuje používat vícejazyčné texty i v JavaScriptu (bez nutnosti

48 implementace vlastního načítání textů). JSTrans používá téměř shodnou syntaxi pro překládané texty, jako framework Yii, tedy funkci tvaru Yii.t(”kategorie”, ”překládaný text”).

3.3 Zobrazovací vrstva aplikace

Tato sekce popisuje, jak je implementována zobrazovací vrstva aplikace, přede- vším uživatelské rozhraní bitevního pole a bitevní pole samotné. Vykreslování uživatelského rozhraní probíhá prostřednictvím standardního postupu frameworku Yii, je zde tedy systém šablon pro jednotlivé stránky. Exis- tuje zde tzv. layout šablona, jež se nachází v adresáři /protected/view/layouts, jež obsahuje kostru stránky. Do této kostry se pak zobrazuje šablona podstránky [55].

3.3.1 Uživatelské rozhraní bitvy

Uživatelské rozhraní je podrobněji popsáno v kapitole 5.4 a vyobrazeno na ob- rázku 5.4. Rozhraní je implementováno na úrovni View a Presenteru modelu MVP, a skládá se především z Html šablony (jíž presenter plní daty) a ze skriptů, zajišťujících komunikaci se serverem, jež jsou napsány v JavaScriptu, a komu- nikaci s protihráčem, jež jsou napsány v ActionScriptu. Dále zde jsou obslužné procedury zajišťující funkčnost rozhraní. Html šablona je k dispozici v adresáři /protected/views/battle/ground.. Dále se využívá několik tzv. widgetů, tedy znovupoužitelných částí kódu, jež jsou do stránky vkládány pomocí frameworku Yii. Tyto jsou k dispozici v adresá- ří /protected/widgets, jež rovněž obsahuje adresář views, v němž jsou uloženy odpovídající šablony. Widgety jsou využívány pro výpis kategorií oddílů, jednot- livých oddílů pro kategorii a hrdinových schopností. Základ JavaScriptového kódu pro obsluhu bitevního rozhraní se pak nachází v souboru /js/battleground.js. Zde je definováno několik globálních proměnných stavu, a definovány tři objekty - presentBattle, jež se stará o vykreslování bi- tevního pole jako takového, battleHandler, jež se stará o komunikaci se serverem

49 i protihráčem, a navíc poskytuje funkčnost pro pohyb, útok a používání schop- ností, a interfaceHandler, jež poskytuje funkce pro interaktivní ovládání rozhraní. Pro bitvu je dále potřeba soubor /js/battlegroundHelper.js, jenž obsahuje adresy obrázků oddílů a funkci pro přepočítávání souřadnic na pixely (toto je v odděle- ném souboru, jelikož se funkce využívá i v základním rozhraní). O vykreslování samotného bitevního pole s jednotkami se stará JavaScriptová knihovna KineticJS [57], jež umožňuje vykreslování do canvasu objektovým sty- lem. Pro kreslení využívá tzv. shapes, s nimiž se dá snadno manipulovat, což je oproti standardním JavaScriptovým funkcím výhoda. Další JavaScriptovou součástí je soubor /js/cirrus.js, jež zajišťuje přímou ko- munikaci mezi klienty prostřednictvím Adobe Cirrus. Tento soubor se využívá pouze v případě, že je konfigurační konstanta pro použití této technologie na- stavena na hodnotu ”1”. Soubor obsahuje funkci pro korektní načtení flashového souboru a objekt cirrus, jenž se stará o navazování spojení, zasílání a příjímání zpráv prostřednictvím technologie Cirrus. Obsahuje navíc dvě funkce mimo ten- to objekt, jelikož rozhraní Adobe Flex neumí volat JavaScriptové funkce uvnitř objektu.

Životní cyklus bitevní stránky

Život stránky zobrazující bitvy je z pohledu klasického webu neobvykle dlouhý. Stránka si všechny informace o bitvě načítá buď pomocí asynchronních http po- žadavků na server (odesílaných JavaScriptem), nebo na základě přijatých dat od protihráče (pomocí P2P spojení). Do prezentační části se pak v obou případech všechny změny promítají JavaScriptem. Jak se v různých fázích bitvy načítají jednotlivé informace je vidět na obrázcích 3.7 a 3.8. Stránka jako celek se tedy v průběhu bitvy nemění, mění se pouze její části.

Vykreslení bitevního pole

Bitevní pole samotné se vykresluje JavaScriptem pomocí canvasu. Skládá se z še- dého podkladu, jež obsahuje síť čtverců v izometrickém náhledu (tzn. zkoseném o 27,5 ◦) i s patřičnými vyvýšeninami a kopci. Přes tento podklad se zobrazu- je transparentní mapa terénu. O kreslení bitevní plochy se stará JavaScriptová

50 Obrázek 3.7: Životní cyklus stránky s bitvou s navázaným P2P spojení pomocí flashe

Obrázek 3.8: Životní cyklus stránky s bitvou bez podpory flashe funkce battleDraw(), o vykreslení jednotek pak funkce unitsDraw().

Generování bitevního pole

Bitevní pole se skládá ze dvou částí - jednak ze samotného terénu, jednak z masky, která dodává terénu plasticitu a určuje tedy výšku terénu. Každé políčko na hrací ploše (určené souřadnicemi X a Y) je tedy specifikováno svojí výškou a druhem terénu. Z technického pohledu je jednoduché takovéto plochy generovat náhodně, z pohledu estetického se zde však naráží na problém skládání jednotlivých obráz- ků tak, aby byl výsledný terén k nerozeznání od terénu, který vytvoří lidská ruka. Problém spočívá v tom, jak jednotlivá políčka skládat vedle sebe a jak vytvářet přechody mezi různými terény. Tyto přechody by musely být ideálně připraveny pro všechny možné kombinace terénů, což dále v kombinaci s různými výškami te- rénu (a tedy různému zkosení políček) dává příliš velké množství přechodů. Proto je vrstva terénu vkládána jako jednolitý předem připravený obrázek (”textura”).

51 V rámci dalšího rozvoje je pak možné vytvořit editor map, kde bude uživatel moci textury editovat. Masku výšek pak lze generovat libovolně.

3.3.2 Uživatelské rozhraní správní části hry

Správní část hry slouží ke správě armád, k zakládání a přihlašování se do bitev a ke správě uživatelského profilu. Šablony uživatelského rozhraní se nacházejí v podadresářích /protected/views, konkrétně se jedná o adresáře army, battle, battleHistory a user pro odpovídající sekce. Dále v adresáři site se nachází šablona pro chybové hlášky (error.php), úvodní stranu (index.php) a stránku pro přihlášení a registrace uživatele (lo- gin.php). Jako layout se využívá soubor /protected/views/layouts/main.php pro přihlá- šeného uživatele, a /protected/views/layouts/login.php pro nepřihlášeného.

3.4 Komunikace v reálném čase

Dojem hry v reálném čase je navozen pomocí přímé komunikace (peer to peer) mezi oběma klienty bez zapojení serveru. Peer to peer komunikace je realizována pomocí neviditelného flashe vloženého ve stránce bitvy. Komunikace je inicializo- vána zakládajícím hráčem - ten vygeneruje komunikační klíč, jenž si od něj pak asynchronním požadavkem vyžádá druhý hráč. Pomocí těchto klíčů již pak flash player může navázat přímou komunikaci s protihráčem. Flashové funkce napsané v ActionScriptu se dají snadno volat přímo z Ja- vaScriptu, obráceně je pak využita třída flash.internal.ExternalInterface, jež je součástí ActionScriptu od verze 2. Flashová část napsaná v ActionScriptu je ma- ximálně jednoduchá - obsahuje pouze funkce pro vygenerování klíče, navázání spojení, odeslání textové zprávy a přijmutí textové zprávy. Vstup i výstup texto- vé zprávy pak rovnou předává JavaScriptovým funkcím. Zažádání o vygenerování klíče proběhne vždy po načtení bitvy. Jakmile klient obdrží identifikátor spojení od serveru Adobe, předá jej JavaScriptové funkci jež ho pomocí Ajaxového volání uloží do databáze. Odtud si jej pak stáhne druhý

52 klient, který s jeho pomocí naváže přímé spojení. Do doby, než se podaří navázat přímé peer to peer spojení, budou oba klienti v normálním Ajaxovém režimu - celá bitva je tedy funkční s tím, že oba klienti se periodicky po určité době dotazují serveru na nové informace o bitvě. Stejně tak pokud je přímé spojení přerušeno - pokud tedy ActionScript vrátí chybu spojení, musí o tom informovat i JavaScriptovou část bitevního rozhraní.

3.4.1 Fronta činností

Fronta činností je forma optimalizace sloužící pro zmenšení požadavků vysílaných na server. Myšlenkou je minimalizování počtu dotazů na server. Změny pohybu oddílů na serveru se budou ukládat vždy pouze při ukončení kola či při akci útoku či použití schopnosti - každý pohyb se tedy při jeho provedení uloží pouze lokálně u klienta. Tato fronta pohybů se na konci tahu odešle na server, kde se ověří, zda je v pořádku (tzn. na serveru se zkontrolují všechny použité cesty a ověří se, zda na danou cestu měl oddíl dostatek pohybových bodů, z důvodu snadného podstrčení falešných hodnot na straně klienta). Výhodou je, že na serveru se již nemusí cesta hledat, není tedy potřeba znovu implementovat algoritmus pro vyhledávání cest. Stačí pouze jít po krocích vygenerovaných JavaScriptovým algoritmem pro hledání nejkratší cesty a kontrolovat, že každý jednotlivý krok je v pořádku.

53 4. Administrátorská dokumentace

Zde je popsána instalace a konfigurace frameworku a na příkladech jsou ilustro- vány vlastní úpravy hrdiny, tvorba vlastní jednotky a hrdinovy schopnosti.

4.1 Instalace

Požadavkem na instalaci je webový server s podporou PhP ve verzi 5 a vyš- ším. Doporučeným webovým serverem je server Apache [59] ve verzi 2.0 a vyšší. Framework pro svůj chod dále vyžaduje databázi PostgreSQL verze 9 a vyšší. Pro instalaci nové hry je nejprve potřeba nahrát framework do vyhrazeného prostoru webového serveru (zpravidla adresář ”www”). Framework zde musí být umístěn v samostatném adresáři. V této složce by také měl být umístěn framework Yii ve složce pojmenované ”yii”. Pokud je třeba umístit framework yii jinam, je nutné v souboru index.php kořenového adresáře frameworku upravit hodnotu proměnné $yii na příslušnou cestu. Po nakopírování frameworku na správné místo je třeba se ujistit, že webový server má oprávnění zapisovat na potřebná místa. Pro instalaci to znamená prá- vo zápisu do souboru /protected/config/database.php (po dokončení instalace je třeba tento soubor pro zápis zakázat). Dále je nutné mít možnost nahrávat obráz- ky do podadresářů adresáře /img, konkrétně ”battlegrounds” (i s podadresářem ”types”), ”heroes”, ”units” (i s podadresáři) a do všech podadresářů ”icons”. Vytvoření databázového schématu se provede přes průvodce dostupného na adrese install.php kořenového adresáře frameworku. Průvodce vyžaduje zadání přístupu k PostgreSQL databázi, do níž vytvoří nové schéma se všemi tabulkami, procedurami a pohledy. Následně vytvoří účet administrátora dle zadaných údajů a umožní první přihlášení. Po dokončení procedury se soubor install.php sám odstraní. Po dokončení průvodce je pro zprovoznění hry nutné prostřednictvím admi- nistračního rozhraní vložit do hry potřebná data, viz kap. 4.2.

54 4.2 Konfigurace

Konfigurace probíhá přes sadu formulářů v administračním rozhraní. Uživatel s potřebným oprávněním se do tohoto rozhraní dostane přes odkaz ”Administra- ce” v menu v základním rozhraní. Zde je v levém panelu přehled všech adminis- tračních sekcí, což zahrnuje přehled všech herních entit, jejich úpravy, mazání a přidávání. Toto rozhraní by se mělo použít nejlépe pouze při počáteční konfiguraci hry. První sekcí je ”Konfigurace hry”, kde se dají upravovat všechny herní kon- stanty. Jejich popis se nachází na přiloženém DVD v souboru ”Konfigurační pa- rametry.pdf”. V sekci ”Mapy” je možné přidávat mapy - při zakládání nové bitvy je pak náhodně vybrána jedna ze zde vytvořených map. Mapy se skládají ze dvou částí - tzv. textury, která se nahrává v podobě poloprůhledného obrázku formátu png, a masky, jež je tvořena sítí znázorňující odlišné výšky jednotlivých políček. Ve výpisu map je odkaz do sekce ”Nastavit mapu”, kde je zobrazena mapa i s maskou. Na každé políčko je zde možné kliknout a v pravém sloupci mu pak zvolit výšku a druh terénu.

4.3 Programátorské úpravy

V této kapitole je popsáno, jak se dá hra upravovat na úrovni kódu. Obsahuje návod pro úpravu hrdiny, vytvoření nového typu jednotky a hrdinovy schopnos- ti. Tato kapitola nepopisuje všechny možné úpravy, pouze popisuje mechanismy, jakým lze dané objekty měnit a na příkladech ilustruje, jak by se k úpravám mě- lo přistupovat. Rovněž neobsahuje popis jednotlivých metod popisovaných tříd, jež se dají upravovat. Ten se nachází v adresáři s dokumentací kódu na přilože- ném DVD a rovněž ve formě komentářů v kódu samotném. Všechny popisované příklady jsou k dispozici v uvedených adresářích vzorové hry.

4.3.1 Načítání vlastní třídy

Každá vlastní vytvářená třída musí obsahovat statickou třídu loadModel(), jež příjímá jako parametr id objektu a vrací korektní instanci třídy (jedná se o tzv.

55 tovární výrobu instancí). Doporučený postup pro vytváření tříd je dědění od im- plicitní třídy, resp. od třídy FActiveRecord. V takovém případě bude kód metody loadModel() vypadat podobně jako následující kód: public static function loadModel($id) { $record = new self(’search’); $record->id = $id; $record->refresh(); return $record; }

Metoda je umístěna ve zděděné třídě a vrací instanci sama sebe (scénář ”search” se ve frameworku Yii používá pro načítání modelu z databáze). Mo- delu je třeba předat id objektu - zde se kód může drobně lišit v závislosti na názvu parametru (např. idunit, idability, ...). Následně je třeba zavolat metodu refresh pro načtení potřebných dat z databáze a výsledný objekt vrátit. V případě tvorby třídy, jež nedědí od objektů frameworku Yii je potřeba tuto metodu naimplementovat ručně - je tedy třeba vytvořit instanci samu sebe a tu pak naplnit daty.

4.3.2 Tvorba vlastní jednotky

Tvorba vlastní jednotky podle standardní šablony probíhá pomocí konfigura- ce hry, jež je popsána v části 4.2. Pro vytvoření vlastní přeprogramovatelné jednotky je třeba vytvořit jednotku běžným postupem, avšak je třeba vyplnit název třídy. Třídu se stejným názvem je pak třeba vytvořit v adresáři /pro- tected/customized/models. Třída musí být uložena v samostatném souboru se stejným názvem jako třída samotná, s koncovkou php. Jedinou nutnou podmínkou třídy jednotky je, že musí implementovat rozhraní IUnit. Doporučený postup je nicméně vytvářet tuto třídu jako dědice jiné třídy - buď CComponent, což přináší výhodu možnosti využití standardních konstruk- tů frameworku Yii. Další možností je dědit od třídy FActiveRecord (potažmo CActiveRecord), jež navíc přidává i implicitní implementace metod pro ukládá- ní, mazání a hromadné nastavování atributů. Poslední variantou je pak dědění

56 od třídy UnitDb, jež sama o sobě implementuje všechny vyžadované metody, a v této třídě pouze přepsat existující metody či přidat metody nové. Např. vlastní jednotka, jež má jméno třídy UnitSpecial a upravuje útok tak, že se zde nepočítá s faktorem náhody, výškového bonusu a ani se nezohledňuje počet útoků v jednom kole, vypadá následovně: class UnitSpecial extends UnitDb implements IUnit { public static function loadModel($id) { $record = new self(’search’); $record->idunit = $id; $record->refresh(); return $record; }

public function attack($idUnit) { ... // count attack rate (meaning how much life would target lose) $attackRate = $this->getAttack() - $target->getDefense(); ... }

}

Celá třída tedy obsahuje jedinou metodu attack(), ostatní dědí v nezměněné podobě od třídy UnitDb. Metoda attack() sama je rovněž téměř shodnou kopií funkce attack() v předkovi, až na řádek, ve kterém se počítá hodnota ubraných životů.

4.3.3 Tvorba vlastní hrdinovy schopnosti

Tvorba hrdinovy schopnosti probíhá obdobně jako tvorba typu jednotky. Musí existovat záznam v databázi vytvořený pomocí konfigurace hry, který musí mít vyplněn název třídy. Tato třída se nahraje do adresáře /protected/customized- /models a musí implementovat rozhraní IDataAbility. Opět je vhodné tuto třídu

57 nevytvářet zcela od začátku, ale raději ji vytvořit jako potomka CComponent, FActiveRecord nebo nejlépe implicitní implementace DataAbilityDb. Schopnosti se zpravidla upravují pomocí metody run() - tato metoda se volá automaticky v určitý moment, jež se nastaví v konfiguraci při vytváření schopnosti (např. před útokem, po útoku, ...). Metoda run() dostává jako parametr pole argumentů, jež se mohou lišit v závislosti na scénáři - např. při útoku je v něm uložena jednotka útočníka, obránce a příp. škoda. Přesné parametry pro jednotlivé scénáře jsou popsány v programátorské dokumentaci na přiloženém DVD. Následující příklad ilustruje schopnost, jež se aktivuje automaticky po obraně jednotky (má tedy vlastnost ”fireevent” nastavenu na ”onAfterDefense”). V daný moment obrany je tedy volána metoda run(). Parametrem je pole obsahující po řadě útočníka, obránce a způsobenou škodu. Tato schopnost se užívá na vlastní armádu, obráncem je tedy vždy vlastní oddíl. Metoda zkontroluje, zda byla způ- sobena nějaká škoda, a pokud ano, okamžitě vrátí obránci 1 život. V případě, že však došlo k eliminaci oddílu, tento oddíl zůstává eliminován. class DataAbilityCustom extends DataAbilityDb implements IDataAbility {

public static function loadModel($id) { $record = new self(’search’); $record->idability = $id; $record->refresh(); return $record; }

public function run($param) { $myUnit = $param[1]; // defender $damage = $param[2]; if ($damage > 0) { $myUnit->setLifes($myUnit->getLifes() + 1); if ($myUnit->getLifes() == 1) { $myUnit->setEliminated(false); } $myUnit->save();

58 } return true; }

}

4.3.4 Tvorba vlastního zvláštního výcviku

Tvorba vlastního zvláštního výcviku probíhá dle stejného scénaře, jako tvorba schopnosti. Metoda run() zde figuruje zcela stejně jako metoda run() ve třídě schopnosti, rozdíl však je v parametrech. Metoda run() zvláštního výcviku se vždy váže pouze k jednotce, která má na rozdíl od hrdinových schopností omezenou působnost, proto vždy dostává jako parametr jednotku, která událost vyvolala, a jednotku protihráče. Vzorová hra obsahuje zvláštní výcvik, jež snižuje o 1 bod cenu útoku. Třída se jmenuje DataLowcostAttack a vypadá následovně: class DataLowcostAttack extends DataSpecialTrainingDb implements IDataSpecialTraining {

public static function loadModel($id) { ... }

public function run($ownUnit, $otherUnit) { $ownUnit->setMovePoints($ownUnit->getMovePoints() + 1); $ownUnit->save(); return true; }

}

4.3.5 Úprava hrdiny

Třída hrdiny se nachází v podadresáři ”protected/models” frameworku a má název Hero.php. Tato třída musí dědit od třídy FActiveRecord frameworku Yii

59 (z důvodu zděděných metod pro ukládání a mazání objektu, možnosti nastavit vztahy s dalšími objekty a zabudovanými validacemi uživatelských vstupů). Třída hrdiny je ve hře vždy pouze jedna, jež zajišťuje základní mechanismy pro všechny hrdiny, které lze parametrizovat jejich školou, předměty a schopnostmi. Jedna třída tedy pokrývá všechny hrdiny, proto není třeba ji duplikovat do adresáře ”customized”. Pro úpravu hrdiny je možné provádět změny přímo do původního souboru, je však doporučeno původní soubor před provedením úprav zálohovat. Možných úprav hrdiny je prakticky neomezené množství, zde jsou vysvětleny dvě, jež mají ilustrovat obecný postup při úpravách. První úprava spočívá v tom, že hrdina má přijít o všechnu koncentraci ve chvíli, kdy se přesouvá k jednotce či naopak do záloh. Je třeba provést změnu v metodách moveToUnit() a moveToBackup(). Do obou metod stačí na konec přidat následující řádek:

$this->concentration = 0;

Další možný scénář úpravy je přidání dalšího druhu koncentrace - např. ta- kový, který se nikdy neregeneruje, tedy omezuje hrdinu na použití maximálního množství schopností za bitvu. V tomto případě je třeba přidat do tabulky ”hero- es” číselný sloupec pro držení hodnoty nové koncentrace nazvaný např. ”mana”. Tím již třída Hero automaticky disponuje vlastností ”mana” (díky mechanismu frameworku Yii). Dále je třeba přidat novou vlastnost do validačních pravidel v metodě rules(), jež je zděděna od třídy CActiveRecord frameworku Yii [58]. Jediné potřebné pravidlo říká, že tato hodnota má být numerická: public function rules() { return array( array(’idarmy, ..., mana’, ’required’), array(’idarmy, ..., mana’, ’numerical’, ’integerOnly’ => true), ... ); }

Dále je třeba přidat popis do metody attributeLabels():

60 public function attributeLabels() { return array( ’idhero’ => ’Idhero’, ... ’mana’ => Yii::t(’Site’, ’Hrdinova mana’), ); }

Nyní zbývá upravit metodu useAbility() tak, aby při každém použití schop- nosti odečetla hrdinovy z jeho many i cenu schopnosti. Na konec této metody stačí přidat následující řádek:

$this->mana -= $ability->getConcentration();

Dalším krokem je hodnotu hrdinovy many nějak inicializovat. To se provede nejjednodušeji přidáním kódu do metody calcHeroVals(), jež se volá při vytvoření či úpravě hrdiny. Je možné vytvořit novou konstantní hodnotu a tu nastavit pevně každému hrdinovi: public function calcHeroVals() { $this->calculateAttack(); ... $this->mana = Yii::app()->config->get(’GAME_HERO_MAX_MANA’); }

Tato konstanta musí být předem vytvořena. Pokud se má hodnota vypočítávat dle jiných vlastností hrdiny, je vhodné vytvořit novou metodu calculateMana() a namísto přímého nastavení hodnoty volat tuto metodu. Poslední úpravou je obnovení hodnoty hrdinovy many po konci bitvy v metodě restore(): public function restore() { ... $this->mana = Yii::app()->config->get(’GAME_HERO_MAX_MANA’); }

61 Opět je zde namísto přímého nastavení konstantní hodnoty možné volat vy- tvořenou metodu calculateMana(). Na závěr je ještě potřeba provedené změny zobrazit. K tomu si lze vytvo- řit pomocnou metodu getMana() a tuto hodnotu následně promítnout v da- ných pohledech - /protected/views/hero/ form.php pro hrdinovu editaci, /protec- ted/views/hero/ view.php pro hrdinovo zobrazení v armádě a /protected/views- /battle/ground.php pro zobrazní v bitvě. Takto tedy hrdina disponuje dvěmi hodnotami koncentrace - jednou aktuální, jež se každé kolo regeneruje, a jednou celkovou, jež mu musí vystačit na celou dobu bitvy. Pokud by se od many neměla odečítat cena schopnosti v bodech koncentrace, ale skutečně many, je třeba provést obdobný proces pro schopnosti - přidat do tabulky ”data abilities” číselný sloupec mana, přidat do rozhraní (a všech tříd jež je implementují) IDataAbility metodu getMana() a tuto metodu pak volat v metodě useAbility() namísto metody getConcentration().

4.4 Používání systému zpráv

V průběhu hry je vhodné informovat hráče o tom, co se děje pomocí systému zpráv bitvy. Stačí využít metodu setBattleMessage() třídy Army. Tato metoda vyžaduje dva parametry - text zprávy samotný, a kategorii zprávy. Volba kategorií je čistě orientační, členění závisí na konkrétní konfiguraci (možností je např. dělit zprávy na systémové, zprávy útoku, obrany, použití schopnosti, ...). Dle kategorií je pak možné implementovat do uživatelského rozhraní například barevné rozlišení či pokročilejší filtrování. Instanci armády lze získat jednoduše pomocí jejího id, např. z hrdiny:

$army = Army::model()->findByPk($hero->getIdArmy());

Implicitní implementace jednotky obsahuje instanci armády přímo jako vlast- nost:

$army = $unit->army;

62 4.5 Přidání dalších událostí pro schopnosti či zvláštní výcviky

Systém událostí funguje tak, že na místě, kde se má událost vyvolat, je volána protected metoda triggerSomeAction(). Název a konkrétní parametry závisí již vždy na konkrétním použití. V těle této metody je pak cyklus iterující přes všech- ny schopnosti a zvláštní výcviky všech zúčastněných objektů. Například metoda triggerAfterAttack jednotky vypadá v implicitní implementaci takto: protected function triggerAfterAttack($target, $attackRate) { // run abilities on attacker foreach ($this->getActiveAbilities() as $ability) { if ($ability->getFireevent() == ’onAfterAttack’) { $ability->run(array($this, $target, $attackRate)); } } // run on defender foreach ($target->getActiveAbilities() as $ability) { if ($ability->getFireevent() == ’onAfterDefense’) { $ability->run(array($this, $target, $attackRate)); } } // run special trainings on attacker foreach ($this->getSpecialTrainings() as $specialTrain) { if ($specialTrain->getFireevent() == ’onAfterAttack’) { $specialTrain->run($this, $target); } } // run special trainings on defender foreach ($target->getSpecialTrainings() as $specialTrain) { if ($specialTrain->getFireevent() == ’onAfterDefense’) { $specialTrain->run($this, $target); } } }

63 Jsou zde tedy dva objekty - útočník a obránce - a na obou se volají události jak pro schopnosti, tak pro zvláštní výcviky. Vlastní událost lze vytvořit obdobně - je třeba vytvořit obdobnou metodu jako triggerAfterAttack, jež ovšem bude zpracovávat jen schopnosti či zvláštní výcviky ve stanovenou událost. Novou událost je možno pojmenovat libovolně, je však třeba přidat název této události do databázového omezení ”fireevent” v tabulce data abilities či data special trainings. Nakonec stačí přidat volbu pro danou událost do konfigurace, tedy souboru /views/admin/abilityEdit.php, resp. /views/admin/specialTrainEdit.php.

64 5. Herní dokumentace

Tato část práce na vzorové implementaci hry Fight for Eternity popisuje, jak vytvořit a spravovat uživatelský účet, armádu a bitvu. Dále je vysvětleno, jak samotnou bitvu hrát.

5.1 Správa uživatelského účtu

Vytvoření uživatelského účtu probíhá na úvodní obrazovce hry - po kliknutí na tlačítko ”Zaregistrovat” se objeví dialog s jednoduchým formulářem, pro zadání uživatelského jména, e-mailu a hesla. Po vytvoření účtu je uživatel automaticky přihlášen a přesměrován na hlavní stránku správního rozhraní. Zde se nachází rychlý přehled rozehraných her, otevřených her (tj. takových, v nichž je možno začít hrát) a přehled uživatelových armád. Před začátkem hry je nutno vytvořit si vlastní armádu.

5.2 Správa armády

V sekci armády se po kliknutí na tlačítko ”Vytvořit novou armádu” zobrazí for- mulář, do něhož je potřeba zadat název nové armády a vybrat alespoň jednu rasu. Po vytvoření se zobrazí hlavní stránka armády - zde je možné provést úpravu ar- mády (jména a rasy) a pomocí odpovídajících tlačítek přidat jednotku či hrdinu. Aby armáda mohla vstoupit do bitvy, musí obsahovat alespoň jednu jednotku. Dialog pro vytvoření jednotky obsahuje výběr rasy a typu jednotky. Typ jed- notky pak ovlivní možnou výzbroj. Dialog pro tvorbu hrdiny se skládá ze tří kroků, druhý krok je na obrázku 5.2. V prvním kroku uživatel zadává jméno, pohlaví, rasu, školu a obrázek hrdiny. Nově vytvářený hrdina je vždy na prv- ní úrovni, s tím, jak získává zkušenosti z boje jeho úroveň roste, čímž získává možnost vlastnit nové předměty a schopnosti. Ve druhém kroku se nachází tzv. obchod - uživatel může koupit hrdinovy předměty ze čtyř různých obchodů (je- jich nabídka se nachází v levém horním rohu dialogu). Které předměty může hrdina používat se liší dle jeho úrovně a školy. Zakoupení předmětu se provede

65 Obrázek 5.1: Správa armády přetažením ikonky předmětu z levé části nabídky obchodu na příslušné místo na vyobrazení hrdiny. V pravém sloupci se pak okamžitě zobrazí nová cena hrdiny a jeho vlastnosti. Ve třetím kroku se pak obdobným způsobem volí schopnosti. Schopnosti však nestojí žádné peníze, jejich počet je nicméně omezen a je přímo úměrný hrdinově úrovni.

Obrázek 5.2: Dialog pro tvorbu hrdiny

Po vytvoření hrdiny a jednotky se na stránce armády zobrazí nové záložky s typem oddílu a jedna záložka navíc pro hrdiny. V těchto záložkách jsou zobra-

66 zeny všechny oddíly daného typu, resp. všichni hrdinové armády. Je zde možnost mazání a úpravy, jež opět otevře stejný dialog popsaný výše. V případě úpravy jsou však některé možnosti neaktivní (rasa, typ jednotky, pohlaví, apod.). Posledním krokem ve tvorbě armády je nastavit počáteční rozestavení oddílů - bez tohoto kroku s armádou není možné hrát. Po vytvoření prvního oddílu přiby- lo vedle tlačítek pro tvorbu hrdiny a jednotky navíc tlačítko ”Nastavit počáteční rozestavení”, jež otevře dialog, ve kterém jsou nahoře vyobrazeny všechny jed- notky armády, a dále první tři řádky bitevního pole (směr útoku je vždy dolů). Kliknutím na oddíl a následně na políčko je možné oddíl umístit. Po umístění všech oddílů je již armáda připravena k bitvě.

5.3 Správa bitvy

V sekci bitvy je zobrazen přehled všech bitev a možnost vytvořit novou bitvu. Pro připojení do již existující bitvy stačí na danou bitvu kliknout a v podrobnostech zvolit vhodnou armádu a kliknout na ”Připojit”. Následně se zde zobrazí volba pro změnu přihlášené armády a odkaz ”Moje armáda je připravena na bitvu”, čímž se spustí bitva samotná.

Obrázek 5.3: Správa bitvy

Vytvoření nové hry je velmi jednoduché, stačí zadat název a armádu, systém již sám vygeneruje terén. Následně je třeba počkat na druhého hráče, v případě kliknutí na odkaz ”Moje armáda je připravena na bitvu” se spouští bitva samotná obdobně jako v předchozím případě. Do obrazovky bitvy je možno vstoupit i bez

67 přítomnosti druhého hráče, není pak nicméně možné provádět žádné akce.

5.4 Bitva

Rozhraní bitvy (viz obrázek 5.4) je navrženo tak, aby zobrazovalo především následující informace:

• Tlačítko odkliknutí tahu (1) - tlačítko volá JavaScriptovou funkci en- dTurn() pro ukončení tahu, jež odesílá informace o proběhlém tahu na server, a předává tah druhému hráči.

• Čas zbývající na dokončení tahu (2) - čas (vteřiny), které zbývají na dokončení tahu. Po uplynutí této doby se tah automaticky ukončí.

• Přehled hrdinů a aktivních jednotek (3) - v levém panelu je přehled všech hrdinů armády, přičemž po kliknutí na daného hrdinu se otevře menu s možnými akcemi (přesunutí ze/do zálohy, použití schopnosti). Dále se zde zobrazují oddíly, jež mohou v aktuálním kole provádět nějaké akce.

• Možnost pauzy, kapitulace (4) - v poslední záložce levého panelu se nacházejí tlačítka pro pauznutí hry, kapitulaci a odkaz zpět do správního rozhraní hry.

• Zobrazení zpráv bitevního systému (5) - v dolní části obrazovky je lišta, jež zobrazuje vždy poslední zprávu z bitvy, po kliknutí na tuto lištu se tato zvětší na výšku (čímž překryje část bitevního pole) a zobrazí výpis všech zpráv dané bitvy.

• Výpis aktivních schopností (6) - v pravém horním rohu se nachází výpis všech aktivních schopností (dané armády).

Pro začátek bitvy je třeba počkat, až oba přihlášení uživatelé kliknou na spuštění bitvy. V tu chvíli se začíná odpočítávat čas prvnímu hráči. Tah končí buď tím, že uživatel klikne na obrázek přesýpacích hodin vlevo dole, nebo automaticky po vypršení času.

68 Obrázek 5.4: Bitevní obrazovka

V levém panelu má uživatel přehled o celé své armádě, buď v záložce ”All”, kde je výpis všech hrdinů a jednotek, nebo v záložce ”Active”, kde jsou zobrazeny pouze jednotky, jímž zbývají v aktuálním kole nějaké pohybové body. U výpisu hrdiny se nachází stav jeho koncentrace (modrý proužek), tedy počet bodů, které mu zbývají na použití některé z jeho schopností. Pokud je u nějakého oddílu, je zde zobrazena i tato skutečnost a je zde navíc vyobrazen stav zdraví a pohybových bodů oddílu (červený a hnědý proužek). Po kliknutí na hrdinu se zobrazí nabídka umožňující přesunout ho na bitevní pole k jednotce či naopak zpět do záloh. Cesta od jednotky k jednotce či do záloh a naopak trvá určitý počet kol, kdy je hrdina nepoužitelný. Z hrdinovy nabídky je rovněž možné používat libovolné schopnosti, jimiž hrdina disponuje. Při použití schopnosti, jež vyžaduje cílovou jednotku, se změní kurzor a je nutné tuto jednotku vybrat kliknutím (to samé se vztahuje i na přesunutí hrdiny k jednotce). Po kliknutí na jednotku, ať už v levém panelu, či přímo na bitevní ploše se jednotka označí, a je možné se s ní pohybovat (v rámci jejích pohybových bodů) či útočit. Obě tyto akce se provedou kliknutím na cílové políčko (v případě pohybu prázdné, v případě útoku s nepřátelskou jednotkou). V záložce ”Menu” levého panelu se nachází možnost kapitulace a navrhnutí pauzy. Pauza hry probíhá do přesně stanového času a musí ji schválit oba hrající uživatelé. Jeden hráč má nárok navrhnout pauzu pouze jednou za pět minut.

69 Obrázek 5.5: Obrázek bitvy

Dolní část bitevního rozhraní obsahuje výpis bitevních zpráv, jež je možné rozkliknout pro podrobný výpis. V pravém horním rohu jsou pak vypsány všechny aktivní schopnosti s jejich zbývajícím časem (počtem kol, po které ještě budou aktivní). Ukázka rozehrané bitvy je k dispozici na obrázku 5.5.

70 6. Obsah přiloženého DVD

V této kapitole je v tabulce 6.1 popsán obsah přiloženého DVD. Následně je po- psáno, jak používat zahrnutý virtuální stroj obsahující funkční kopii frameworku.

Tabulka 6.1: Struktura přiloženého DVD Název Popis Image Adresář obsahující virtuální stroj, viz 6.1 Dokumentace Adresář obsahující generovanou doku- mentaci zdrojových kódů (spouští se otevřením souboru ”index.html”) Zdrojové kódy Adresář obsahující zdrojové kódy fra- meworku Struktura databáze.pdf Diagram se strukturou databáze Konfigurační parametry.pdf Popis konfiguračních parametrů fra- meworku (konstant) Pravidla hry.pdf Pravidla vzorové hry (dovysvětlují ně- které herní mechanismy) Práce.pdf Kopie této práce

6.1 Virtuální stroj

Přiložené DVD obsahuje v adresáři ”Image” obraz virtuálního stroje s operačním systémem Ubuntu 12.10. Celý adresář je třeba zkopírovat na pevný disk a spustit v programu VMware (např. VMware Workstation či VMware Player). Pro správ- nou funkci je třeba zajistit, aby měl virtuální stroj přístup k internetu. Obraz je nakonfigurovaný tak, že přímo využívá síťovou kartu počítače, na kterém je spuštěn. Uživatelský účet systému je ”mff” s heslem ”mff”. Ve virtuálním systému jsou pak na ploše umístěny dvě ikony pro rychlé spuště- ní vzorové hry a instalátoru. Odpovídající adresy jsou http://fish.example.com/ a http://install.example.com/. Pro simulaci hry dvou hráčů je možné otevřít vzo- rovou hru ve dvou dostupných prohlížečích (Firefox a Chromium) a přihlásit se s existujícími uživatelskými účty ”Adam” a ”Barbora”. Hesla k uživatelským účtům jsou stejná jako jejich názvy. Účet Adam je účtem administrátorským s nejvyšším oprávněním (i s možností konfigurace celé hry).

71 Při instalaci je třeba zadat údaje pro připojení k databázi. Ve virtuálním systému je vytvořena databáze s názvem ”installtest”. Adresou databázového serveru je ”localhost”, pro přihlášení k databázi lze využít účet ”postgres” s heslem ”1234”.

72 Závěr

Cílem práce bylo vytvořit snadno rozšiřitelný framework pro tvorbu interneto- vých strategických her. Práce představuje a srovnává současné technologie běžně používané pro vývoj internetových aplikací. Popisuje rovněž klíčové problémy na něž naráží nejen vývoj herního on-line frameworku, ale i mnoho jiných moderních internetových aplikací (tzv. Web 2.0 či Rich internet applications). Nejzásadnějším popisovaným problémem je komunikace dvou klientů a ne- možnost zasílání ”push notifikací” pomocí v současné době používaného proto- kolu HTTP 1. V práci jsou popsány možné postupy, jak navázat přímé spojení mezi dvěma klienty, či jak je možné vyřešit problém s nemožností zahájení ko- munikace mezi klientem a serverem ze strany serveru. Dále je pak představeno řešení pomocí kombinace periodického zasílání dotazů na server přes standardní HTTP protokol, a technologie Adobe Cirrus, jež umožňuje přímou komunikaci mezi klienty. Dalším řešeným problémem je pak grafické vykreslování bitevního pole. Pro- blémem je, jak vykreslovat plochu, jež se skládá ze dvou částí - barvy (terénu) a výšky - tak, aby se obě části mohly snadno měnit. Výšky jsou tak přidány až nakonec jako síť zkosených obdélníků, jejichž tvar se mění dle výšek soused- ních políček. Problém generování terénu se však vyřešit nepodařilo z estetických důvodů, jelikož při jednoduchém generování barev (či primitivních textur) do při- pravené sítě políček je bitevní pole velice nehezké. Proto se pozadí bitevní plochy nahrává jako jeden předpřipravený poloprůhledný obrázek. Stěžejním bodem pro vývoj celého frameworku je návrh databáze a návrh používaných objektů. Ty jsou detailně popsány ve třetí kapitole. Nejzajímavější částí je načítání vlastních tříd pro některé typy objektů, kdy se využívá tovární metody, jež vybírá správnou třídu pro daný objekt na základě hodnoty načtené z databáze. To umožňuje jednoduchou rozšiřitelnost konkrétní hry přidáváním vlastních objektů, jež mohou být naprosto odlišné od vzorové hry. Framework rovněž disponuje jednoduchým systémem událostí, kdy je možné uložit některé události do fronty a volat je v určitou chvíli. Systém událostí implementuje zá- kladní operace, při budoucím rozšiřování frameworku je pak možné jej přepsat

73 tak, aby byl flexibilnější. Uživatelské rozhraní vzorové hry obsahuje pouze části, které jsou pro funkci frameworku nezbytné a při dalším rozvoji projektu se jistě bude vylepšovat tak, aby bylo líbivější a intuitivnější. Pro tvorbu hry a následné hraní však zcela postačuje. V budoucnu rovněž budou doplněny další funkce, např. pro zasílání zpráv mezi hráči, výpisy hráčských profilů či fóra. V práci rovněž není řešeno vytváření odlišných vzhledů aplikace jinak, než na úrovni frameworku Yii, jež však nutí uživatele kopírovat a přepisovat všechny pohledy (views) aplikace. Toto by se dalo řešit i lépe tak, aby měl uživatel předdefinovaný automatický nástroj pro změnu vzhledu pomocí nahrávání obrázků a nastavení barev (podobně jako např. v systému Wordpress [56]). Framework zahrnuje průvodce instalací a sadu uživatelsky přívětivých for- mulářů pro následnou konfiguraci celé hry tak, aby vlastní hru dokázal spustit i technicky nevzdělaný uživatel. S využitím návodů v programátorské dokumen- taci je pak možno měnit herní objekty na úrovni zdrojového kódu. Pro ověření funkčnosti zvolené implementace byla nad tímto frameworkem implementovaná vzorová hra Fight for Eternity, čímž se dokázalo, že vytvořené řešení je funkční a použitelné.

74 Literatura

[1] Gutmans, Andi, Bakken, Stig, Rethans, Derick. Mistrovství v PhP5. 2. vydání. Computer Press, 2007 ISBN 978-80-251-1519-9.

[2] Momjian, Bruce. PostgreSQL: Praktický průvodce. 1. vydání. Computer Press, 2003 ISBN 80-7226-954-2.

[3] Delicata, Curtis. Modular Gaming. http://modulargaming.com/

[4] Bertrand, Alain. Nowhere Engine. http://engine.nowhere-else.org/

[5] Toloi, Marcio. DotK web engine. http://dotk-project.sourceforge. net/

[6] Bertrand, Alain. New Worlds Engine. http://www.nw-engine.com/

[7] LoGD Resource Community. Dragon Prime. http://dragonprime. net/

[8] PopcornPHP Team. PopCorn PhP game engine. http://popcornphp. com/

[9] Lerdorf, Rasmus. PhP. http://php.net/

[10] Hansson, David Heinemeier. Ruby On Rails. http://rubyonrails.cz/

[11] Sun Microsystems. JavaServer Pages. http://www.oracle.com/ technetwork/java/jsp-138432.html

[12] . ASP.NET. http://www.asp.net/

[13] Rossum, Guido van. Python. http://www.python.org/

[14] Eich, Brendan. JavaScript. https://developer.mozilla.org/en-US/ docs/JavaScript

[15] Odersky, Martin. Scala. http://www.scala-lang.org/

[16] Matoušek, Tomáš, Prošek, Ladislav. Phalanger. http://www. php-compiler.net/

[17] Dahl, Ryan Lienhart. Node.js. http://nodejs.org/

[18] Kubica, Marek. Python documentation: HOWTO Use Python in the web. http://docs.python.org/howto/webservers.html

[19] Microsoft. Microsoft SQL Server. http://www.microsoft.com/en-us/ sqlserver

[20] Oracle Corporation. Oracle Database. http://www.oracle.com

[21] Hipp, Richard. SQLite. http://www.sqlite.org/

75 [22] Oracle Corporation (pův. Sun Microsystems). MySQL. http:// www.mysql.com/

[23] PostgreSQL Global Development Group. PostgreSQL. http:// www.postgresql.org/

[24] Firebird Project. Firebird. http://www.firebirdsql.org/

[25] CakePhP. Cake Software Foundation, Inc.. http://cakephp.org/

[26] Nette Foundation. . http://nette.org/

[27] EllisLab. CodeIgniter. http://codeigniter.com/

[28] Kohana Team. Kohana Framework. http://kohanaframework.org/

[29] Xue, Qiang. Yii Framework. http://www.yiiframework.com/

[30] Zend. ”Zend Framework”, http://framework.zend.com/

[31] Sensio Labs. Symfony. http://www.symfony-project.org/

[32] Proietti, Valerio. SlickSpeed: speed/validity selectors test for frameworks. http://mootools.net/slickspeed/

[33] Wikipedia, Comparison of JavaScript frameworks. http://en.wikipedia. org/wiki/Comparison_of_JavaScript_frameworks

[34] Munandar, Freddy. JavaScript UI framework comparison or Why I cho- ose ExtJS & JQuery. http://fictionalrealm.com/coding/2009/04/19/ javascript-ui-framework-comparison-or-why-i-choose-extjs-jquery/

[35] Resig, John. JavaScript a Ajax: Moderní programování webových aplikací. 1. vydání. Computer Press, 2007 ISBN 978-80-251-1824-5.

[36] Wikipedia. Abstract factory pattern. http://en.wikipedia.org/wiki/ Abstract_factory_pattern

[37] Barth, A, Internet Engineering Task Force (IETF). HTTP State Manage- ment Mechanism. http://tools.ietf.org/html/rfc6265

[38] Hickson, Ian, Google, Inc. Web Storage W3C Candidate Recommendation. http://www.w3.org/TR/webstorage/

[39] Reinman, Andris. jStorage. http://www.jstorage.info/

[40] Bajer, Lukáš. Algoritmy pro pathfinding. http://bajeluk.matfyz.cz/ mff/algs-4-pathf.pdf. 2006

[41] Scheiber, Emanuel. Comparison Of Pathfinding Algorithms, Bachelor Thesis. http://www.emanuel.frihost.org/hp/index.php?option=com_ content&view=article&id=47&Itemid=54. 2011

[42] Stefanov, Stoyan. AJAX MVC. http://www.phpied.com/ajax-mvc/

76 [43] Bernard, Borek. MVC a další prezentační vzory. http://www.zdrojak. cz/serialy/mvc-a-dalsi-prezentacni-vzory/

[44] Yii Community. Model-View-Controller (MVC). http://www. yiiframework.com/doc/guide/1.1/en/basics.mvc

[45] Langerak, Berry. Getters and setters: evil or necessary evil?. http://berryllium.nl/2011/02/ getters-and-setters-evil-or-necessary-evil/

[46] Yii Community. Yii Documentation: Authentication and Authorization. http://www.yiiframework.com/doc/guide/1.1/en/topics.auth

[47] Yii Community. Yii Documentation: Logging. http://www. yiiframework.com/doc/guide/1.1/en/topics.logging

[48] Yii Community. Yii Documentation: CErrorHandler. http://www. yiiframework.com/doc/api/1.1/CErrorHandler

[49] Yii Community. Yii Documentation: Error Handling. http://www. yiiframework.com/doc/guide/1.1/en/topics.error

[50] Riel, Mike van. PhPDocumentator. http://www.phpdoc.org/

[51] Douglas, Korry. PostgreSQL SQL Syntax and Use. 2. vydání. Sams Pub- lishing, 2006 ISBN 0-672-32756-2.

[52] Yii Community. Yii class reference: CActiveRecord. http://www. yiiframework.com/doc/api/1.1/CActiveRecord

[53] Yii Community. Yii class reference: CController. http://www. yiiframework.com/doc/api/1.1/CController

[54] Yii Community. Yii class reference: CBaseUserIdentity. http://www. yiiframework.com/doc/api/1.1/CBaseUserIdentity

[55] Yii Community. Understanding the view rende- ring flow. http://www.yiiframework.com/wiki/249/ understanding-the-view-rendering-flow/

[56] WordPress Foundation. Wordpress. http://cs.wordpress.org/

[57] Eric Rowell. KineticJS: Enterprise class interactive web graphics. http://kineticjs.com/

[58] Yii Community. Reference: Model rules validation. http://www. yiiframework.com/wiki/56/

[59] Apache Software Foundation. Apache HTTP Server Project. http:// httpd.apache.org/

77