Hlavní navigace

Vytváření animací a práce se zvukem i s hudbou v nástroji Pygame Zero

10. 11. 2020
Doba čtení: 31 minut

Sdílet

Ve čtvrté části miniseriálu o nástroji Pygame Zero se budeme zabývat především tvorbou animací, což kupodivu nemusí být příliš složité téma. Ukážeme si také, jakým způsobem se pracuje se zvuky a s hudbou.

Obsah

1. Animace založené na tweeningu

2. Animace v nástroji Pygame Zero

3. Automatické spuštění animace po inicializaci programu

4. Kostra aplikace demonstrující animační schopnosti Pygame Zero

5. Nastavení rychlosti animace

6. Zrychlování a/nebo zpomalování animace

7. Rozkmitání objektu na začátku a/nebo na konci animace

8. Odraz objektu na začátku a/nebo na konci animace

9. Složitější animace složená ze série na sebe navazujících animací

10. Animace většího množství objektů ve scéně

11. Rotace spritů

12. Ukázka základu hry typu Asteroids

13. Zvuky a hudba v Pygame Zero

14. Podpora pro přehrávání zvuků

15. Demonstrační příklad: přehrání zvuku po stisku klávesy

16. Podpora pro přehrávání hudby

17. Demonstrační příklad: přehrání hudby inicializované po spuštění

18. Relevantní funkce z knihovny Pygame

19. Repositář s demonstračními příklady

20. Odkazy na Internetu

1. Animace založené na tweeningu

V první části dnešního článku o nástroji Pygame Zero si ukážeme tvorbu jednodušších a následně i poměrně komplikovaných animací. Ty jsou – minimálně v Pygame Zero – založeny na takzvaném tweeningu, což znamená, že je nějakým způsobem popsán začátek animace a současně i její konec. Jednotlivé snímky animace (resp. přesněji řečeno mezisnímky) mezi známým začátkem a koncem jsou dopočteny automaticky, typicky s využitím lineární či nelineární interpolace mezi klíčovými snímky. A právě tento výpočet mezisnímků se nazývá tweening, což je slovo získané zkrácením slova inbetweening.

tweeningu jsme se již na stránkách Roota minimálně jednou zmínili, a to konkrétně při popisu dnes již historického Autodesk Animatoru, za jehož vývojem stál Jim Kent, jenž ještě před Autodesk Animatorem pracoval i na vývoji dalších animačních programů, zejména Aegis Animatoru a Cyber Paintu. Rozšířený tweening nalezneme i v moderních animačních programech – viz například stránky společnosti Adobe.

Jim Kent v prakticky všech svých animačních programech experimentoval s animační technikou zvanou tweening zmíněnou v úvodním odstavci. Jedná se o označení, které původně odkazovalo na profesi tweenera, tedy člověka, který ručně kreslil přechody mezi klíčovými snímky vytvořené animátorem. A prakticky stejný způsob nalezneme například již v Aegis Animatoru – explicitně je nutné vytvořit pouze klíčové snímky, přičemž mezisnímky automaticky dopočítá software. Příkladem může být změna pozice nějakého spritu, změna tvaru mnohoúhelníku, vyplňování barvou, aplikace jednoduchého filtru atd. Mezisnímek vypočtený Animatorem obsahoval rozdíly mezi dvojicí snímků, přičemž tyto rozdíly byly zobrazeny první barvou palety, což je většinou (alespoň v dobovém animačním software) barva modrá. Tyto rozdíly, popř. i další pomocné prvky (guides) bylo možné smazat jediným příkazem (clear guides) a vytvořit tak z pomocného mezisnímku skutečnou součást výsledné animace.

Obrázek 1: Animace vytvořená v Cyber Paintu přímo Jimem Kentem.

2. Animace v nástroji Pygame Zero

Připomeňme si ve stručnosti, jakým způsobem se animace založená na tweeningu specifikuje v nástroji Pygame Zero. Víme již, že samotná animace se vytvoří funkcí pojmenovanou animate, které se předávají minimálně dva parametry:

  1. Objekt, jehož atributy se mají v rámci animace měnit
  2. Atribut(y) a jejich konečné parametry po dokončení animace

Podívejme se nyní na jednoduchý demonstrační příklad, v němž budeme postupně měnit pozici spritu, který plynule přejede ze své původní polohy na místo označené kurzorem myši (ten určí nový střed spritu). Animovaným objektem tedy bude sprite, atributem pak pos a koncovou hodnotou tohoto atributu je pozice kurzoru myši ve chvíli, kdy uživatel stiskne její (libovolné) tlačítko. Animace se deklaruje následovně:

def on_mouse_down(pos, button):
    animate(sprite, pos=pos)

Obrázek 2: Výchozí pozice spritu ve scéně ihned po spuštění aplikace.

Poznámka: ve skutečnosti je atribut pos tvořen dvojicí (tuple), protože na pozici spritu se můžeme dívat několika pohledy – lze zjistit souřadnice levého horního rohu spritu, středu spritu atd. Tyto jednotlivé atributy se vzájemně ovlivňují.

Obrázek 3: Nová pozice spritu ve scéně po stisku libovolného tlačítka myši.

Úplný zdrojový kód příkladu, v němž se po stisku myši sprite plynule přesune na místo kurzoru myši, vypadá následovně:

WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
 
sprite = Actor("sprite1.png")
sprite.pos = (240, 240)
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
    sprite.draw()
 
 
def on_key_down(key, mod, unicode):
    if key == keys.ESCAPE:
        exit()
 
 
def on_mouse_down(pos, button):
    animate(sprite, pos=pos)

3. Automatické spuštění animace po inicializaci programu

V některých aplikacích budeme vyžadovat spuštění animace ihned po inicializaci programu. To lze ve skutečnosti provést jednoduše, protože kód, který není umístěn ve funkcích, je systémem Pygame Zero automaticky spuštěn (neexistuje zde koncept funkce main atd.). V následujícím programu je tedy sprite ihned po jeho spuštění postupně přesouván z levého okraje (x=0) až na pravý okraj (x=WIDTH). Animace je ve výpisu zvýrazněna podtržením:

WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
 
sprite = Actor("sprite1.png")
sprite.pos = (0, 240)
animation = animate(sprite, x=WIDTH)
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
    sprite.draw()
 
 
def on_key_down(key, mod, unicode):
    if key == keys.ESCAPE:
        exit()

4. Kostra aplikace demonstrující animační schopnosti Pygame Zero

Nyní si ukažme zdrojový kód aplikace, na které budeme postupně demonstrovat základní animační schopnosti nástroje Pygame Zero. Tato aplikace po svém spuštění vypíše nápovědu s popisem kláves, kterými se může ovládat:

MESSAGES = (
        "F - fast animation",
        "R - reset animation",
        "",
        "Esc - exit"
        )
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
 
    y = 10
    for message in MESSAGES:
        screen.draw.text(message, (TEXT_LEFT, y), color=TEXT_COLOR)
        y += TEXT_HEIGHT

Současně se do scény vykreslí i sprite, jehož původní pozice je nastavena na levý okraj okna aplikace:

sprite = Actor("sprite1.png")
sprite.pos = (0, 240)
 
def draw():
    sprite.draw()

Obrázek 4: Kostra aplikace pro demonstraci animací je ve skutečnosti plně funkčním programem – výchozí situace.

Prozatím je v aplikaci implementována jediná animace, a to konkrétně plynulý přesun spritu z levého okraje okna směrem k okraji pravému:

if key == keys.R:
    sprite.x = 0
if key == keys.F:
    animate(sprite, x=WIDTH)

Obrázek 5: Kostra aplikace pro demonstraci animací je ve skutečnosti plně funkčním programem – situace po dokončení animace.

Úplný (a současně i plně funkční) zdrojový kód kostry aplikace může vypadat následovně:

WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
TEXT_COLOR = "Orange"
TEXT_LEFT = 10
TEXT_HEIGHT = 16
 
MESSAGES = (
        "F - fast animation",
        "R - reset animation",
        "",
        "Esc - exit"
        )
 
sprite = Actor("sprite1.png")
sprite.pos = (0, 240)
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
    sprite.draw()
 
    y = 10
    for message in MESSAGES:
        screen.draw.text(message, (TEXT_LEFT, y), color=TEXT_COLOR)
        y += TEXT_HEIGHT
 
 
def on_key_down(key, mod, unicode):
    if key == keys.ESCAPE:
        exit()
    if key == keys.R:
        sprite.x = 0
    if key == keys.F:
        animate(sprite, x=WIDTH)
Poznámka: povšimněte si, že po dokončení animace je nutné nějakým způsobem obnovit původní pozici spritu na obrazovce. Tuto funkci zajišťuje klávesa R.

5. Nastavení rychlosti animace

Celá animace je při výchozím nastavení provedena za jednu sekundu (interně se výpočty provádí s přesností jedné šedesátiny sekundy). Ovšem pochopitelně budeme chtít, aby se některé animace provedly rychleji a jiné zase pomaleji. K tomuto účelu slouží nepovinný parametr duration:

animate(sprite, x=WIDTH, duration=1)

Dobu trvání animace můžeme prodloužit, například na pět sekund:

animate(sprite, x=WIDTH, duration=5)

V upraveném demonstračním příkladu je možné animaci spustit jak rychle (tlačítkem F), tak i pomalu (tlačítkem S):

Obrázek 6: Nová podoba testovací aplikace.

Opět si uvedeme úplný kód našeho upraveného demonstračního příkladu:

WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
TEXT_COLOR = "Orange"
TEXT_LEFT = 10
TEXT_HEIGHT = 16
 
MESSAGES = (
        "F - fast animation",
        "S - slow animation",
        "R - reset animation",
        "",
        "Esc - exit"
        )
 
sprite = Actor("sprite1.png")
sprite.pos = (0, 240)
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
    sprite.draw()
 
    y = 10
    for message in MESSAGES:
        screen.draw.text(message, (TEXT_LEFT, y), color=TEXT_COLOR)
        y += TEXT_HEIGHT
 
 
def on_key_down(key, mod, unicode):
    if key == keys.ESCAPE:
        exit()
    if key == keys.R:
        sprite.x = 0
    if key == keys.F:
        animate(sprite, x=WIDTH, duration=1)
    if key == keys.S:
        animate(sprite, x=WIDTH, duration=5)

6. Zrychlování a/nebo zpomalování animace

Prozatím animace probíhala konstantní rychlostí, přesněji řečeno se atribut či atributy objektu měnily v čase lineárně. Mnohdy je ovšem vhodné animaci na začátku urychlit, popř. na konci zpomalit. I toto chování je možné v nástroji Pygame Zero řídit, a to konkrétně nepovinným parametrem duration.

Zrychlení animace na začátku (z nulové rychlosti):

animate(sprite, x=WIDTH, duration=1, tween="accelerate")

Zpomalení animace na konci (na nulovou rychlost):

animate(sprite, x=WIDTH, duration=1, tween="decelerate")

Zrychlení animace na začátku a současně zpomalení na konci:

animate(sprite, x=WIDTH, duration=1, tween="accel_decel")

Obrázek 7: Podoba upraveného demonstračního příkladu po jeho spuštění.

Následuje výpis zdrojového kódu takto upraveného demonstračního příkladu:

WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
TEXT_COLOR = "Orange"
TEXT_LEFT = 10
TEXT_HEIGHT = 16
 
MESSAGES = (
        "F - fast animation",
        "S - slow animation",
        "R - reset animation",
        "",
        "A - fast animation, accelerated tween",
        "D - fast animation, decelerated tween",
        "B - fast animation, both accelerated and decelerated tween",
        "",
        "Esc - exit"
        )
 
sprite = Actor("sprite1.png")
sprite.pos = (0, 240)
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
    sprite.draw()
 
    y = 10
    for message in MESSAGES:
        screen.draw.text(message, (TEXT_LEFT, y), color=TEXT_COLOR)
        y += TEXT_HEIGHT
 
 
def on_key_down(key, mod, unicode):
    if key == keys.ESCAPE:
        exit()
    if key == keys.R:
        sprite.x = 0
    if key == keys.F:
        animate(sprite, x=WIDTH, duration=1)
    if key == keys.S:
        animate(sprite, x=WIDTH, duration=5)
    if key == keys.A:
        animate(sprite, x=WIDTH, duration=1, tween="accelerate")
    if key == keys.D:
        animate(sprite, x=WIDTH, duration=1, tween="decelerate")
    if key == keys.B:
        animate(sprite, x=WIDTH, duration=1, tween="accel_decel")

7. Rozkmitání objektu na začátku a/nebo na konci animace

Existuje ještě další varianta, jak může animace začít, popř. skončit. Tato varianta spočívá v rozkmitání objektu ještě předtím, než se začne pohybovat (to pochopitelně platí pouze za předpokladu, že animujeme pohyb objektu ve scéně – můžeme totiž „animovat“ prakticky jakýkoli atribut). I tato modifikace animace se zadává pomocí nepovinného parametru tween, ovšem s odlišnými hodnotami.

Rozkmitání objektu před vlastním pohybem:

animate(sprite, x=WIDTH, duration=2, tween="in_elastic")

Zakmitání objektu po zastavení:

animate(sprite, x=WIDTH, duration=2, tween="out_elastic")

Kombinace obou předchozích možností:

animate(sprite, x=WIDTH, duration=2, tween="in_out_elastic")

Obrázek 8: Další podoba upraveného demonstračního příkladu po jeho spuštění.

Opět si ukažme, jak vypadá úplný zdrojový kód takto upraveného příkladu:

WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
TEXT_COLOR = "Orange"
TEXT_LEFT = 10
TEXT_HEIGHT = 16
 
MESSAGES = (
        "F - fast animation",
        "S - slow animation",
        "R - reset animation",
        "",
        "I - fast animation, elastic @ in tween",
        "O - fast animation, elastic @ out tween",
        "B - fast animation, elastic @ both sides tween",
        "",
        "Esc - exit"
        )
 
sprite = Actor("sprite1.png")
sprite.pos = (0, 240)
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
    sprite.draw()
 
    y = 10
    for message in MESSAGES:
        screen.draw.text(message, (TEXT_LEFT, y), color=TEXT_COLOR)
        y += TEXT_HEIGHT
 
 
def on_key_down(key, mod, unicode):
    if key == keys.ESCAPE:
        exit()
    if key == keys.R:
        sprite.x = 0
    if key == keys.F:
        animate(sprite, x=WIDTH, duration=1)
    if key == keys.S:
        animate(sprite, x=WIDTH, duration=5)
    if key == keys.I:
        animate(sprite, x=WIDTH, duration=2, tween="in_elastic")
    if key == keys.O:
        animate(sprite, x=WIDTH, duration=2, tween="out_elastic")
    if key == keys.B:
        animate(sprite, x=WIDTH, duration=2, tween="in_out_elastic")

8. Odraz objektu na začátku a/nebo na konci animace

Konečně se dostáváme k poslední modifikaci animace podporované nástrojem Pygame Zero. Tato modifikace spočívá v tom, že se objekt na začátku či na konci animace několikrát „odrazí“ od počáteční nebo koncové hodnoty. V naprosté většině případů má smysl použít odrazy na konci, ovšem pro úplnost si opět uvedeme všechny podporované možnosti (asi není velkým překvapením, že se opět využije parametr tween).

Odrazy na začátku animace:

animate(sprite, x=WIDTH-BORDER, duration=2, tween="bounce_start")

Odrazy na konci animace:

animate(sprite, x=WIDTH-BORDER, duration=2, tween="bounce_end")

Odrazy na začátku a současně i na konci animace:

animate(sprite, x=WIDTH-BORDER, duration=2, tween="bounce_start_end")

Obrázek 9: Upravená varianta demonstračního příkladu.

Poslední varianta demonstračního příkladu s animací řízenou uživatelem pomocí kláves vypadá takto:

WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
TEXT_COLOR = "Orange"
TEXT_LEFT = 10
TEXT_HEIGHT = 16
 
MESSAGES = (
        "F - fast animation",
        "S - slow animation",
        "R - reset animation",
        "",
        "T - fast animation, bounce @ start tween",
        "E - fast animation, bounce @ end tween",
        "B - fast animation, bounce @ both sides tween",
        "",
        "Esc - exit"
        )
 
sprite = Actor("sprite1.png")
BORDER = sprite.width/2 - 5
sprite.pos = (BORDER, 240)
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
    sprite.draw()
 
    y = 10
    for message in MESSAGES:
        screen.draw.text(message, (TEXT_LEFT, y), color=TEXT_COLOR)
        y += TEXT_HEIGHT
 
 
def on_key_down(key, mod, unicode):
    if key == keys.ESCAPE:
        exit()
    if key == keys.R:
        sprite.x = BORDER
    if key == keys.F:
        animate(sprite, x=WIDTH-BORDER, duration=1)
    if key == keys.S:
        animate(sprite, x=WIDTH-BORDER, duration=5)
    if key == keys.T:
        animate(sprite, x=WIDTH-BORDER, duration=2, tween="bounce_start")
    if key == keys.E:
        animate(sprite, x=WIDTH-BORDER, duration=2, tween="bounce_end")
    if key == keys.B:
        animate(sprite, x=WIDTH-BORDER, duration=2, tween="bounce_start_end")

9. Složitější animace složená ze série na sebe navazujících animací

Nástroj Pygame Zero umožňuje specifikaci funkce, která se má zavolat po dokončení animace. A právě tato vlastnost nám umožňuje vytváření složitějších animací postavených na konceptu takzvaných klíčových snímků (keyframe), mezi kterými jsou dopočítány mezisnímky (inbetween → tween). Podívejme se nyní na způsob zadání takové animace, při které objekt (sprite) objede po všech okrajích okna. Celá animace je složena ze série jednodušších lineárních posunů, každý reprezentovaný samostatnou funkcí:

def a1():
    animate(sprite, x=WIDTH-BORDER, on_finished=a2)
 
 
def a2():
    animate(sprite, y=HEIGHT-BORDER, on_finished=a3)
 
 
def a3():
    animate(sprite, x=BORDER, on_finished=a4)
 
 
def a4():
    animate(sprite, y=BORDER)
Poznámka: povšimněte si, jak na sebe jednotlivé funkce navazují – viz nepovinný parametr on_finished.

Celá animace je spuštěna klávesou W:

def on_key_down(key, mod, unicode):
    if key == keys.W:
        animate(sprite, x=BORDER, y=BORDER, on_finished=a1)

Úplný zdrojový kód demonstračního příkladu, který provádí tuto již poněkud složitější animaci, vypadá následovně:

WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
TEXT_COLOR = "Orange"
TEXT_LEFT = 10
TEXT_HEIGHT = 16
 
MESSAGES = (
        "F - fast animation",
        "R - reset animation",
        "",
        "W - walk around screen",
        "Esc - exit"
        )
 
sprite = Actor("sprite1.png")
BORDER = sprite.width/2 - 5
sprite.pos = (BORDER, HEIGHT/2)
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
    sprite.draw()
 
    y = 10
    for message in MESSAGES:
        screen.draw.text(message, (TEXT_LEFT, y), color=TEXT_COLOR)
        y += TEXT_HEIGHT
 
 
def on_key_down(key, mod, unicode):
    if key == keys.ESCAPE:
        exit()
    if key == keys.R:
        sprite.x = BORDER
        sprite.y = HEIGHT/2
    if key == keys.F:
        animate(sprite, x=WIDTH-BORDER)
    if key == keys.W:
        animate(sprite, x=BORDER, y=BORDER, on_finished=a1)
 
 
def a1():
    animate(sprite, x=WIDTH-BORDER, on_finished=a2)
 
 
def a2():
    animate(sprite, y=HEIGHT-BORDER, on_finished=a3)
 
 
def a3():
    animate(sprite, x=BORDER, on_finished=a4)
 
 
def a4():
    animate(sprite, y=BORDER)

10. Animace většího množství objektů ve scéně

Nic nám nebrání v tom, aby se v jeden okamžik spustilo několik animací. Ty budou prováděny současně. Nejdříve si opět připravme kostru příkladu, která prozatím bude provádět animaci jediného spritu (částice). Tato částice bude padat z horního okraje obrazovky směrem za její spodní okraj. Přesné souřadnice začátku a konce jsou zvoleny pseudonáhodně a částice je urychlována (jakoby skutečně padala v gravitačním poli):

from random import randrange
 
WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
X_SPREAD = 50
 
sprite = Actor("particle.png")
sprite.pos = (240, 0)
 
 
def a1():
    sprite.x = WIDTH/2 + randrange(-X_SPREAD, X_SPREAD)
    sprite.y = -10
    animate(sprite,
            x=WIDTH/2 + randrange(-X_SPREAD, X_SPREAD),
            y=HEIGHT,
            on_finished=a1,
            duration=5,
            tween="accelerate")
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
    sprite.draw()
 
 
def on_key_down(key, mod, unicode):
    if key == keys.ESCAPE:
        exit()
 
 
a1()

Obrázek 10: Jediná padající částice.

Rozšíření na větší počet částic (v našem konkrétním případě je jejich počet řízen pomocí SPRITES_COUNT) je již snadné. Vytvoříme seznam sprites se všemi částicemi a posléze animaci spustíme s tím, že se po dopadu částice animace zopakuje:

from random import randrange
 
WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
X_SPREAD = 100
Y_SPREAD = 200
SPRITES_COUNT = 100
sprites = None
 
 
def init_sprites():
    global sprites
    sprites = [Actor("particle.png") for i in range(SPRITES_COUNT)]
    for sprite in sprites:
        sprite.pos = (240, 0)
        a1(sprite)
 
 
def a1(sprite):
    sprite.x = WIDTH/2 + randrange(-X_SPREAD, X_SPREAD)
    sprite.y = 0 - randrange(Y_SPREAD)
    animate(sprite,
            x=WIDTH/2 + randrange(-X_SPREAD, X_SPREAD),
            y=HEIGHT + randrange(Y_SPREAD),
            on_finished=lambda: a1(sprite),
            duration=randrange(2, 7),
            tween="accelerate")
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
    for sprite in sprites:
        sprite.draw()
 
 
def on_key_down(key, mod, unicode):
    if key == keys.ESCAPE:
        exit()
 
 
init_sprites()

Obrázek 11: Větší množství animovaných spritů ve scéně.

Poznámka: povšimněte si, jakým způsobem je řešena problematika předávání parametrů do funkce specifikované parametrem on_finished. Takové funkci zdánlivě nelze předat žádná data, ovšem ve skutečnosti si můžeme pomoci klíčovým slovem lambda a vytvořením uzávěru (closure):
animate(sprite,
        x=WIDTH/2 + randrange(-X_SPREAD, X_SPREAD),
        y=HEIGHT + randrange(Y_SPREAD),
        on_finished=lambda: a1(sprite),
        duration=randrange(2, 7),
        tween="accelerate")

11. Rotace spritů

Sprity je možné otáčet, a to konkrétně změnou atributu angle. V následujícím demonstračním příkladu je otáčení prováděno kontinuálně, takže nepoužijeme klasickou animaci, ale budeme úhel měnit ve funkci update, která je volaná šedesátkrát za sekundu:

def update():
    sprite.left += dx
    sprite.top += dy
    sprite.angle += 1

Obrázek 12: Otáčení spritu ve scéně.

Opět si ukážeme celý zdrojový kód tohoto demonstračního příkladu:

WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
 
sprite = Actor("sprite1.png")
sprite.pos = (240, 240)
dx = 0
dy = 0
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
    sprite.draw()
 
 
def update():
    sprite.left += dx
    sprite.top += dy
    sprite.angle += 1
 
 
def on_key_down(key, mod, unicode):
    global dx, dy
    if key == keys.ESCAPE:
        exit()
    if key == keys.UP:
        dy = -1
    if key == keys.DOWN:
        dy = 1
    if key == keys.LEFT:
        dx = -1
    if key == keys.RIGHT:
        dx = 1
 
 
def on_key_up(key, mod):
    global dx, dy
    if key == keys.ESCAPE:
        exit()
    if key == keys.UP or key == keys.DOWN:
        dy = 0
    if key == keys.LEFT or key == keys.RIGHT:
        dx = 0

Upravit můžeme i předchozí příklad s animovanými částicemi tak, aby se částice při pádu náhodně otáčely:

from random import randrange
 
WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
X_SPREAD = 100
Y_SPREAD = 200
SPRITES_COUNT = 100
sprites = None
 
 
def init_sprites():
    global sprites
    sprites = [Actor("particle.png") for i in range(SPRITES_COUNT)]
    for sprite in sprites:
        sprite.pos = (240, 0)
        a1(sprite)
 
 
def a1(sprite):
    sprite.x = WIDTH/2 + randrange(-X_SPREAD, X_SPREAD)
    sprite.y = 0 - randrange(Y_SPREAD)
    animate(sprite,
            x=WIDTH/2 + randrange(-X_SPREAD, X_SPREAD),
            y=HEIGHT + randrange(Y_SPREAD),
            angle=randrange(360),
            on_finished=lambda: a1(sprite),
            duration=randrange(2, 7),
            tween="accelerate")
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
    for sprite in sprites:
        sprite.draw()
 
 
def on_key_down(key, mod, unicode):
    if key == keys.ESCAPE:
        exit()
 
 
init_sprites()

12. Ukázka základu hry typu Asteroids

Nyní již máme k dispozici všechny potřebné znalosti k tomu, abychom vytvořili základ jednoduché hry typu Asteroids. Prozatím budeme implementovat jen pohyb rakety s otáčením a dynamickou změnou rychlosti kurzorovými tlačítky (raketa navíc sama zpomaluje, což je sice ve vesmíru nesmysl, ale alespoň si můžeme odzkoušet implementaci zpomalování):

Obrázek 13: Snímek ze „hry“.

from math import sin, cos, radians
 
WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
 
sprite = Actor("spaceship.png")
sprite.pos = (240, 240)
speed_delta = 0
angle_delta = 0
speed = 0
angle = 0
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
    sprite.draw()

 
def update():
    global speed, angle, speed_delta
    angle += angle_delta
    sprite.top -= speed*cos(radians(angle))
    sprite.left -= speed*sin(radians(angle))
    sprite.angle = angle
    speed += speed_delta
    speed *= 0.95
 
 
def on_key_down(key, mod, unicode):
    global speed_delta, angle_delta, speed
    if key == keys.ESCAPE:
        exit()
    if key == keys.R:
        speed_delta = 0
        speed = 0
        sprite.x = WIDTH/2
        sprite.y = HEIGHT/2
    if key == keys.UP:
        speed_delta = 1.5
    if key == keys.DOWN:
        speed_delta = -1.5
    if key == keys.LEFT:
        angle_delta = 1
    if key == keys.RIGHT:
        angle_delta = -1
 
 
def on_key_up(key, mod):
    global speed_delta, angle_delta
    if key == keys.ESCAPE:
        exit()
    if key == keys.LEFT or key == keys.RIGHT:
        angle_delta = 0
    if key == keys.UP or key == keys.DOWN:
        speed_delta = 0

13. Zvuky a hudba v Pygame Zero

V navazujících kapitolách si řekneme základní informace o podpoře přehrávání zvuků a hudby v nástroji Pygame Zero. Tato funkcionalita je opět postavena přímo na možnostech poskytovaných knihovnou Pygame, i když prozatím některé možnosti nejsou přímo přístupné – například mixování zvuků atd.

14. Podpora pro přehrávání zvuků

Nástroj Pygame Zero podporuje přehrávání zvuků, kterých může v jeden okamžik znít větší množství. Mixáž je v tomto případě prováděna buď programově, nebo přímo na zvukové kartě. Zvuky uložené typicky ve formátu WAV (typicky nekomprimovaný), MP3 nebo Ogg/Vorbis jsou automaticky vyhledány v podadresáři sounds, odkud jsou načteny a jsou z nich vytvořeny příslušné objekty nabízené jako atributy objektu sounds (viz navazující kapitolu s demonstračním příkladem):

.
├── 00_intro.py
...
...
...
├── 50_play_sound.py
├── 51_play_music.py
├── fonts
│   ├── AUTHORS
│   ├── COPYING
│   ├── CREDITS
│   ├── freesans.ttf
│   └── README
├── images
│   ├── LICENSE
│   ├── particle.png
│   ├── plasma.png
│   ├── spaceship.png
│   └── sprite1.png
├── music
│   └── test.ogg
└── sounds
    ├── login.wav
    └── README.md

15. Demonstrační příklad: přehrání zvuku po stisku klávesy

V dnešním předposledním demonstračním příkladu je ukázáno, jakým způsobem je možné zajistit přehrání zvuku po stisku klávesy. Konkrétně se jedná o klávesu Space, po jejímž stisku se přehraje obsah souboru „login.wav“ uloženého v podadresáři „sounds“ (viz též předchozí kapitolu se stručným popisem práce se zvuky):

WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
 
 
def on_key_down(key, mod, unicode):
    if key == keys.ESCAPE:
        exit()
    if key == keys.SPACE:
        sounds.login.play()
Poznámka: ve skutečnosti je možné mít zvuky uloženy i v dalších formátech. Především se jedná o Ogg/Vorbis a podporován by měl být i formát MPEG Audio Layer III neboli známý MP3. V některých případech (mnoho animací, slabší počítač) se však může stát, že zvuk bude za spuštěním metody sounds.login.play poněkud opožděn, takže použití nekomprimovaného formátu může být (možná i trošku paradoxně) v tomto případě výhodnější.

16. Podpora pro přehrávání hudby

Na hudbu klademe poněkud odlišné nároky, než na zvuky. Většinou totiž není vyžadováno, aby bylo spuštění hudby přísně navázáno na nějaký časový okamžik (pokud se nejedná o intro atd.), ovšem naproti tomu bývají hudební soubory rozsáhlejší a je nutné je přehrávat bez zasekávání. Z tohoto důvodu může být výhodné při přehrávání používat delší buffery, které sice (obecně) zdrží začátek přehrávání, ovšem do značné míry zamezí zasekávání přehrávání. Hudební soubory jsou typicky uloženy ve formátech Ogg/Vorbis a MP3; tyto soubory jsou automaticky hledány v podadresáři „music“:

.
├── 00_intro.py
...
...
...
├── 50_play_sound.py
├── 51_play_music.py
├── fonts
│   ├── AUTHORS
│   ├── COPYING
│   ├── CREDITS
│   ├── freesans.ttf
│   └── README
├── images
│   ├── LICENSE
│   ├── particle.png
│   ├── plasma.png
│   ├── spaceship.png
│   └── sprite1.png
├── music
│   └── test.ogg
└── sounds
    ├── login.wav
    └── README.md

17. Demonstrační příklad: přehrání hudby inicializované po spuštění

Konečně se dostáváme k dnešnímu poslednímu demonstračnímu příkladu. Po spuštění tohoto příkladu se načte a prakticky ihned se začne přehrávat obsah zvukového/hudebního souboru nazvaného „test.ogg“, jenž je uložen v podadresáři „music“. Kdykoli poté je možné spustit zvuk „login“, a to naprosto stejným způsobem, jako tomu bylo v předchozím demonstračním příkladu, jenž byl popsán v patnácté kapitole. Jak zvuk tak i hudba jsou v tomto případě korektně zmixovány (prozatím však nedokážeme vyvážit hlasitosti ani jinak ovlivnit mixáž):

WIDTH = 480
HEIGHT = 480
 
BACKGROUND_COLOR = (0, 0x80, 0x80)
 
 
def draw():
    screen.fill(BACKGROUND_COLOR)
 
 
def on_key_down(key, mod, unicode):
    if key == keys.ESCAPE:
        exit()
    if key == keys.SPACE:
        sounds.login.play()
 
 
music.play("test")

18. Relevantní funkce z knihovny Pygame

V této kapitole jsou uvedeny odkazy na dokumentaci k funkcím knihovny Pygame, které jsou interně používány i projektem Pygame Zero. Tyto funkce jsou vidět v některých chybových hlášeních, protože i přes snahy autorů Pygame Zero není odstínění od knihovny Pygame úplné (což je možná jeden z největších současných nedostatků tohoto projektu):

  1. pygame.init()
    http://www.pygame.org/doc­s/ref/pygame.html#pygame.i­nit
  2. pygame.quit()
    http://www.pygame.org/doc­s/ref/pygame.html#pygame.qu­it
  3. pygame.display.set_mode()
    http://www.pygame.org/doc­s/ref/display.html#pygame­.display.set_mode
  4. pygame.display.set_caption()
    http://www.pygame.org/doc­s/ref/display.html#pygame­.display.set_caption
  5. pygame.display.update()
    http://www.pygame.org/doc­s/ref/display.html#pygame­.display.update
  6. pygame.event.get()
    http://www.pygame.org/doc­s/ref/event.html#pygame.e­vent.get
  7. pygame.time.wait()
    http://www.pygame.org/doc­s/ref/time.html#pygame.ti­me.wait
  8. pygame.time.Clock.tick()
    http://www.pygame.org/doc­s/ref/time.html#pygame.ti­me.Clock.tick
  9. pygame.draw.line()
    http://www.pygame.org/doc­s/ref/draw.html#pygame.draw­.line
  10. pygame.draw.circle()
    http://www.pygame.org/doc­s/ref/draw.html#pygame.draw­.circle
  11. pygame.draw.rect()
    http://www.pygame.org/doc­s/ref/draw.html#pygame.draw­.rect
  12. pygame.draw.ellipse()
    http://www.pygame.org/doc­s/ref/draw.html#pygame.draw­.ellipse
  13. pygame.key.get_pressed
    https://www.pygame.org/doc­s/ref/key.html#pygame.key­.get_pressed
  14. pygame.key.get_mods
    https://www.pygame.org/doc­s/ref/key.html#pygame.key­.get_mods
  15. pygame.mouse.get_pos
    https://www.pygame.org/doc­s/ref/mouse.html#pygame.mou­se.get_pos
  16. pygame.mouse.get_rel
    https://www.pygame.org/doc­s/ref/mouse.html#pygame.mou­se.get_rel
  17. pygame.mouse.get_pressed
    https://www.pygame.org/doc­s/ref/mouse.html#pygame.mou­se.get_pressed
  18. pygame.mixer
    https://www.pygame.org/doc­s/ref/mixer.html
  19. pygame.mixer.music
    https://www.pygame.org/doc­s/ref/music.html
  20. pygame.mixer.Sound
    https://www.pygame.org/doc­s/ref/mixer.html#pygame.mi­xer.Sound
  21. pygame.mixer.Channel
    https://www.pygame.org/doc­s/ref/mixer.html#pygame.mi­xer.Channel

19. Repositář s demonstračními příklady

Zdrojové kódy všech popsaných demonstračních příkladů určených pro Python 3 a současně i pro nástroj Pygame Zero byly uloženy do Git repositáře dostupného na adrese https://github.com/tisnik/most-popular-python-libs. V případě, že nebudete chtít klonovat celý repositář (ten je ovšem stále velmi malý, dnes má velikost zhruba několik desítek kilobajtů), můžete namísto toho použít odkazy na jednotlivé příklady, které naleznete v následující čtveřici tabulek (ovšem vzhledem k tomu, že se datové soubory hledají v konkrétních podadresářích, je výhodnější provést klon celého repositáře):

# Demonstrační příklad Stručný popis příkladu Cesta
1 00_intro.py prázdný, ovšem plně funkční projekt https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/00_intro.py
2 01_clear_screen.py vymazání obrazovky https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/01_clear_screen.py
3 02_fill_in_screen.py vyplnění obrazovky určenou barvou specifikovanou trojicí RGB https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/02_fill_in_screen.py
4 03_fill_in_screen.py vyplnění obrazovky určenou barvou specifikovanou jménem https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/03_fill_in_screen.py
5 04_display_sprite.py zobrazení spritu https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/04_display_sprite.py
6 05_display_sprite.py zobrazení spritu odlišným způsobem https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/05_display_sprite.py
7 06_background.py zobrazení pozadí scény https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/06_background.py
8 07_background_and_sprite.py zobrazení pozadí scény a současně i spritu https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/07_background_and_spri­te.py
9 08_screen_type.py výpis typu globální proměnné screen https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/08_screen_type.py
10 09_images_type.py výpis typu globální proměnné images https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/09_images_type.py
11 10_sounds_type.py výpis typu globální proměnné souds https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/10_sounds_type.py
12 11_keyboard_type.py výpis typu globální proměnné keyboard https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/11_keyboard_type.py
13 12_tone_type.py výpis typu globální proměnné tone https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/12_tone_type.py
14 13_draw_lines.py okraj v okně aplikace vykreslený čtveřicí úseček https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/13_draw_lines.py
15 14_draw_lines.py úsečky, z nichž každá je vykreslena odlišnou barvou https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/14_draw_lines.py
16 15_draw_rect.py obrys obdélníka vykreslený metodou screen.draw.rect https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/15_draw_rect.py
17 16_draw_filled_rect.py část barvové palety, pro jejíž vykreslení je použita metoda screen.draw.filled_rect https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/16_draw_filled_rect.py
18 17_draw_circle.py kružnice vykreslená metodou screen.draw.circle https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/17_draw_circle.py
19 18_draw_filled_circles.py část barvové palety, pro jejíž vykreslení je použita metoda screen.draw.filled_circle https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/18_draw_filled_circles­.py
20 19_draw_simple_text.py nejjednodušší forma vykreslení textu do okna https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/19_draw_simple_text.py
21 20_font_name.py vykreslení textu fontem o zvolené velikosti https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/20_font_name.py
22 21_outline.py vykreslení textu se zvýrazněným obrysem https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/21_outline.py
23 22_drop_shadow.py vykreslení stínovaného textu https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/22_drop_shadow.py
24 23_drop_shadow_more.py vykreslení stínovaného textu s větším odstupem stínu https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/23_drop_shadow_more.py
25 24_color_gradient.py text vykreslený s využitím gradientního přechodu https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/24_color_gradient.py
26 25_wrapping.py zalomení delšího textu na obrazovce https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/25_wrapping.py
27 26_vertical_text.py vertikální text https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/26_vertical_text.py
28 27_rotated_text.py otočení vykreslovaného textu o libovolný úhel https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/27_rotated_text.py
29 28_sprite_on_background.py zobrazení spritu na vyplněném pozadí scény https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/28_sprite_on_background­.py
30 29_print_key_codes.py výpis kódů stisknutých kláves https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/29_print_key_codes.py
31 30_esc_to_end.py ukončení aplikace po stisku Esc https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/30_esc_to_end.py
32 31_move_sprite.py přesun spritu kurzorovými klávesami (první verze) https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/31_move_sprite.py
33 32_move_sprite_in_update.py přesun spritu kurzorovými klávesami (druhá verze) https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/32_move_sprite_in_upda­te.py
34 33_move_sprite_in_update_correct.py přesun spritu kurzorovými klávesami (funkční verze) https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/33_move_sprite_in_upda­te_correct.py
35 34_move_sprite_by_mouse.py přesun spritu pohybem myši https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/34_move_sprite_by_mouse­.py
36 35_move_sprite_by_mouse_click.py okamžitý přesun spritu po kliku myší https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/35_move_sprite_by_mouse_clic­k.py
37 36_animate_sprite_by_mouse_click.py animovaný přesun spritu po kliku myší https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/36_animate_sprite_by_mou­se_click.py
38 37_colors_table.py tabulka s názvy barev https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/37_colors_table.py
39 38_show_colors.py zobrazení několika barev podporovaných knihovnou Pygame Zero https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/38_show_colors.py
40 39_animation_framework.py kostra příkladu s animací spritů ovládaných z klávesnice https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/39_animation_framework­.py
41 40_fast_slow_animation.py rychlá a pomalá animace řízená z klávesnice https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/40_fast_slow_animation­.py
42 41_accelerated_decelerated_tween.py zrychlující a zpomalující se animace https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/41_accelerated_decelera­ted_tween.py
43 42_elastic_tween.py elastické odrazy na začátku či na konci animace https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/42_elastic_tween.py
44 43_bounce_tween.py odrazy na začátku a konci animace https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/43_bounce_tween.py
45 44_complicated_animation.py komplikovanější animace https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/44_complicated_animati­on.py
46 45_more_sprites_preparation.py animace s více sprity (příprava) https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/45_more_sprites_prepara­tion.py
47 46_more_sprites.py animace s více sprity (funkční příklad) https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/46_more_sprites.py
48 47_rotate_sprite.py rotace spritu https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/47_rotate_sprite.py
49 48_more_sprites_rotation.py rotace více spritů současně (kombinace s lineárním pohybem) https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/48_more_sprites_rotati­on.py
50 49_move_and_rotate_sprite.py posun a rotace spritu řízený z klávesnice https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/49_move_and_rotate_spri­te.py
51 50_play_sound.py přehrání zvuku po stisku klávesy https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/50_play_sound.py
52 51_play_music.py automatické přehrání hudby po spuštění příkladu https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_ze­ro/51_play_music.py

Rastrové obrázky použité v demonstračních příkladech jsou uloženy na adrese https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_zero/images.

tip obecný root

Zvuky použité v demonstračních příkladech jsou uloženy na adrese https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_zero/sounds.

A konečně hudební soubory (resp. přesněji řečeno prozatím pouze jediný soubor) jsou uloženy na adrese https://github.com/tisnik/most-popular-python-libs/blob/master/pygame_zero/music

20. Odkazy na Internetu

  1. Welcome to Pygame Zero
    https://pygame-zero.readthedocs.io/en/sta­ble/index.html
  2. Other libraries like Pygame Zero
    https://pygame-zero.readthedocs.io/en/stable/other-libs.html
  3. Principles of Pygame Zero
    https://pygame-zero.readthedocs.io/en/sta­ble/principles.html
  4. Built-in Objects (in Pygame Zero)
    https://pygame-zero.readthedocs.io/en/sta­ble/builtins.html
  5. Pygame
    https://www.pygame.org/news
  6. Kniha: Coding Games With Pygame Zero & Python: Student workbook
    https://bookerystore.com/dow­nloads/coding-games-with-pygame-zero-python-student-workbook/
  7. Projekty založené na Pygame
    https://www.pygame.org/tags/all
  8. Domovská stránka projektu LÖVE
    https://love2d.org/
  9. PyWeek, a bi-annual game jam to write games in Python
    https://pyweek.org/
  10. Teaching a kid to code with Pygame Zero
    https://www.mattlayman.com/blog/2019/te­ach-kid-code-pygame-zero/
  11. Games with PyGame Zero
    https://codewith.mu/en/tu­torials/1.0/pgzero
  12. Coding Games With Pygame Zero & Python: Student workbook (2nd edition)
    https://electronstudio.git­hub.io/pygame-zero-book/
  13. Historie vývoje počítačových her (116. část – vývoj her v současnosti: od assembleru k PyGame)
    https://www.root.cz/clanky/historie-vyvoje-pocitacovych-her-116-cast-vyvoj-her-v-soucasnosti-od-assembleru-k-pygame/
  14. Lua + LÖVE: vytvořte si vlastní hru
    https://www.root.cz/clanky/lua-love-vytvorte-si-vlastni-hru/
  15. Hrátky se systémem LÖVE
    https://www.root.cz/clanky/hratky-se-systemem-love/
  16. Vytváříme hru v systému LÖVE
    https://www.root.cz/clanky/vytvarime-hru-v-systemu-love/
  17. Hrátky se systémem LÖVE – částicové systémy
    https://www.root.cz/clanky/hratky-se-systemem-love-casticove-systemy/
  18. Hrátky se systémem LÖVE – kolize a odrazy těles
    https://www.root.cz/clanky/hratky-se-systemem-love-ndash-kolize-a-odrazy-teles/
  19. Hrátky se systémem LÖVE – kolize a odrazy těles II
    https://www.root.cz/clanky/hratky-se-systemem-love-kolize-a-odrazy-teles-ii/
  20. Hrátky se systémem LÖVE – pružné vazby mezi tělesy
    https://www.root.cz/clanky/hratky-se-systemem-love-pruzne-vazby-mezi-telesy/
  21. Hrátky se systémem LÖVE – dokončení
    https://www.root.cz/clanky/hratky-se-systemem-love-dokonceni/
  22. Seriál Letní škola programovacího jazyka Logo
    http://www.root.cz/serialy/letni-skola-programovaciho-jazyka-logo/
  23. Scratch: oficiální stránka projektu
    http://scratch.mit.edu/
  24. Scratch: galerie projektů vytvořených ve Scratchi
    http://scratch.mit.edu/ga­lleries/browse/newest
  25. Scratch: nápověda
    file:///usr/share/scratch/Hel­p/en/index.html
  26. Scratch: obrazovky nápovědy
    file:///usr/share/scratch/Hel­p/en/allscreens.html
  27. Scratch (Wikipedie CZ)
    http://cs.wikipedia.org/wiki/Scratch
  28. Scratch (programming language)
    http://en.wikipedia.org/wi­ki/Scratch_(programming_lan­guage)
  29. Scratch Modification
    http://wiki.scratch.mit.e­du/wiki/Scratch_Modificati­on
  30. Scratch Lowers Resistance to Programming
    http://www.wired.com/gadge­tlab/2009/03/scratch-lowers/
  31. Snap!
    http://snap.berkeley.edu/
  32. Prostředí Snap!
    http://snap.berkeley.edu/snap­source/snap.html
  33. Alternatives to Scratch
    http://wiki.scratch.mit.e­du/wiki/Alternatives_to_Scrat­ch
  34. Snap! (programming language)
    https://en.wikipedia.org/wi­ki/Snap!_(programming_lan­guage)
  35. Kniha o Basicu-256
    http://www.basicbook.org/fi­les/syw2l2p_b256.pdf/
  36. Basic-256 home page
    http://www.basic256.org/index_en
  37. Basic-256 Language Documentation
    http://doc.basic256.org/doku.php
  38. Basic-256 Art Gallery
    http://www.basic256.org/artgallery
  39. Basic-256 Tutorial
    http://www.basic256.org/tutorials
  40. Why BASIC?
    http://www.basic256.org/whybasic
  41. A book to teach ANYBODY how to program a computer (using BASIC)
    http://www.basicbook.org/
  42. Sprite ve Scratchi
    https://en.scratch-wiki.info/wiki/Sprite
  43. Scratch Modification
    https://en.scratch-wiki.info/wiki/Scratch_Modification
  44. 3D Programming in Python – Part 1
    https://greendalecs.wordpres­s.com/2012/04/21/3d-programming-in-python-part-1/
  45. A very basic Pyglet tutorial
    http://www.natan.termitnjak­.net/tutorials/pyglet_basic­.html
  46. Alpha blending
    https://en.wikipedia.org/wi­ki/Alpha_compositing#Alpha_blen­ding
  47. Pygame Colors
    https://pygame-zero.readthedocs.io/en/la­test/colors_ref.html
  48. Python Color Constants Module
    https://www.webucator.com/blog/2015/03/pyt­hon-color-constants-module/
  49. Inbetweening
    https://en.wikipedia.org/wi­ki/Inbetweening
  50. MP3 (Wikipedia)
    https://en.wikipedia.org/wiki/MP3
  51. Ogg (Wikipedia)
    https://en.wikipedia.org/wiki/Ogg
  52. Vorbis audio compression
    https://xiph.org/vorbis/
  53. Vorbis (Wikipedia)
    https://en.wikipedia.org/wiki/Vorbis
  54. Tweens
    https://helpx.adobe.com/a­nimate/using/Tweens.html

Autor článku

Pavel Tišnovský vystudoval VUT FIT a v současné době pracuje ve společnosti Red Hat, kde vyvíjí nástroje pro OpenShift.io.