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 mohl/a 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.

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ěl/a 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:
    ...

Funguje to? Vidíš v tom – aspoň zhruba – hada poskládaného ze čtverečků?

Had na „šachovnici“ a ukázka programu

Jestli ne, 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. Nebo 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ěl/a.

Proto Pythonu řekneme, aby nám dal všechny soubory s koncovkou .png v daném adresáři. Na to se dá použít třída Path z modulu pathlib. Zkus si do nového souboru, třeba experiment.py, napsat následující kód a spustit ho. Dokážeš vysvětlit, co dělá?

from pathlib import Path

TILES_DIRECTORY = Path('snake-tiles')

for path in TILES_DIRECTORY.glob('*.png'):
    print(path)

My z každého souboru potřebujeme nejlépe jméno, tedy místo snake-tiles/right-end.png jenom right-end. Na to naštěstí existuje atribut stem (kořen, t.j. jméno bez přípony). Místo print(path) použij:

    print(path.stem)

Funguje? Máš vypsané všechny možné kousky hada?

Teď budeme chtít načíst obrázky do slovníku. Klíče slovníku, podle kterých budeme vyhledávat, budou jména, která jsi právě vypsal/a. Hodnoty pak budou pygletí obrázky, které ve hře můžeš rovnou vykreslit.

Začni s prázdným slovníkem, {}, a v cyklu for do něj postupně přidávej záznamy. Pak celý slovník vypiš.

Až to budeš mít, měl by výpis vypadat asi takhle:

{'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>,
 ...

Řešení

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, ale budeme chtít vybrat vždycky ten správný.

Jak na to? Podle čeho ho vybrat?

Pojďme si to vyzkoušet vedle. Vytvoř soubor smery.py a napiš do něj:

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

for x, y in snake:
    print(x, y)

Tenhle kód vypisuje souřadnice:

1 2
2 2
3 2
3 3
3 4
3 5
4 5

Zkus vymyslet, jak by se tenhle kód dal změnit, aby vypisoval ke každé souřadnici směr k předchozímu a následujícímu políčku – tedy odkud a kam každý kousek hada „vede“. Takhle:

1 2 end right
2 2 left right
3 2 left top
3 3 bottom top
3 4 bottom top
3 5 bottom right
4 5 left end

Toto je těžký úkol. Nepředpokládám, že ho zvládneš vyřešit hned, i když všechny potřebné informace a nástroje k tomu znáš. 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š.

Až se to stane, zkus své řešení co nejvíc zjednodušit a pak ho zakomponovat do vykreslovací funkce místo existujícího cyklu for x, y in snake.

    for ... in ...:
        ...
        x = ...
        y = ...
        odkud = ...
        kam = ...
        ...

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

Soubor smery.py po vyřešení nemaž, bude se ti pak hodit.

Odměnou za vyřešení tohoto úkolu 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 další část – logiku hry – s housenkou.

{
  "data": {
    "sessionMaterial": {
      "id": "session-material:2018/snake-brno-codeweek:workshop:1",
      "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 mohl/a 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=\"/2018/snake-brno-codeweek/snake/drawing/static/coords.svg\"><img src=\"/2018/snake-brno-codeweek/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<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=\"/2018/snake-brno-codeweek/snake/drawing/static/coords-px.svg\"><img src=\"/2018/snake-brno-codeweek/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;l/a 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=\"/2018/snake-brno-codeweek/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=\"/2018/snake-brno-codeweek/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=\"/2018/snake-brno-codeweek/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>Funguje to? Vid&#xED;&#x161; v&#xA0;tom &#x2013; aspo&#x148; zhruba &#x2013; hada poskl&#xE1;dan&#xE9;ho ze &#x10D;tvere&#x10D;k&#x16F;?</p>\n<p><span class=\"figure\"><a href=\"/2018/snake-brno-codeweek/snake/drawing/static/coords-blocks.svg\"><img src=\"/2018/snake-brno-codeweek/snake/drawing/static/coords-blocks.svg\" alt=\"Had na &#x201E;&#x161;achovnici&#x201C; a uk&#xE1;zka programu\"></a></span></p>\n<p>Jestli ne, 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.\nNebo 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=\"/2018/snake-brno-codeweek/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=\"/2018/snake-brno-codeweek/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=\"/2018/snake-brno-codeweek/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=\"/2018/snake-brno-codeweek/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=\"/2018/snake-brno-codeweek/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=\"/2018/snake-brno-codeweek/snake/drawing/static/screenshot-dir.png\"><img src=\"/2018/snake-brno-codeweek/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=\"/2018/snake-brno-codeweek/snake/drawing/static/snake-tiles.png\"><img src=\"/2018/snake-brno-codeweek/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=\"/2018/snake-brno-codeweek/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;l/a.</p>\n<p>Proto Pythonu &#x159;ekneme, aby n&#xE1;m dal v&#x161;echny soubory s&#xA0;koncovkou <code>.png</code> v&#xA0;dan&#xE9;m\nadres&#xE1;&#x159;i.\nNa to se d&#xE1; pou&#x17E;&#xED;t t&#x159;&#xED;da <code>Path</code> z modulu <a href=\"https://docs.python.org/3/library/pathlib.html\"><code>pathlib</code></a>.\nZkus si do nov&#xE9;ho souboru, t&#x159;eba <code>experiment.py</code>, napsat n&#xE1;sleduj&#xED;c&#xED; k&#xF3;d\na spustit ho.\nDok&#xE1;&#x17E;e&#x161; vysv&#x11B;tlit, co d&#x11B;l&#xE1;?</p>\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=\"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=\"k\">for</span> <span class=\"n\">path</span> <span class=\"ow\">in</span> <span class=\"n\">TILES_DIRECTORY</span><span class=\"o\">.</span><span class=\"n\">glob</span><span class=\"p\">(</span><span class=\"s1\">&apos;*.png&apos;</span><span class=\"p\">):</span>\n    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">path</span><span class=\"p\">)</span>\n</pre></div><p>My z&#xA0;ka&#x17E;d&#xE9;ho souboru pot&#x159;ebujeme nejl&#xE9;pe jm&#xE9;no, tedy m&#xED;sto\n<code>snake-tiles/right-end.png</code> jenom <code>right-end</code>.\nNa to na&#x161;t&#x11B;st&#xED; existuje atribut <code>stem</code> (<em>ko&#x159;en</em>, t.j. jm&#xE9;no bez p&#x159;&#xED;pony).\nM&#xED;sto <code>print(path)</code> pou&#x17E;ij:</p>\n<div class=\"highlight\"><pre><span></span>    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">stem</span><span class=\"p\">)</span>\n</pre></div><p>Funguje? M&#xE1;&#x161; vypsan&#xE9; v&#x161;echny mo&#x17E;n&#xE9; kousky hada?</p>\n<p>Te&#x10F; budeme cht&#xED;t na&#x10D;&#xED;st obr&#xE1;zky do <em>slovn&#xED;ku</em>.\n<em>Kl&#xED;&#x10D;e</em> slovn&#xED;ku, podle kter&#xFD;ch budeme vyhled&#xE1;vat, budou jm&#xE9;na, kter&#xE1; jsi\npr&#xE1;v&#x11B; vypsal/a.\n<em>Hodnoty</em> pak budou pyglet&#xED; obr&#xE1;zky, kter&#xE9; ve h&#x159;e m&#x16F;&#x17E;e&#x161; rovnou vykreslit.</p>\n<p>Za&#x10D;ni s pr&#xE1;zdn&#xFD;m slovn&#xED;kem, <code>{}</code>, a v&#xA0;cyklu <code>for</code> do n&#x11B;j postupn&#x11B; p&#x159;id&#xE1;vej\nz&#xE1;znamy.\nPak cel&#xFD; slovn&#xED;k vypi&#x161;.</p>\n<p>A&#x17E; to bude&#x161; m&#xED;t, m&#x11B;l by v&#xFD;pis vypadat asi takhle:</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><div class=\"solution\" id=\"solution-3\">\n    <h3>&#x158;e&#x161;en&#xED;</h3>\n    <div class=\"solution-cover\">\n        <a href=\"/2018/snake-brno-codeweek/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\">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_tiles</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n<span class=\"k\">for</span> <span class=\"n\">path</span> <span class=\"ow\">in</span> <span class=\"n\">TILES_DIRECTORY</span><span class=\"o\">.</span><span class=\"n\">glob</span><span class=\"p\">(</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\">path</span><span class=\"o\">.</span><span class=\"n\">stem</span><span class=\"p\">]</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=\"n\">path</span><span class=\"p\">)</span>\n\n<span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">snake_tiles</span><span class=\"p\">)</span>\n</pre></div>\n    </div>\n</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=\"/2018/snake-brno-codeweek/snake/drawing/static/caterpillar.png\"><img src=\"/2018/snake-brno-codeweek/snake/drawing/static/caterpillar.png\" alt=\"Housenka\"></a></span></p>\n<div class=\"solution\" id=\"solution-4\">\n    <h3>&#x158;e&#x161;en&#xED;</h3>\n    <div class=\"solution-cover\">\n        <a href=\"/2018/snake-brno-codeweek/snake/drawing/index/solutions/4/\"><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\">path</span> <span class=\"ow\">in</span> <span class=\"n\">TILES_DIRECTORY</span><span class=\"o\">.</span><span class=\"n\">glob</span><span class=\"p\">(</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\">path</span><span class=\"o\">.</span><span class=\"n\">stem</span><span class=\"p\">]</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=\"n\">path</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\">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\">snake_tiles</span><span class=\"p\">[</span><span class=\"s1\">&apos;end-end&apos;</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    <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,\nale budeme 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>Poj&#x10F;me si to vyzkou&#x161;et vedle.\nVytvo&#x159; soubor <code>smery.py</code> a napi&#x161; do n&#x11B;j:</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\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=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">,</span> <span class=\"n\">y</span><span class=\"p\">)</span>\n</pre></div><p>Tenhle k&#xF3;d vypisuje sou&#x159;adnice:</p>\n<div class=\"highlight\"><pre><code>1 2\n2 2\n3 2\n3 3\n3 4\n3 5\n4 5</code></pre></div><p>Zkus vymyslet, jak by se tenhle k&#xF3;d dal zm&#x11B;nit, aby vypisoval ke ka&#x17E;d&#xE9;\nsou&#x159;adnici <em>sm&#x11B;r</em> k p&#x159;edchoz&#xED;mu a n&#xE1;sleduj&#xED;c&#xED;mu pol&#xED;&#x10D;ku &#x2013; tedy odkud a kam\nka&#x17E;d&#xFD; kousek hada &#x201E;vede&#x201C;.\nTakhle:</p>\n<div class=\"highlight\"><pre><code>1 2 end right\n2 2 left right\n3 2 left top\n3 3 bottom top\n3 4 bottom top\n3 5 bottom right\n4 5 left end</code></pre></div><p>Toto je <strong>t&#x11B;&#x17E;k&#xFD; &#xFA;kol</strong>.\nNep&#x159;edpokl&#xE1;d&#xE1;m, &#x17E;e ho zvl&#xE1;dne&#x161; vy&#x159;e&#x161;it hned, i kdy&#x17E; v&#x161;echny pot&#x159;ebn&#xE9; informace\na n&#xE1;stroje k&#xA0;tomu zn&#xE1;&#x161;.\nZkus 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;.</p>\n<p>A&#x17E; se to stane, zkus sv&#xE9; &#x159;e&#x161;en&#xED; co nejv&#xED;c <em>zjednodu&#x161;it</em> a pak ho zakomponovat\ndo vykreslovac&#xED; funkce m&#xED;sto existuj&#xED;c&#xED;ho cyklu <code>for x, y in snake</code>.</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>\n        <span class=\"o\">...</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\">odkud</span> <span class=\"o\">=</span> <span class=\"o\">...</span>\n        <span class=\"n\">kam</span> <span class=\"o\">=</span> <span class=\"o\">...</span>\n        <span class=\"o\">...</span>\n\n        <span class=\"n\">snake_tiles</span><span class=\"p\">[</span><span class=\"n\">odkud</span> <span class=\"o\">+</span> <span class=\"s1\">&apos;-&apos;</span> <span class=\"o\">+</span> <span class=\"n\">kam</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>Soubor <code>smery.py</code> po vy&#x159;e&#x161;en&#xED; nema&#x17E;, bude se ti pak hodit.</p>\n<p>Odm&#x11B;nou za vy&#x159;e&#x161;en&#xED; tohoto &#xFA;kolu 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 dal&#x161;&#xED; &#x10D;&#xE1;st &#x2013; logiku hry &#x2013; s&#xA0;housenkou.</p>\n\n\n        "
    }
  }
}