Hry pro děti

Školení, která pořádám

Moje děti si občas chtějí zahrát nějakou hru. Tak už jsem jim několik her naprogramoval, občas i s jejich pomocí. Nešlo o to vytvořit něco dokonalého, ale rychle spíchnout něco, co bychom si mohli hned zahrát a snadno tomu přidávat další vlastnosti. Jednou jsme třeba někam letěli, tak jsem bez dostupnosti Internetu naprogramoval hru, kterou jsme se po zbytek letu bavili. Docela mě překvapilo, že celkem hratelná hra se vejde třeba i do 100 řádek JavaScriptu. Naštěstí jsem nemusel řešit, aby hry fungovaly ve všech prohlížečích, ale v dnešní době i tak nejspíš budou.


ukázka ze hryPrší

Klasická hra pro dva a více hráčů. Každý hráč hraje na svém zařízení, aby si vzájemně nekoukali do karet. Hry spolu komunikují pomocí WebSocket, což zajišťuje okamžitou viditelnost událostí na všech zařízeních bez nutnosti neustálého dotazování se serveru. Tím pádem je hra i trochu složitější na zprovoznění – nejprve je potřeba spustit server, pak ve zdrojáku nastavit, na jaké běží adrese a pak teprve otevřít hry v prohlížeči. Pro WebSockets jsem použil knihovnu Ratchet.


ukázka ze hryČlověče, nezlob se

Hra pro čtyři hráče. Pamatuji si, že se část stavu hry načítá přímo z DOMu, což je velmi krkolomné. Když bych hru programoval znovu, tak si veškerý stav uložím ve vlastních strukturách a do DOMu ho jenom promítám, nejspíš pomocí Reactu.


ukázka ze hryHad

Jednoduchá hra pro tři hráče. Po obrazovce lezou hadi, kteří žerou jídlo. Každý had může prolézt sám sebou, ale nesmí narazit do jiného hada, jinak chcípne a promění se v jídlo. Had může zrychlit, což ho zkracuje.

VlevoVpravoZrychlení
Hráč 1
Hráč 2ZXA
Hráč 3NMB

Hadi jsou tvořeni jednotlivými body, což může vést k trhanosti v pozdější fázi hry, kdy jsou hadi dlouzí. Při programování jsem musel oprášit velice pokročilou matematiku (goniometrické funkce):

snake.x += Math.cos(snake.angle / 180 * Math.PI) * snake.speed;
snake.y += Math.sin(snake.angle / 180 * Math.PI) * snake.speed;

ukázka ze hryMotokáry

Hra pro dva kráče. Po trati jezdí motokára. Když narazí do svodidel, tak zastaví. Vzájemně sebou motokáry můžou projíždět, aby se hráči neblokovali. Jde o to zajet nejrychlejší kolo.

Na čtverečkovaný papír jsem nakreslil trať, kterou jsem pak ručně přeťukal do kódu. Funkce arcTo, která se k tomu především používá, má dost nepříjemné API – přijímá bod, ke kterému má vyrazit rovná čára a druhý bod, ke kterému má čára zatočit. Obrázek v dokumentaci to hezky znázorňuje – ani jeden z bodů přijímaných funkcí na výsledné čáře není. Mnohem intuitivnější by bylo API, které by přijímalo cílový bod a poloměr křivky. Trať jsem kreslil pomocí API proto, že jsem si myslel, že křivky následně využiji pro detekci kolizí. Tu jsem ale nakonec vyřešil pomocí barvy bodů, takže jsem trať mohl hře předat i formou obrázku.

VlevoVpravoZrychleníBrzda/couvání
Hráč 1
Hráč 2ZCSX

Hra kontroluje, jestli motokára projela checkpointem v polovině trati, ale jinak lze trať projet oběma směry. Rychlost motokáry je pečlivě nastavena tak, aby se celá trať dala projet na plný plyn. Detekce kolizí: ctx.getImageData(x, y, 1, 1).data[0] != 255.


Monopoly

Viz samostatný článek.


ukázka ze hryVrchcáby

Hra pro jednoho a více hráčů. Cílem je na tři pokusy hodit co nejvíc bodů v každé kombinaci. Vybranou kombinaci musí hráč nahlásit před posledním hodem.

U her (stejně jako u jakýchkoliv aplikací) je výzva navrhnout rozraní tak, aby se dobře používalo a pokud možno bylo snadno pochopitelné bez nějakých návodů. Při hraní na stole kostky, se kterými chci házet, prostě seberu. Jak to ale vyjádřím na obrazovce? Nejspíš tím, že na kostku kliknu. Znamená ale kliknutí to, že s ní chci házet, nebo naopak, že ji chci na stole nechat? Jak to znázornit? Jak uživateli říct, že si musí před posledním hodem vybrat kombinaci? Jistě by to šlo udělat nějakými nápovědami, které by si uživatel mohl později vypnout. Já jsem zvolil cestu pokusu a omylu – když uživatel udělá něco špatně, tak mu to hra řekne a příště už to snad nesplete. Časem si třeba taky všimne, že vybrání kombinace automaticky vybere kostky, se kterými se má házet. Tato pomůcka mimochodem zabírá přes polovinu kódu programu, protože se snaží napodobit skutečné uvažování při hře.

Také bylo potřeba vyřešit situaci, kdy uživatel už znovu házet nechce. Třeba druhým hodem hodil ⚅⚅⚅⚄⚄, skoro nejlepší možné 3+2. Jak mu dát možnost, aby už nemusel házet znovu? Přidat další tlačítko – jedno pro házení znovu, druhé pro ukončení kola? Raději jsem to vyřešil tak, že když nevybere žádnou kostku a má už vybranou kombinaci, tak se mu současný výsledek jednoduše zapíše. Vzhledem k tomu, že při vybrané kombinaci se automaticky vybírají kostky, se kterými se bude házet znovu, to funguje skvěle a v rozhraní je o tlačítko míň, na které uživatel nemůže omylem kliknout.

Jakub Vrána, Výuka, 24.10.2016, diskuse: 2 (nové: 0)

Diskuse

:-):

Zajímávé, spíš mi ale přijde, že jste si chtěl hrát Vy (zabavit se programováním). Protože např. člověče nezlob se to je příšerně unfriendly, to nemůže nikoho bavit.

ikona Jakub Vrána OpenID:

Zrovna u Člověče mi děti s programováním pomáhaly. A i u hry jsme se pak bavili náramně. Někdy prostě jídlo, které si člověk sám uvaří, chutná líp.

Vložit komentář

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

avatar © 2005-2019 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.