Nakresli mi hada

Většina videoher má celý herní svět uložený jako spoustu čísel, textů, seznamů a jiných datových objektů, které popisují všechno, co ve hře je. Tenhle stav se časem mění, ať už automaticky nebo podle akcí hráče. A docela často – většinou zhruba šedesátkrát za vteřinu – se stav hry převede na obrázek, který se hráčovi ukáže.

Abys mohla zobrazit hada, budeš napřed muset definovat stav hry – zadat to, co se má vykreslovat.

Zkus se zamyslet, co všechno bude ten stav obsahovat: co všechno si počítač musí o hře „pamatovat“, aby mohl aktuální stav zobrazit?

Bude potřebovat například aktuální polohu všech částí hada: kde má začátek? Kroutí se doprava nebo doleva? Jak je dlouhý? Naopak barvu hada ve stavu uložit nepotřebuješ – každý had v téhle hře bude stejný.

Napadne tě, jak polohu hada zapsat pomocí čísel, seznamů a dalších základních datových typů?

Reprezentace hada

Asi nejjednodušší způsob, jak si v počítači „zapamatovat“ herního hada, je pomocí seznamu souřadnic.

Pamatuješ si ze školy na kartézské souřadnice? To je taková ta část matematiky, co možná vypadala že nemá praktické využití. Pro počítačovou grafiku jsou ale souřadnice to co pro češtinu písmenka. Pojďme si je osvěžit.

Každý bod v rovině (třeba na obrazovce!) je možné popsat dvěmi čísly: x-ovou a y-ovou souřadnicí. Ta x-ová říká, jak moc vlevo je bod od nějakého počátku, ta y-ová udává jak moc je nahoře. My za onen „počátek“ zvolíme roh okýnka, ve kterém se bude náš had plazit.

Na rozdíl od školní geometrie se had bude plazit po čtverečkové mřížce. Je to jako na šachovnici – když jde pěšec na D5, D značí, jak moc je to políčko vlevo od okraje a 5 jak moc „nahoře“.

Tady je had, který začíná na souřadnicích (1, 2) a hlavu má na (4, 5):

Had na „šachovnici“ se souřadnicemi

Možná si všimneš, že matematický zápis souřadnic – (1, 2) – odpovídá způsobu, jak se v Pythonu píšou n-tice. To není náhoda! Dvojice čísel je perfektní způsob, jak uložit souřadnice kousku hada.

Had má ale kousků víc, a jinak dlouzí hadi jich budou mít různý počet. Na to je dobré použít seznam. Seznam souřadnic. A protože souřadnice pro nás budou dvojice čísel, seznam souřadnic bude seznam dvojic čísel.

Had z obrázku výše bude v Pythonu vypadat takto:

snake = [(1, 2), (2, 2), (3, 2), (3, 3), (3, 4), (3, 5), (4, 5)]

Tohle je reprezentace hada – to, co je z hlediska hry potřeba o konkrétním hadovi vědět.

Počítačům (a programátorům?) to takhle stačí. My si to ale zkusme zobrazit barevně, ať hadovi rozumí i hráč naší budoucí hry.

Angličtina

Teď, když děláme profesionální software, zkusíme začít používat pro jména proměnných, funkcí a podobně univerzálnější jazyk než je čeština. Moje proměnná se jmenuje snake místo had.

Logické a zobrazovací souřadnice

U vykreslování hada musíme vyřešit jeden základní problém: převod logických souřadnic na souřadnice obrazovky.

Displeje počítačů fungují podobně jako naše souřadnicová „šachovnice“: jsou to čtvercové mřížky plné políček. Každému políčku – pixelu – lze nastavit barvu. Hlavní rozdíl proti šachovnici je v tom, že pixelů na obrazovce je mnohem, mnohem víc.

Kdyby byl každý „herní“ čtvereček 10×10 pixelů velký, tak hlava hada z ukázky, která má „herní“ souřadnice (4, 5), se na obrazovku bude vykreslovat na čtverečku, který začíná na (40, 50):

Had na „šachovnici“ se souřadnicemi obrazovky

A ocas s „herními“ (logickými) souřadnicemi (1, 2) se vykreslí na čtvereček se souřadnicemi (10, 20).

Sázení čtverečku

Na to, abychom hada vykreslili, použijeme okýnko z Pygletu. Tady je základní kostra Pygletí aplikace, které už bys měla rozumět:

import pyglet

window = pyglet.window.Window()

@window.event
def on_draw():
    window.clear()

pyglet.app.run()

V editoru si otevři nový soubor, ulož ho jako had.py a kostru programu do něj zkopíruj. Budeme ji dál rozvíjet.

Stáhni si soubor green.png – zelený čtvereček – a dej ho do adresáře, kam píšeš kód.

Pod import pyglet přidej řádek, který tento obrázek načte.

green_image = pyglet.image.load('green.png')

Potom zkus dovnitř do funkce on_draw přidat vykreslení obrázku na souřadnice (40, 50), velikosti 10.

    green_image.blit(40, 50, width=10, height=10)

Program spusť (cd do nového adresáře; python had.py). Funguje? (Je docela důležité, aby fungoval – nevidíš-li zelený čtvereček, nečti dál a program radši oprav.)

Jak vidíš, čtvereček je docela malý. Budeme radši používat čtverečky větší, řekněme 64 pixelů.

To číslo je „střelené od boku“. V programu ho použijeme několikrát, a možná ho později budeš chtít upravit. Uložíme si ho proto do konstanty (proměnné, kterou nebudeme měnit). Konstanty se tradičně pojmenovávají velkými písmeny a píšou se hned za řádek import (i když to není technicky nutné). Přidej tedy za import řádek:

TILE_SIZE = 64

… a ve volání green.blit velikost čtverečku zohledni:

    green_image.blit(4 * TILE_SIZE, 5 * TILE_SIZE,
                     width=TILE_SIZE, height=TILE_SIZE)

Povedlo se? Máš čtvereček? Jestli ne, zkus si program celý, řádek po řádce, projít a zkontrolovat. Nebo ho porovnej se vzorovým řešením (což je rychlejší varianta, ale míň se naučíš).

Řešení

Sázení hada

Zkus teď na začátek programu – těsně pod import a konstantu – přidat definici hada:

snake = [(1, 2), (2, 2), (3, 2), (3, 3), (3, 4), (3, 5), (4, 5)]

A ve funkci draw vykresli všechny čtverečky hada. Vzpomeň si, že seznam dvojic můžeš „projít“ pomocí cyklu for a „rozbalení“ n-tice:

for x, y in snake:
    ...

Zvládneš to? Ve výsledku by měl být vidět – aspoň zhruba – had poskládaný ze čtverečků.

Had na „šachovnici“ a ukázka programu

Jestli to nefunguje, nezoufej, zkontroluj si to znovu, poptej se na radu. Ukázkové řešení využij až jako krajní možnost, jak pokračovat dál. Anebo pro kontrolu!

Řešení

Krmení

Aby bylo ve hře co dělat, budeme potřebovat pro hada krmení. Stáhni si do adresáře s projektem obrázek apple.png a zkus vykreslit jablíčka na následující souřadnice:

food = [(2, 0), (5, 1), (1, 4)]

Řešení

Možná si všimneš, že obrázek má ve hře trošičku „zubaté“ hrany. To je dáno způsobem, jakým v Pygletu vykreslujeme. Úplné vysvětlení by se do tohoto návodu nevešlo, potřebuje trochu hlubší znalosti počítačové grafiky. Proto uvedu jen řešení. Do funkce on_draw, hned za clear, dej následující tři řádky:

    # Lepší vykreslování (pro nás zatím kouzelné zaříkadlo)
    pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
    pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)

Načítání kousků hada

Teď, když umíš kreslit hada ze čtverců, zkusíme ho udělat hezčího. Stáhni si archiv snake-tiles.zip a rozbal si ho tak, aby adresář snake-tiles s obrázky byl na stejné úrovni jako program s hrou. Struktura adresáře by měla vypadat takhle:

Adresářová struktura

V archivuje spousta „kousků“ hada, které můžeme vykreslovat místo zelených čtverečků. Kousky vypadají následovně. Všimni si pojmenování – každý kousek hada buď spojuje dvě strany obrázku, nebo stranu obrázku s hlavou či ocasem. Obrázek se jmenuje odkud-kam.png.

Kousky hada

Co jsou taková ta divná „hadí vajíčka”? To je pro případ, že by had byl jen jedno políčko dlouhý – a tedy měl hlavu i ocas na stejném políčku. V dodělané hře se do takového stavu nedostaneme (had bude začínat s délkou 2), ale než hru dokončíme, budou tyhle obrázky užitečné.

Pojďme si teď tyhle obrázky načíst. Šlo by to dělat postupně, třeba takhle:

bottom_left = pyglet.image.load('snake-tiles/bottom-left.png')
bottom_right = pyglet.image.load('snake-tiles/bottom-right.png')
bottom_top = pyglet.image.load('snake-tiles/bottom-top.png')
...

Ale obrázků je spousta, tímhle způsobem by to bylo zdlouhavé a nejspíš bys na některý zapomněla.

Proto si obrázky načteme automaticky, v cyklu, a dáme je do slovníku.

Program bude vypadat takhle:

  • Začni s prázdným slovníkem.
  • Pro každý začátek (bottom, end, left, right, top):
    • Pro každý konec (bottom, end, left, right, top, dead, tongue):
      • Budeme načítat obrázek „začátek-konec“; tento klíč si dej do proměnné
      • Načti obrázek klíč.png
      • Ulož obrázek do slovníku pod klíč.
snake_tiles = {}
for start in ['bottom', 'end', 'left', 'right', 'top']:
    for end in ['bottom', 'end', 'left', 'right', 'top', 'dead', 'tongue']:
        key = start + '-' + end
        image = pyglet.image.load('snake-tiles/' + key + '.png')
        snake_tiles[key] = image

Pak celý slovník vypiš. Výpis bude vypadat dost nepřehledně, ale třeba v něm poznáš slovník – {klíč: hodnota, klíč: hodnota, ...}:

{'right-tongue': <ImageData 64x64>, 'top-tongue': <ImageData 64x64>,
 'right-top': <ImageData 64x64>, 'left-bottom': <ImageData 64x64>,
 'end-left': <ImageData 64x64>, 'bottom-tongue': <ImageData 64x64>,
 'left-top': <ImageData 64x64>, 'bottom-bottom': <ImageData 64x64>,
 ...

Housenka

A teď zkus načtení obrázků začlenit do programu s hadem!

Všechny importy patří nahoru, konstanty pod ně, a dál pak zbytek kódu. Vypisovat načtený slovník ve hře nemusíš. Zato ve vykreslovací funkci použij místo green_image třeba snake_tiles['end-end'].

Místo čtverečků se teď objeví kuličky – místo hada budeš mít „housenku“.

Housenka

Řešení

Jak vybrat čtverečky?

Místo toho, aby byl všude stejný kousek hada, budeme chtít vybrat vždycky ten správný.

Jak na to? Podle čeho ho vybrat?

Obrázky s kousky hada jsou pojmenovány odkud-kam.png. To není náhoda – ukazuje to, co potřebuješ vědět, abys mohla ten správný kousek vybrat.

Když máš hada podle následujícího obrázku, na políčko (3, 2) patří kousek, na kterém had „leze“ zleva nahoru – tedy left-top.png

Had na „šachovnici“ se souřadnicemi. Políčko (3, 2) je zvýrazněné a vedou z něj šipky doleva a nahoru, kudy had pokračuje.

Pro každé z políček budeš potřebovat zjistit, odkud a kam na něm had leze – tedy směr k předchozí a následující souřadnici.

Potřebuješ pro každé políčko hada zjistit

  • x-ovou a y-ovou souřadnici políčka
  • směr k předchozímu a následujícímu políčku

Do programu se pak dají hodnoty zadat nějak takto:

    for ... in ...:   # čím bude cyklus procházet? Samotným self.snake?
        x = ...
        y = ...
        before = ...  # Směr k předchozímu políčku ('left' nebo 'top' nebo ...)
        after = ...   # Směr k následujícímu políčku 

        snake_tiles[before + '-' + after].blit(
            x * TILE_SIZE, y * TILE_SIZE, width=TILE_SIZE, height=TILE_SIZE)

Toto je těžký úkol. I když všechny potřebné informace a nástroje k tomu teď teoreticky znáš, je potřeba je správným způsobem poskládat dohromady. Tohle skládání dohromady, návrh algoritmů, je nejsložitější programátorská disciplína.

Zkus nad tím ale přemýšlet, nech si to rozležet v hlavě třeba přes noc, vrať se k materiálům k předchozím lekcím (hlavně k úvodu do Pythonu), zkoušej a objevuj… A časem na to přijdeš. Odměnou za vyřešení ti bude had místo housenky.

Než na to přijdeš, zbytek programu ti neuteče. Housenka je úplně stejně hratelná jako had, jen jinak vypadá. Klidně přejdi na psaní logiky hry s housenkou.

Nebo se necháš poddat?

{
  "data": {
    "sessionMaterial": {
      "id": "session-material:2019/brno-podzim-snake:workshop:2",
      "title": "Kreslení hada",
      "html": "\n          \n    \n\n    <h1>Nakresli mi hada</h1>\n<p>V&#x11B;t&#x161;ina videoher m&#xE1; cel&#xFD; hern&#xED; sv&#x11B;t ulo&#x17E;en&#xFD; jako spoustu &#x10D;&#xED;sel, text&#x16F;, seznam&#x16F;\na jin&#xFD;ch datov&#xFD;ch objekt&#x16F;, kter&#xE9; popisuj&#xED; v&#x161;echno, co ve h&#x159;e je.\nTenhle stav se &#x10D;asem m&#x11B;n&#xED;, a&#x165; u&#x17E; automaticky nebo podle akc&#xED; hr&#xE1;&#x10D;e.\nA docela &#x10D;asto &#x2013; v&#x11B;t&#x161;inou zhruba &#x161;edes&#xE1;tkr&#xE1;t za vte&#x159;inu &#x2013; se stav hry p&#x159;evede\nna obr&#xE1;zek, kter&#xFD; se hr&#xE1;&#x10D;ovi uk&#xE1;&#x17E;e.</p>\n<p>Abys mohla zobrazit hada, bude&#x161; nap&#x159;ed muset definovat stav hry &#x2013; zadat\nto, co se m&#xE1; vykreslovat.</p>\n<p>Zkus se zamyslet, co v&#x161;echno bude ten stav obsahovat: co v&#x161;echno si po&#x10D;&#xED;ta&#x10D;\nmus&#xED; o h&#x159;e &#x201E;pamatovat&#x201C;, aby mohl aktu&#xE1;ln&#xED; stav zobrazit?</p>\n<p>Bude pot&#x159;ebovat nap&#x159;&#xED;klad aktu&#xE1;ln&#xED; polohu v&#x161;ech &#x10D;&#xE1;st&#xED; hada: kde m&#xE1; za&#x10D;&#xE1;tek?\nKrout&#xED; se doprava nebo doleva? Jak je dlouh&#xFD;?\nNaopak barvu hada ve stavu ulo&#x17E;it nepot&#x159;ebuje&#x161; &#x2013; ka&#x17E;d&#xFD; had v&#xA0;t&#xE9;hle h&#x159;e bude\nstejn&#xFD;.</p>\n<p>Napadne t&#x11B;, jak polohu hada zapsat pomoc&#xED; &#x10D;&#xED;sel, seznam&#x16F; a dal&#x161;&#xED;ch z&#xE1;kladn&#xED;ch\ndatov&#xFD;ch typ&#x16F;?</p>\n<h2>Reprezentace hada</h2>\n<p>Asi nejjednodu&#x161;&#x161;&#xED; zp&#x16F;sob, jak si v&#xA0;po&#x10D;&#xED;ta&#x10D;i &#x201E;zapamatovat&#x201C; hern&#xED;ho hada,\nje pomoc&#xED; seznamu sou&#x159;adnic.</p>\n<p>Pamatuje&#x161; si ze &#x161;koly na kart&#xE9;zsk&#xE9; sou&#x159;adnice?\nTo je takov&#xE1; ta &#x10D;&#xE1;st matematiky, co mo&#x17E;n&#xE1; vypadala &#x17E;e nem&#xE1; praktick&#xE9; vyu&#x17E;it&#xED;.\nPro po&#x10D;&#xED;ta&#x10D;ovou grafiku jsou ale sou&#x159;adnice to co pro &#x10D;e&#x161;tinu p&#xED;smenka.\nPoj&#x10F;me si je osv&#x11B;&#x17E;it.</p>\n<p>Ka&#x17E;d&#xFD; bod v&#xA0;rovin&#x11B; (t&#x159;eba na obrazovce!)\nje mo&#x17E;n&#xE9; popsat dv&#x11B;mi &#x10D;&#xED;sly: <var>x</var>-ovou a <var>y</var>-ovou sou&#x159;adnic&#xED;.\nTa <var>x</var>-ov&#xE1; &#x159;&#xED;k&#xE1;, jak moc vlevo je bod od n&#x11B;jak&#xE9;ho po&#x10D;&#xE1;tku,\nta <var>y</var>-ov&#xE1; ud&#xE1;v&#xE1; jak moc je naho&#x159;e.\nMy za onen &#x201E;po&#x10D;&#xE1;tek&#x201C; zvol&#xED;me roh ok&#xFD;nka, ve kter&#xE9;m se bude n&#xE1;&#x161; had plazit.</p>\n<p>Na rozd&#xED;l od &#x161;koln&#xED; geometrie se had bude plazit po &#x10D;tvere&#x10D;kov&#xE9; m&#x159;&#xED;&#x17E;ce.\nJe to jako na &#x161;achovnici &#x2013; kdy&#x17E; jde p&#x11B;&#x161;ec na D5, D zna&#x10D;&#xED;, jak moc je to\npol&#xED;&#x10D;ko vlevo od okraje a 5 jak moc &#x201E;naho&#x159;e&#x201C;.</p>\n<p>Tady je had, kter&#xFD; za&#x10D;&#xED;n&#xE1; na sou&#x159;adnic&#xED;ch (1, 2) a hlavu m&#xE1; na (4, 5):</p>\n<p><span class=\"figure\"><a href=\"/2019/brno-podzim-snake/snake/drawing/static/coords.svg\"><img src=\"/2019/brno-podzim-snake/snake/drawing/static/coords.svg\" alt=\"Had na &#x201E;&#x161;achovnici&#x201C; se sou&#x159;adnicemi\"></a></span></p>\n<p>Mo&#x17E;n&#xE1; si v&#x161;imne&#x161;, &#x17E;e matematick&#xFD; z&#xE1;pis sou&#x159;adnic &#x2013; (1, 2) &#x2013; odpov&#xED;d&#xE1;\nzp&#x16F;sobu, jak se v&#xA0;Pythonu p&#xED;&#x161;ou <var>n</var>-tice.\nTo nen&#xED; n&#xE1;hoda!\nDvojice &#x10D;&#xED;sel je perfektn&#xED; zp&#x16F;sob, jak ulo&#x17E;it sou&#x159;adnice kousku hada.</p>\n<p>Had m&#xE1; ale kousk&#x16F; v&#xED;c, a jinak dlouz&#xED; hadi jich budou m&#xED;t r&#x16F;zn&#xFD; po&#x10D;et.\nNa to je dobr&#xE9; pou&#x17E;&#xED;t seznam. Seznam sou&#x159;adnic.\nA proto&#x17E;e sou&#x159;adnice pro n&#xE1;s budou dvojice &#x10D;&#xED;sel,\nseznam sou&#x159;adnic bude seznam dvojic &#x10D;&#xED;sel.</p>\n<p>Had z&#xA0;obr&#xE1;zku v&#xFD;&#x161;e bude v&#xA0;Pythonu vypadat takto:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">snake</span> <span class=\"o\">=</span> <span class=\"p\">[(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">)]</span>\n</pre></div><p>Tohle je reprezentace hada &#x2013; to, co je z&#xA0;hlediska hry pot&#x159;eba o konkr&#xE9;tn&#xED;m\nhadovi v&#x11B;d&#x11B;t.</p>\n<p>Po&#x10D;&#xED;ta&#x10D;&#x16F;m (a program&#xE1;tor&#x16F;m?) to takhle sta&#x10D;&#xED;.\nMy si to ale zkusme zobrazit barevn&#x11B;, a&#x165; hadovi rozum&#xED; i hr&#xE1;&#x10D; na&#x161;&#xED; budouc&#xED; hry.</p>\n<div class=\"admonition note\"><p class=\"admonition-title\">Angli&#x10D;tina</p>\n<p>Te&#x10F;, kdy&#x17E; d&#x11B;l&#xE1;me profesion&#xE1;ln&#xED; software, zkus&#xED;me za&#x10D;&#xED;t pou&#x17E;&#xED;vat pro\njm&#xE9;na prom&#x11B;nn&#xFD;ch, funkc&#xED; a podobn&#x11B; univerz&#xE1;ln&#x11B;j&#x161;&#xED; jazyk ne&#x17E; je &#x10D;e&#x161;tina.\nMoje prom&#x11B;nn&#xE1; se jmenuje <code>snake</code> m&#xED;sto <code>had</code>.</p>\n</div><h2>Logick&#xE9; a zobrazovac&#xED; sou&#x159;adnice</h2>\n<p>U vykreslov&#xE1;n&#xED; hada mus&#xED;me vy&#x159;e&#x161;it jeden z&#xE1;kladn&#xED; probl&#xE9;m:\np&#x159;evod <em>logick&#xFD;ch sou&#x159;adnic</em> na sou&#x159;adnice <em>obrazovky</em>.</p>\n<p>Displeje po&#x10D;&#xED;ta&#x10D;&#x16F; funguj&#xED; podobn&#x11B; jako na&#x161;e sou&#x159;adnicov&#xE1; &#x201E;&#x161;achovnice&#x201C;:\njsou to &#x10D;tvercov&#xE9; m&#x159;&#xED;&#x17E;ky pln&#xE9; pol&#xED;&#x10D;ek.\nKa&#x17E;d&#xE9;mu pol&#xED;&#x10D;ku &#x2013; <em>pixelu</em> &#x2013; lze nastavit barvu.\nHlavn&#xED; rozd&#xED;l proti &#x161;achovnici je v&#xA0;tom, &#x17E;e pixel&#x16F; na obrazovce je mnohem,\nmnohem v&#xED;c.</p>\n<p>Kdyby byl ka&#x17E;d&#xFD; &#x201E;hern&#xED;&#x201C; &#x10D;tvere&#x10D;ek 10&#xD7;10 pixel&#x16F; velk&#xFD;,\ntak hlava hada z uk&#xE1;zky, kter&#xE1; m&#xE1; &#x201E;hern&#xED;&#x201C; sou&#x159;adnice (4, 5),\nse na obrazovku bude vykreslovat na &#x10D;tvere&#x10D;ku, kter&#xFD; za&#x10D;&#xED;n&#xE1; na (40, 50):</p>\n<p><span class=\"figure\"><a href=\"/2019/brno-podzim-snake/snake/drawing/static/coords-px.svg\"><img src=\"/2019/brno-podzim-snake/snake/drawing/static/coords-px.svg\" alt=\"Had na &#x201E;&#x161;achovnici&#x201C; se sou&#x159;adnicemi obrazovky\"></a></span></p>\n<p>A ocas s &#x201E;hern&#xED;mi&#x201C; (<em>logick&#xFD;mi</em>) sou&#x159;adnicemi (1, 2) se vykresl&#xED; na &#x10D;tvere&#x10D;ek\nse sou&#x159;adnicemi (10, 20).</p>\n<h2>S&#xE1;zen&#xED; &#x10D;tvere&#x10D;ku</h2>\n<p>Na to, abychom hada vykreslili, pou&#x17E;ijeme ok&#xFD;nko z&#xA0;Pygletu.\nTady je z&#xE1;kladn&#xED; kostra Pyglet&#xED; aplikace, kter&#xE9; u&#x17E; bys m&#x11B;la rozum&#x11B;t:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">pyglet</span>\n\n<span class=\"n\">window</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">window</span><span class=\"o\">.</span><span class=\"n\">Window</span><span class=\"p\">()</span>\n\n<span class=\"nd\">@window.event</span>\n<span class=\"k\">def</span> <span class=\"nf\">on_draw</span><span class=\"p\">():</span>\n    <span class=\"n\">window</span><span class=\"o\">.</span><span class=\"n\">clear</span><span class=\"p\">()</span>\n\n<span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">app</span><span class=\"o\">.</span><span class=\"n\">run</span><span class=\"p\">()</span>\n</pre></div><p>V&#xA0;editoru si otev&#x159;i nov&#xFD; soubor, ulo&#x17E; ho jako <code>had.py</code> a kostru programu\ndo n&#x11B;j zkop&#xED;ruj.\nBudeme ji d&#xE1;l rozv&#xED;jet.</p>\n<p><img src=\"/2019/brno-podzim-snake/snake/drawing/static/green.png\" alt style=\"display:block; float:right; margin: 2px; border: 1px solid #ccc; border-radius: 1px;\">\nSt&#xE1;hni si soubor <a href=\"/2019/brno-podzim-snake/snake/drawing/static/green.png\">green.png</a> &#x2013; zelen&#xFD; &#x10D;tvere&#x10D;ek &#x2013;\na dej ho do adres&#xE1;&#x159;e, kam p&#xED;&#x161;e&#x161; k&#xF3;d.</p>\n<p>Pod <code>import pyglet</code> p&#x159;idej &#x159;&#xE1;dek, kter&#xFD; tento obr&#xE1;zek na&#x10D;te.</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">green_image</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">image</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"s1\">&apos;green.png&apos;</span><span class=\"p\">)</span>\n</pre></div><p>Potom zkus dovnit&#x159; do funkce <code>on_draw</code> p&#x159;idat vykreslen&#xED; obr&#xE1;zku na sou&#x159;adnice\n(40, 50), velikosti 10.</p>\n<div class=\"highlight\"><pre><span></span>    <span class=\"n\">green_image</span><span class=\"o\">.</span><span class=\"n\">blit</span><span class=\"p\">(</span><span class=\"mi\">40</span><span class=\"p\">,</span> <span class=\"mi\">50</span><span class=\"p\">,</span> <span class=\"n\">width</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">,</span> <span class=\"n\">height</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n</pre></div><p>Program spus&#x165; (<code>cd</code> do nov&#xE9;ho adres&#xE1;&#x159;e; <code>python had.py</code>). Funguje?\n(Je docela d&#x16F;le&#x17E;it&#xE9;, aby fungoval &#x2013; nevid&#xED;&#x161;-li zelen&#xFD; &#x10D;tvere&#x10D;ek,\nne&#x10D;ti d&#xE1;l a program rad&#x161;i oprav.)</p>\n<p>Jak vid&#xED;&#x161;, &#x10D;tvere&#x10D;ek je docela mal&#xFD;.\nBudeme rad&#x161;i pou&#x17E;&#xED;vat &#x10D;tvere&#x10D;ky v&#x11B;t&#x161;&#xED;, &#x159;ekn&#x11B;me 64 pixel&#x16F;.</p>\n<p>To &#x10D;&#xED;slo je &#x201E;st&#x159;elen&#xE9; od boku&#x201C;.\nV&#xA0;programu ho pou&#x17E;ijeme n&#x11B;kolikr&#xE1;t, a mo&#x17E;n&#xE1; ho pozd&#x11B;ji bude&#x161; cht&#xED;t upravit.\nUlo&#x17E;&#xED;me si ho proto do <em>konstanty</em> (prom&#x11B;nn&#xE9;, kterou nebudeme m&#x11B;nit).\nKonstanty se tradi&#x10D;n&#x11B; pojmenov&#xE1;vaj&#xED; velk&#xFD;mi p&#xED;smeny a p&#xED;&#x161;ou se hned za &#x159;&#xE1;dek\n<code>import</code> (i kdy&#x17E; to nen&#xED; technicky nutn&#xE9;).\nP&#x159;idej tedy za <code>import</code> &#x159;&#xE1;dek:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">TILE_SIZE</span> <span class=\"o\">=</span> <span class=\"mi\">64</span>\n</pre></div><p>&#x2026; a ve vol&#xE1;n&#xED; <code>green.blit</code> velikost &#x10D;tvere&#x10D;ku zohledni:</p>\n<div class=\"highlight\"><pre><span></span>    <span class=\"n\">green_image</span><span class=\"o\">.</span><span class=\"n\">blit</span><span class=\"p\">(</span><span class=\"mi\">4</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"mi\">5</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span>\n                     <span class=\"n\">width</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">height</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">)</span>\n</pre></div><p>Povedlo se? M&#xE1;&#x161; &#x10D;tvere&#x10D;ek?\nJestli ne, zkus si program cel&#xFD;, &#x159;&#xE1;dek po &#x159;&#xE1;dce, proj&#xED;t a zkontrolovat.\nNebo ho porovnej se vzorov&#xFD;m &#x159;e&#x161;en&#xED;m (co&#x17E; je rychlej&#x161;&#xED; varianta, ale m&#xED;&#x148;\nse nau&#x10D;&#xED;&#x161;).</p>\n<div class=\"solution\" id=\"solution-0\">\n    <h3>&#x158;e&#x161;en&#xED;</h3>\n    <div class=\"solution-cover\">\n        <a href=\"/2019/brno-podzim-snake/snake/drawing/index/solutions/0/\"><span class=\"link-text\">Uk&#xE1;zat &#x159;e&#x161;en&#xED;</span></a>\n    </div>\n    <div class=\"solution-body\" aria-hidden=\"true\">\n        <div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">pyglet</span>\n\n<span class=\"n\">TILE_SIZE</span> <span class=\"o\">=</span> <span class=\"mi\">64</span>\n<span class=\"n\">green_image</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">image</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"s1\">&apos;green.png&apos;</span><span class=\"p\">)</span>\n\n<span class=\"n\">window</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">window</span><span class=\"o\">.</span><span class=\"n\">Window</span><span class=\"p\">()</span>\n\n<span class=\"nd\">@window.event</span>\n<span class=\"k\">def</span> <span class=\"nf\">on_draw</span><span class=\"p\">():</span>\n    <span class=\"n\">window</span><span class=\"o\">.</span><span class=\"n\">clear</span><span class=\"p\">()</span>\n    <span class=\"n\">green_image</span><span class=\"o\">.</span><span class=\"n\">blit</span><span class=\"p\">(</span><span class=\"mi\">4</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"mi\">5</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span>\n                     <span class=\"n\">width</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">height</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">)</span>\n\n<span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">app</span><span class=\"o\">.</span><span class=\"n\">run</span><span class=\"p\">()</span>\n</pre></div>\n    </div>\n</div><h2>S&#xE1;zen&#xED; hada</h2>\n<p>Zkus te&#x10F; na za&#x10D;&#xE1;tek programu &#x2013; t&#x11B;sn&#x11B; pod <code>import</code> a konstantu &#x2013; p&#x159;idat\ndefinici hada:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">snake</span> <span class=\"o\">=</span> <span class=\"p\">[(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">)]</span>\n</pre></div><p>A ve funkci <code>draw</code> vykresli v&#x161;echny &#x10D;tvere&#x10D;ky hada.\nVzpome&#x148; si, &#x17E;e seznam dvojic m&#x16F;&#x17E;e&#x161; &#x201E;proj&#xED;t&#x201C; pomoc&#xED; cyklu <code>for</code> a &#x201E;rozbalen&#xED;&#x201C;\n<var>n</var>-tice:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"k\">for</span> <span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"n\">snake</span><span class=\"p\">:</span>\n    <span class=\"o\">...</span>\n</pre></div><p>Zvl&#xE1;dne&#x161; to?\nVe v&#xFD;sledku by m&#x11B;l b&#xFD;t vid&#x11B;t &#x2013; aspo&#x148; zhruba &#x2013; had poskl&#xE1;dan&#xFD; ze &#x10D;tvere&#x10D;k&#x16F;.</p>\n<p><span class=\"figure\"><a href=\"/2019/brno-podzim-snake/snake/drawing/static/coords-blocks.svg\"><img src=\"/2019/brno-podzim-snake/snake/drawing/static/coords-blocks.svg\" alt=\"Had na &#x201E;&#x161;achovnici&#x201C; a uk&#xE1;zka programu\"></a></span></p>\n<p>Jestli to nefunguje, nezoufej, zkontroluj si to znovu, poptej se na radu.\nUk&#xE1;zkov&#xE9; &#x159;e&#x161;en&#xED; vyu&#x17E;ij a&#x17E; jako krajn&#xED; mo&#x17E;nost, jak pokra&#x10D;ovat d&#xE1;l.\nAnebo pro kontrolu!</p>\n<div class=\"solution\" id=\"solution-1\">\n    <h3>&#x158;e&#x161;en&#xED;</h3>\n    <div class=\"solution-cover\">\n        <a href=\"/2019/brno-podzim-snake/snake/drawing/index/solutions/1/\"><span class=\"link-text\">Uk&#xE1;zat &#x159;e&#x161;en&#xED;</span></a>\n    </div>\n    <div class=\"solution-body\" aria-hidden=\"true\">\n        <div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">pyglet</span>\n\n<span class=\"n\">TILE_SIZE</span> <span class=\"o\">=</span> <span class=\"mi\">64</span>\n\n<span class=\"n\">snake</span> <span class=\"o\">=</span> <span class=\"p\">[(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">)]</span>\n\n<span class=\"n\">green_image</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">image</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"s1\">&apos;green.png&apos;</span><span class=\"p\">)</span>\n\n<span class=\"n\">window</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">window</span><span class=\"o\">.</span><span class=\"n\">Window</span><span class=\"p\">()</span>\n\n<span class=\"nd\">@window.event</span>\n<span class=\"k\">def</span> <span class=\"nf\">on_draw</span><span class=\"p\">():</span>\n    <span class=\"n\">window</span><span class=\"o\">.</span><span class=\"n\">clear</span><span class=\"p\">()</span>\n    <span class=\"k\">for</span> <span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"n\">snake</span><span class=\"p\">:</span>\n        <span class=\"n\">green_image</span><span class=\"o\">.</span><span class=\"n\">blit</span><span class=\"p\">(</span><span class=\"n\">x</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span>\n                         <span class=\"n\">width</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">height</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">)</span>\n\n<span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">app</span><span class=\"o\">.</span><span class=\"n\">run</span><span class=\"p\">()</span>\n</pre></div>\n    </div>\n</div><h2>Krmen&#xED;</h2>\n<p><img src=\"/2019/brno-podzim-snake/snake/drawing/static/apple.png\" alt style=\"display:block; float:right; margin: 2px; border: 1px solid #ccc; border-radius: 1px;\">\nAby bylo ve h&#x159;e co d&#x11B;lat, budeme pot&#x159;ebovat pro hada krmen&#xED;.\nSt&#xE1;hni si do adres&#xE1;&#x159;e s&#xA0;projektem obr&#xE1;zek\n<a href=\"/2019/brno-podzim-snake/snake/drawing/static/apple.png\">apple.png</a> a zkus vykreslit\njabl&#xED;&#x10D;ka na n&#xE1;sleduj&#xED;c&#xED; sou&#x159;adnice:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">food</span> <span class=\"o\">=</span> <span class=\"p\">[(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">)]</span>\n</pre></div><div class=\"solution\" id=\"solution-2\">\n    <h3>&#x158;e&#x161;en&#xED;</h3>\n    <div class=\"solution-cover\">\n        <a href=\"/2019/brno-podzim-snake/snake/drawing/index/solutions/2/\"><span class=\"link-text\">Uk&#xE1;zat &#x159;e&#x161;en&#xED;</span></a>\n    </div>\n    <div class=\"solution-body\" aria-hidden=\"true\">\n        <div class=\"highlight\"><pre><span></span><span class=\"kn\">import</span> <span class=\"nn\">pyglet</span>\n\n<span class=\"n\">TILE_SIZE</span> <span class=\"o\">=</span> <span class=\"mi\">64</span>\n\n<span class=\"n\">snake</span> <span class=\"o\">=</span> <span class=\"p\">[(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">)]</span>\n<span class=\"n\">food</span> <span class=\"o\">=</span> <span class=\"p\">[(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">)]</span>\n\n<span class=\"n\">red_image</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">image</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"s1\">&apos;apple.png&apos;</span><span class=\"p\">)</span>\n<span class=\"n\">green_image</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">image</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"s1\">&apos;green.png&apos;</span><span class=\"p\">)</span>\n\n<span class=\"n\">window</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">window</span><span class=\"o\">.</span><span class=\"n\">Window</span><span class=\"p\">()</span>\n\n<span class=\"nd\">@window.event</span>\n<span class=\"k\">def</span> <span class=\"nf\">on_draw</span><span class=\"p\">():</span>\n    <span class=\"n\">window</span><span class=\"o\">.</span><span class=\"n\">clear</span><span class=\"p\">()</span>\n    <span class=\"k\">for</span> <span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"n\">snake</span><span class=\"p\">:</span>\n        <span class=\"n\">green_image</span><span class=\"o\">.</span><span class=\"n\">blit</span><span class=\"p\">(</span><span class=\"n\">x</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span>\n                         <span class=\"n\">width</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">height</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">)</span>\n    <span class=\"k\">for</span> <span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"n\">food</span><span class=\"p\">:</span>\n        <span class=\"n\">red_image</span><span class=\"o\">.</span><span class=\"n\">blit</span><span class=\"p\">(</span><span class=\"n\">x</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span>\n                       <span class=\"n\">width</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">height</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">)</span>\n\n<span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">app</span><span class=\"o\">.</span><span class=\"n\">run</span><span class=\"p\">()</span>\n</pre></div>\n    </div>\n</div><p>Mo&#x17E;n&#xE1; si v&#x161;imne&#x161;, &#x17E;e obr&#xE1;zek m&#xE1; ve h&#x159;e tro&#x161;i&#x10D;ku &#x201E;zubat&#xE9;&#x201C; hrany.\nTo je d&#xE1;no zp&#x16F;sobem, jak&#xFD;m v&#xA0;Pygletu vykreslujeme.\n&#xDA;pln&#xE9; vysv&#x11B;tlen&#xED; by se do tohoto n&#xE1;vodu neve&#x161;lo, pot&#x159;ebuje trochu hlub&#x161;&#xED;\nznalosti po&#x10D;&#xED;ta&#x10D;ov&#xE9; grafiky.\nProto uvedu jen &#x159;e&#x161;en&#xED;.\nDo funkce <code>on_draw</code>, hned za <code>clear</code>, dej n&#xE1;sleduj&#xED;c&#xED; t&#x159;i &#x159;&#xE1;dky:</p>\n<div class=\"highlight\"><pre><span></span>    <span class=\"c1\"># Lep&#x161;&#xED; vykreslov&#xE1;n&#xED; (pro n&#xE1;s zat&#xED;m kouzeln&#xE9; za&#x159;&#xED;kadlo)</span>\n    <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">gl</span><span class=\"o\">.</span><span class=\"n\">glEnable</span><span class=\"p\">(</span><span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">gl</span><span class=\"o\">.</span><span class=\"n\">GL_BLEND</span><span class=\"p\">)</span>\n    <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">gl</span><span class=\"o\">.</span><span class=\"n\">glBlendFunc</span><span class=\"p\">(</span><span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">gl</span><span class=\"o\">.</span><span class=\"n\">GL_SRC_ALPHA</span><span class=\"p\">,</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">gl</span><span class=\"o\">.</span><span class=\"n\">GL_ONE_MINUS_SRC_ALPHA</span><span class=\"p\">)</span>\n</pre></div><h2>Na&#x10D;&#xED;t&#xE1;n&#xED; kousk&#x16F; hada</h2>\n<p>Te&#x10F;, kdy&#x17E; um&#xED;&#x161; kreslit hada ze &#x10D;tverc&#x16F;, zkus&#xED;me ho ud&#x11B;lat hez&#x10D;&#xED;ho.\nSt&#xE1;hni si archiv <a href=\"/2019/brno-podzim-snake/snake/drawing/static/snake-tiles.zip\">snake-tiles.zip</a>\na rozbal si ho tak, aby adres&#xE1;&#x159; <code>snake-tiles</code> s&#xA0;obr&#xE1;zky byl na stejn&#xE9; &#xFA;rovni\njako program s&#xA0;hrou.\nStruktura adres&#xE1;&#x159;e by m&#x11B;la vypadat takhle:</p>\n<p><span class=\"figure\"><a href=\"/2019/brno-podzim-snake/snake/drawing/static/screenshot-dir.png\"><img src=\"/2019/brno-podzim-snake/snake/drawing/static/screenshot-dir.png\" alt=\"Adres&#xE1;&#x159;ov&#xE1; struktura\"></a></span></p>\n<p>V&#xA0;archivuje spousta &#x201E;kousk&#x16F;&#x201C; hada, kter&#xE9; m&#x16F;&#x17E;eme vykreslovat m&#xED;sto zelen&#xFD;ch\n&#x10D;tvere&#x10D;k&#x16F;.\nKousky vypadaj&#xED; n&#xE1;sledovn&#x11B;.\nV&#x161;imni si pojmenov&#xE1;n&#xED; &#x2013; ka&#x17E;d&#xFD; kousek hada bu&#x10F; spojuje dv&#x11B; strany obr&#xE1;zku,\nnebo stranu obr&#xE1;zku s hlavou &#x10D;i ocasem.\nObr&#xE1;zek se jmenuje <var>odkud</var>-<var>kam</var>.png.</p>\n<p><span class=\"figure\"><a href=\"/2019/brno-podzim-snake/snake/drawing/static/snake-tiles.png\"><img src=\"/2019/brno-podzim-snake/snake/drawing/static/snake-tiles.png\" alt=\"Kousky hada\"></a></span></p>\n<div class=\"admonition note\"><p>Co jsou takov&#xE1; ta divn&#xE1; &#x201E;had&#xED; vaj&#xED;&#x10D;ka&#x201D;?\n<img src=\"/2019/brno-podzim-snake/snake/drawing/static/snake-tiles/end-end.png\" alt style=\"display:block; float:left; margin: 2px; border: 1px solid #ccc; border-radius: 1px;\">\nTo je pro p&#x159;&#xED;pad, &#x17E;e by had byl jen jedno pol&#xED;&#x10D;ko dlouh&#xFD; &#x2013; a tedy m&#x11B;l hlavu\ni ocas na stejn&#xE9;m pol&#xED;&#x10D;ku.\nV&#xA0;dod&#x11B;lan&#xE9; h&#x159;e se do takov&#xE9;ho stavu nedostaneme (had bude za&#x10D;&#xED;nat s&#xA0;d&#xE9;lkou 2),\nale ne&#x17E; hru dokon&#x10D;&#xED;me, budou tyhle obr&#xE1;zky u&#x17E;ite&#x10D;n&#xE9;.</p>\n</div><p>Poj&#x10F;me si te&#x10F; tyhle obr&#xE1;zky <em>na&#x10D;&#xED;st</em>.\n&#x160;lo by to d&#x11B;lat postupn&#x11B;, t&#x159;eba takhle:</p>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">bottom_left</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">image</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"s1\">&apos;snake-tiles/bottom-left.png&apos;</span><span class=\"p\">)</span>\n<span class=\"n\">bottom_right</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">image</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"s1\">&apos;snake-tiles/bottom-right.png&apos;</span><span class=\"p\">)</span>\n<span class=\"n\">bottom_top</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">image</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"s1\">&apos;snake-tiles/bottom-top.png&apos;</span><span class=\"p\">)</span>\n<span class=\"o\">...</span>\n</pre></div><p>Ale obr&#xE1;zk&#x16F; je spousta, t&#xED;mhle zp&#x16F;sobem by to bylo zdlouhav&#xE9; a nejsp&#xED;&#x161; bys\nna n&#x11B;kter&#xFD; zapomn&#x11B;la.</p>\n<p>Proto si obr&#xE1;zky na&#x10D;teme automaticky, v cyklu, a d&#xE1;me je do slovn&#xED;ku.</p>\n<p>Program bude vypadat takhle:</p>\n<ul>\n<li>Za&#x10D;ni s pr&#xE1;zdn&#xFD;m slovn&#xED;kem.</li>\n<li>Pro ka&#x17E;d&#xFD; <em>za&#x10D;&#xE1;tek</em> (<code>bottom</code>, <code>end</code>, <code>left</code>, <code>right</code>, <code>top</code>):<ul>\n<li>Pro ka&#x17E;d&#xFD; <em>konec</em> (<code>bottom</code>, <code>end</code>, <code>left</code>, <code>right</code>, <code>top</code>, <code>dead</code>, <code>tongue</code>):<ul>\n<li>Budeme na&#x10D;&#xED;tat obr&#xE1;zek &#x201E;<var>za&#x10D;&#xE1;tek</var>-<var>konec</var>&#x201C;; tento\n<var>kl&#xED;&#x10D;</var> si dej do prom&#x11B;nn&#xE9;</li>\n<li>Na&#x10D;ti obr&#xE1;zek <var>kl&#xED;&#x10D;</var>.png</li>\n<li>Ulo&#x17E; obr&#xE1;zek do slovn&#xED;ku pod <var>kl&#xED;&#x10D;</var>.</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<div class=\"highlight\"><pre><span></span><span class=\"n\">snake_tiles</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n<span class=\"k\">for</span> <span class=\"n\">start</span> <span class=\"ow\">in</span> <span class=\"p\">[</span><span class=\"s1\">&apos;bottom&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;end&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;left&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;right&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;top&apos;</span><span class=\"p\">]:</span>\n    <span class=\"k\">for</span> <span class=\"n\">end</span> <span class=\"ow\">in</span> <span class=\"p\">[</span><span class=\"s1\">&apos;bottom&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;end&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;left&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;right&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;top&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;dead&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;tongue&apos;</span><span class=\"p\">]:</span>\n        <span class=\"n\">key</span> <span class=\"o\">=</span> <span class=\"n\">start</span> <span class=\"o\">+</span> <span class=\"s1\">&apos;-&apos;</span> <span class=\"o\">+</span> <span class=\"n\">end</span>\n        <span class=\"n\">image</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">image</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"s1\">&apos;snake-tiles/&apos;</span> <span class=\"o\">+</span> <span class=\"n\">key</span> <span class=\"o\">+</span> <span class=\"s1\">&apos;.png&apos;</span><span class=\"p\">)</span>\n        <span class=\"n\">snake_tiles</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">image</span>\n</pre></div><p>Pak cel&#xFD; slovn&#xED;k vypi&#x161;.\nV&#xFD;pis bude vypadat dost nep&#x159;ehledn&#x11B;, ale t&#x159;eba v&#xA0;n&#x11B;m pozn&#xE1;&#x161; slovn&#xED;k &#x2013;\n<em>{kl&#xED;&#x10D;: hodnota, kl&#xED;&#x10D;: hodnota, ...}</em>:</p>\n<div class=\"highlight\"><pre><code>{&apos;right-tongue&apos;: &lt;ImageData 64x64&gt;, &apos;top-tongue&apos;: &lt;ImageData 64x64&gt;,\n &apos;right-top&apos;: &lt;ImageData 64x64&gt;, &apos;left-bottom&apos;: &lt;ImageData 64x64&gt;,\n &apos;end-left&apos;: &lt;ImageData 64x64&gt;, &apos;bottom-tongue&apos;: &lt;ImageData 64x64&gt;,\n &apos;left-top&apos;: &lt;ImageData 64x64&gt;, &apos;bottom-bottom&apos;: &lt;ImageData 64x64&gt;,\n ...</code></pre></div><h2>Housenka</h2>\n<p>A te&#x10F; zkus na&#x10D;ten&#xED; obr&#xE1;zk&#x16F; za&#x10D;lenit do programu s hadem!</p>\n<p>V&#x161;echny importy pat&#x159;&#xED; nahoru, konstanty pod n&#x11B;, a d&#xE1;l pak zbytek k&#xF3;du.\nVypisovat na&#x10D;ten&#xFD; slovn&#xED;k ve h&#x159;e nemus&#xED;&#x161;.\nZato ve vykreslovac&#xED; funkci pou&#x17E;ij m&#xED;sto <code>green_image</code>\nt&#x159;eba <code>snake_tiles[&apos;end-end&apos;]</code>.</p>\n<p>M&#xED;sto &#x10D;tvere&#x10D;k&#x16F; se te&#x10F; objev&#xED; kuli&#x10D;ky &#x2013; m&#xED;sto hada bude&#x161; m&#xED;t &#x201E;housenku&#x201C;.</p>\n<p><span class=\"figure\"><a href=\"/2019/brno-podzim-snake/snake/drawing/static/caterpillar.png\"><img src=\"/2019/brno-podzim-snake/snake/drawing/static/caterpillar.png\" alt=\"Housenka\"></a></span></p>\n<div class=\"solution\" id=\"solution-3\">\n    <h3>&#x158;e&#x161;en&#xED;</h3>\n    <div class=\"solution-cover\">\n        <a href=\"/2019/brno-podzim-snake/snake/drawing/index/solutions/3/\"><span class=\"link-text\">Uk&#xE1;zat &#x159;e&#x161;en&#xED;</span></a>\n    </div>\n    <div class=\"solution-body\" aria-hidden=\"true\">\n        <div class=\"highlight\"><pre><span></span><span class=\"kn\">from</span> <span class=\"nn\">pathlib</span> <span class=\"kn\">import</span> <span class=\"n\">Path</span>\n\n<span class=\"kn\">import</span> <span class=\"nn\">pyglet</span>\n\n<span class=\"n\">TILE_SIZE</span> <span class=\"o\">=</span> <span class=\"mi\">64</span>\n<span class=\"n\">TILES_DIRECTORY</span> <span class=\"o\">=</span> <span class=\"n\">Path</span><span class=\"p\">(</span><span class=\"s1\">&apos;snake-tiles&apos;</span><span class=\"p\">)</span>\n\n<span class=\"n\">snake</span> <span class=\"o\">=</span> <span class=\"p\">[(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">3</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">3</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">4</span><span class=\"p\">,</span> <span class=\"mi\">5</span><span class=\"p\">)]</span>\n<span class=\"n\">food</span> <span class=\"o\">=</span> <span class=\"p\">[(</span><span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"mi\">0</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">5</span><span class=\"p\">,</span> <span class=\"mi\">1</span><span class=\"p\">),</span> <span class=\"p\">(</span><span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"mi\">4</span><span class=\"p\">)]</span>\n\n<span class=\"n\">red_image</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">image</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"s1\">&apos;apple.png&apos;</span><span class=\"p\">)</span>\n<span class=\"n\">snake_tiles</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n<span class=\"k\">for</span> <span class=\"n\">start</span> <span class=\"ow\">in</span> <span class=\"p\">[</span><span class=\"s1\">&apos;bottom&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;end&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;left&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;right&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;top&apos;</span><span class=\"p\">]:</span>\n    <span class=\"k\">for</span> <span class=\"n\">end</span> <span class=\"ow\">in</span> <span class=\"p\">[</span><span class=\"s1\">&apos;bottom&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;end&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;left&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;right&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;top&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;dead&apos;</span><span class=\"p\">,</span> <span class=\"s1\">&apos;tongue&apos;</span><span class=\"p\">]:</span>\n        <span class=\"n\">key</span> <span class=\"o\">=</span> <span class=\"n\">start</span> <span class=\"o\">+</span> <span class=\"s1\">&apos;-&apos;</span> <span class=\"o\">+</span> <span class=\"n\">end</span>\n        <span class=\"n\">image</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">image</span><span class=\"o\">.</span><span class=\"n\">load</span><span class=\"p\">(</span><span class=\"s1\">&apos;snake-tiles/&apos;</span> <span class=\"o\">+</span> <span class=\"n\">key</span> <span class=\"o\">+</span> <span class=\"s1\">&apos;.png&apos;</span><span class=\"p\">)</span>\n        <span class=\"n\">snake_tiles</span><span class=\"p\">[</span><span class=\"n\">key</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">image</span>\n\n<span class=\"n\">window</span> <span class=\"o\">=</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">window</span><span class=\"o\">.</span><span class=\"n\">Window</span><span class=\"p\">()</span>\n\n<span class=\"nd\">@window.event</span>\n<span class=\"k\">def</span> <span class=\"nf\">on_draw</span><span class=\"p\">():</span>\n    <span class=\"n\">window</span><span class=\"o\">.</span><span class=\"n\">clear</span><span class=\"p\">()</span>\n    <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">gl</span><span class=\"o\">.</span><span class=\"n\">glEnable</span><span class=\"p\">(</span><span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">gl</span><span class=\"o\">.</span><span class=\"n\">GL_BLEND</span><span class=\"p\">)</span>\n    <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">gl</span><span class=\"o\">.</span><span class=\"n\">glBlendFunc</span><span class=\"p\">(</span><span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">gl</span><span class=\"o\">.</span><span class=\"n\">GL_SRC_ALPHA</span><span class=\"p\">,</span> <span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">gl</span><span class=\"o\">.</span><span class=\"n\">GL_ONE_MINUS_SRC_ALPHA</span><span class=\"p\">)</span>\n    <span class=\"k\">for</span> <span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"n\">snake</span><span class=\"p\">:</span>\n        <span class=\"n\">tile</span> <span class=\"o\">=</span> <span class=\"n\">snake_tiles</span><span class=\"p\">[</span><span class=\"s1\">&apos;end-end&apos;</span><span class=\"p\">]</span>\n        <span class=\"n\">tile</span><span class=\"o\">.</span><span class=\"n\">blit</span><span class=\"p\">(</span>\n            <span class=\"n\">x</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">width</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">height</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">)</span>\n    <span class=\"k\">for</span> <span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"n\">food</span><span class=\"p\">:</span>\n        <span class=\"n\">red_image</span><span class=\"o\">.</span><span class=\"n\">blit</span><span class=\"p\">(</span>\n            <span class=\"n\">x</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">width</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">height</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">)</span>\n\n<span class=\"n\">pyglet</span><span class=\"o\">.</span><span class=\"n\">app</span><span class=\"o\">.</span><span class=\"n\">run</span><span class=\"p\">()</span>\n</pre></div>\n    </div>\n</div><h2>Jak vybrat &#x10D;tvere&#x10D;ky?</h2>\n<p>M&#xED;sto toho, aby byl v&#x161;ude stejn&#xFD; kousek hada,\nbudeme cht&#xED;t vybrat v&#x17E;dycky ten spr&#xE1;vn&#xFD;.</p>\n<p>Jak na to?\nPodle &#x10D;eho ho vybrat?</p>\n<p>Obr&#xE1;zky s&#xA0;kousky hada jsou pojmenov&#xE1;ny\n<code><var>odkud</var>-kam.png</code>.\nTo nen&#xED; n&#xE1;hoda &#x2013; ukazuje to, co pot&#x159;ebuje&#x161; v&#x11B;d&#x11B;t, abys mohla ten spr&#xE1;vn&#xFD;\nkousek vybrat.</p>\n<p>Kdy&#x17E; m&#xE1;&#x161; hada podle n&#xE1;sleduj&#xED;c&#xED;ho obr&#xE1;zku, na pol&#xED;&#x10D;ko (3, 2) pat&#x159;&#xED;\nkousek, na kter&#xE9;m had &#x201E;leze&#x201C; zleva nahoru &#x2013; tedy <code>left-top.png</code></p>\n<p><span class=\"figure\"><a href=\"/2019/brno-podzim-snake/snake/drawing/static/tile-selection.svg\"><img src=\"/2019/brno-podzim-snake/snake/drawing/static/tile-selection.svg\" alt=\"Had na &#x201E;&#x161;achovnici&#x201C; se sou&#x159;adnicemi. Pol&#xED;&#x10D;ko (3, 2) je zv&#xFD;razn&#x11B;n&#xE9; a vedou z n&#x11B;j &#x161;ipky doleva a nahoru, kudy had pokra&#x10D;uje.\"></a></span></p>\n<p>Pro ka&#x17E;d&#xE9; z&#xA0;pol&#xED;&#x10D;ek bude&#x161; pot&#x159;ebovat zjistit, odkud a kam na n&#x11B;m had leze &#x2013;\ntedy sm&#x11B;r k&#xA0;<em>p&#x159;edchoz&#xED;</em> a <em>n&#xE1;sleduj&#xED;c&#xED;</em> sou&#x159;adnici.</p>\n<p>Pot&#x159;ebuje&#x161; pro <em>ka&#x17E;d&#xE9; pol&#xED;&#x10D;ko</em> hada zjistit</p>\n<ul>\n<li><var>x</var>-ovou a <var>y</var>-ovou sou&#x159;adnici pol&#xED;&#x10D;ka</li>\n<li>sm&#x11B;r k&#xA0;<em>p&#x159;edchoz&#xED;mu</em> a <em>n&#xE1;sleduj&#xED;c&#xED;mu</em> pol&#xED;&#x10D;ku</li>\n</ul>\n<p>Do programu se pak daj&#xED; hodnoty zadat n&#x11B;jak takto:</p>\n<div class=\"highlight\"><pre><span></span>    <span class=\"k\">for</span> <span class=\"o\">...</span> <span class=\"ow\">in</span> <span class=\"o\">...</span><span class=\"p\">:</span>   <span class=\"c1\"># &#x10D;&#xED;m bude cyklus proch&#xE1;zet? Samotn&#xFD;m self.snake?</span>\n        <span class=\"n\">x</span> <span class=\"o\">=</span> <span class=\"o\">...</span>\n        <span class=\"n\">y</span> <span class=\"o\">=</span> <span class=\"o\">...</span>\n        <span class=\"n\">before</span> <span class=\"o\">=</span> <span class=\"o\">...</span>  <span class=\"c1\"># Sm&#x11B;r k p&#x159;edchoz&#xED;mu pol&#xED;&#x10D;ku (&apos;left&apos; nebo &apos;top&apos; nebo ...)</span>\n        <span class=\"n\">after</span> <span class=\"o\">=</span> <span class=\"o\">...</span>   <span class=\"c1\"># Sm&#x11B;r k n&#xE1;sleduj&#xED;c&#xED;mu pol&#xED;&#x10D;ku </span>\n\n        <span class=\"n\">snake_tiles</span><span class=\"p\">[</span><span class=\"n\">before</span> <span class=\"o\">+</span> <span class=\"s1\">&apos;-&apos;</span> <span class=\"o\">+</span> <span class=\"n\">after</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">blit</span><span class=\"p\">(</span>\n            <span class=\"n\">x</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">y</span> <span class=\"o\">*</span> <span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">width</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">,</span> <span class=\"n\">height</span><span class=\"o\">=</span><span class=\"n\">TILE_SIZE</span><span class=\"p\">)</span>\n</pre></div><p>Toto je <strong>t&#x11B;&#x17E;k&#xFD; &#xFA;kol</strong>.\nI kdy&#x17E; v&#x161;echny pot&#x159;ebn&#xE9; informace a n&#xE1;stroje k&#xA0;tomu te&#x10F; teoreticky zn&#xE1;&#x161;,\nje pot&#x159;eba je spr&#xE1;vn&#xFD;m zp&#x16F;sobem poskl&#xE1;dat dohromady.\nTohle skl&#xE1;d&#xE1;n&#xED; dohromady, <em>n&#xE1;vrh algoritm&#x16F;</em>, je nejslo&#x17E;it&#x11B;j&#x161;&#xED; program&#xE1;torsk&#xE1; \ndiscipl&#xED;na.</p>\n<p>Zkus nad t&#xED;m ale p&#x159;em&#xFD;&#x161;let, nech si to rozle&#x17E;et v&#xA0;hlav&#x11B; t&#x159;eba p&#x159;es noc,\nvra&#x165; se k&#xA0;materi&#xE1;l&#x16F;m k&#xA0;p&#x159;edchoz&#xED;m lekc&#xED;m (hlavn&#x11B; k&#xA0;&#xFA;vodu do Pythonu),\nzkou&#x161;ej a objevuj&#x2026; A &#x10D;asem na to p&#x159;ijde&#x161;.\nOdm&#x11B;nou za vy&#x159;e&#x161;en&#xED; ti bude had m&#xED;sto housenky.</p>\n<p>Ne&#x17E; na to p&#x159;ijde&#x161;, zbytek programu ti neute&#x10D;e.\nHousenka je &#xFA;pln&#x11B; stejn&#x11B; hrateln&#xE1; jako had, jen jinak vypad&#xE1;.\nKlidn&#x11B; p&#x159;ejdi na <a href=\"/2019/brno-podzim-snake/snake/logic/\">psan&#xED; logiky hry</a> s&#xA0;housenkou.</p>\n<p>Nebo se <a href=\"/2019/brno-podzim-snake/snake/tile-selection/\">nech&#xE1;&#x161; poddat</a>?</p>\n\n\n        "
    }
  }
}