Nedílnou součástí prakticky všech multimediálních aplikací a samozřejmě také her je čtení stavu vstupních zařízení, tj. především klávesnice, myši, joysticků či dotykové obrazovky. I tuto oblast je možné pokrýt funkcemi z knihovny Pyglet. V dnešním článku se zaměříme na popis práce s klávesnicí, což není zdaleka tak triviální, jak by se mohlo na první pohled zdát.
Obsah
1. Multimediální knihovna Pyglet: práce se vstupními zařízeními
4. První demonstrační příklad: zachycení události stisku a puštění klávesy
5. Modifikátory (Shift, Control, Alt atd.)
7. Třetí demonstrační příklad: vizuální zobrazení stisku kláves Shift a Control
9. Čtvrtý demonstrační příklad: využití pole se stavy všech kláves
10. Událost on_text aneb detekce napsaných (Unicode) znaků
11. Pátý demonstrační příklad: použití události typu on_text
12. Problematika pohybu v textu a její řešení: událost typu on_text_motion
13. Šestý demonstrační příklad: využití události on_text_motion
14. Sedmý demonstrační příklad: událost on_text_motion a pohyb spritu ve scéně
15. Repositář s demonstračními příklady
1. Multimediální knihovna Pyglet: práce se vstupními zařízeními
V knihovně Pyglet existuje podpora pro několik typů vstupních zařízení. V první řadě se pochopitelně jedná o klávesnici a myš (popř. touchpad), což jsou dnes standardní zařízení dostupná na desktopech i noteboocích. Kromě toho jsou však podporována i další zařízení, zejména joysticky, různé typy pedálů, volanty, dotykové obrazovky atd. Pro přístup k těmto zařízením se používají buď specializované callback funkce nebo je nutné použít modul pyglet.input. Dnes se budeme převážně zabývat popisem způsobu práce s klávesnicí, což ve skutečnosti není v oblasti her a multimediálních aplikací zdaleka tak triviální, jak by se mohlo na první pohled zdát, na rozdíl od běžných (řekněme kancelářských) aplikací s GUI či CLI, které používají klávesnici buď pro vstup znaků (textu) či pro ovládání uživatelského rozhraní.
2. Událost on_key_press
Základní callback funkcí, která se používá při práci s klávesnicí, je funkce nazvaná on_key_press. Tato funkce musí být přes anotaci @jméno_proměnné_reprezentující_okno.event navázána na vybrané okno. Jinými slovy to znamená, že je možné pro každé okno používat odlišnou callback funkci (na druhou stranu mají typicky hry jen jediné okno zobrazené v režimu fullscreen, což celou situaci zjednodušuje). Tato callback funkce se zavolá ve chvíli, kdy je stisknuta nějaká klávesa. Funkci se předávají dva parametry – konstanta reprezentující stisknutou klávesu (kód klávesy) a další konstanta, která je složena z příznakových bitů přiřazených každému modifikátoru (což typicky bývají klávesy Shift, Control, Alt atd.). Nejjednodušší podoba této funkce tedy může vypadat následovně:
<strong>@window.event</strong>
def on_key_press(symbol, modifiers):
pass
Důležité upozornění: na PC a navíc jen u některých kláves odpovídá hodnota parametru symbol ASCII kódu stisknuté klávesy, ovšem není dobré se na toto chování spoléhat. Namísto toho je nutné pro porovnání používat konstanty pyglet.window.key.JMÉNO_KLÁVESY. Taktéž se může stát, že symbol obsahuje zdánlivě zcela nesmyslnou (vysokou) hodnotu. To nastává ve chvíli, kdy je stisknuta nějaká multimediální klávesa, klávesa Fn na některých noteboocích, klávesa s akcentovaným znakem u národních klávesnic atd.
K symbolům kláves lze přistupovat například takto:
Konstanta | Klávesa |
---|---|
pyglet.window.key.A | klávesa A |
pyglet.window.key._1 | klávesa 1 (nutno použít podtržítko, neboť 1 není identifikátor) |
pyglet.window.key.NUM_1 | klávesa 1 na numerickém bloku |
pyglet.window.key.SPACE | mezerník |
pyglet.window.key.ENTER | Enter/Return na hlavním bloku |
pyglet.window.key.RETURN | dtto |
pyglet.window.key.NUM_ENTER | Enter/Return na numerickém bloku |
pyglet.window.key.UP | kurzorová šipka |
pyglet.window.key.DOWN | kurzorová šipka |
pyglet.window.key.LEFT | kurzorová šipka |
pyglet.window.key.RIGHT | kurzorová šipka |
pyglet.window.key.HOME | další klávesy pro pohyb kurzoru |
pyglet.window.key.END | další klávesy pro pohyb kurzoru |
pyglet.window.key.PAGEUP | další klávesy pro pohyb kurzoru |
pyglet.window.key.PAGEDOWN | další klávesy pro pohyb kurzoru |
pyglet.window.key.F1 | klávesa F1 |
Poznámka: rozlišení mezi znakem „A“ a „a“ je nutné řešit programově testem stisknutých modifikátorů (zde konkrétně Shift), protože se do callback funkcí stále bude předávat jen symbol pyglet.window.key.A (žádný symbol pyglet.window.key.a ani neexistuje).
3. Událost on_key_release
Opakem callback funkce on_key_press je funkce on_key_release, které se při jejím zavolání předají stejné parametry, tedy kód puštěné klávesy a případné modifikátory:
<strong>@window.event</strong>
def on_key_release(symbol, modifiers):
pass
Tuto funkci je nutné použít pro zjištění, zda a kdy je klávesa puštěna, a to z toho důvodu, že dvojice callback funkcí on_key_press + on_key_release neberou do úvahy automatické opakování stisknutých kláves. To jinými slovy znamená, že když dojde ke stisku klávesy, jejím podržení (řekněme deset sekund) a puštění, zavolá se funkce on_key_press jen jedenkrát (při stisku, tedy ihned na začátku) a on_key_release taktéž jedenkrát (po puštění).
4. První demonstrační příklad: zachycení události stisku a puštění klávesy
Použití callback funkcí on_key_press a on_key_release si ukážeme v dnešním prvním demonstračním příkladu, v němž je nejdříve vytvořeno okno a následně textové návěští použité pro výpis zpráv:
def create_window(width, height):
return pyglet.window.Window(width=width,
height=height,
caption="Pyglet library")
def create_label():
return pyglet.text.Label("Event:",
font_size=18,
x=window.width//4,
y=window.height//2,
anchor_x='left',
anchor_y='center')
window = create_window(640, 480)
label = create_label()
Následně jsou obě callback funkce zaregistrovány:
@window.event
def on_key_press(symbol, modifiers):
display_key_event(symbol, modifiers, "pressed")
@window.event
def on_key_release(symbol, modifiers):
display_key_event(symbol, modifiers, "released")
Při každém stisku klávesy či jejím puštění se do okna (přes textové návěští) vypíše symbol stisknuté/puštěné klávesy.
def display_key_event(symbol, modifiers, action):
text = format("Event: key with code %d %s" % (symbol, action))
label.text = text
print(symbol)
on_draw()
Obrázek 1: Událost vyvolaná puštěním klávesy A.
Úplný zdrojový kód prvního demonstračního příkladu vypadá takto:
#!/usr/bin/env python
import pyglet
def create_window(width, height):
return pyglet.window.Window(width=width,
height=height,
caption="Pyglet library")
def create_label():
return pyglet.text.Label("Event:",
font_size=18,
x=window.width//4,
y=window.height//2,
anchor_x='left',
anchor_y='center')
window = create_window(640, 480)
label = create_label()
def display_key_event(symbol, modifiers, action):
text = format("Event: key with code %d %s" % (symbol, action))
label.text = text
print(symbol)
on_draw()
@window.event
def on_draw():
window.clear()
label.draw()
@window.event
def on_key_press(symbol, modifiers):
display_key_event(symbol, modifiers, "pressed")
@window.event
def on_key_release(symbol, modifiers):
display_key_event(symbol, modifiers, "released")
pyglet.app.run()
5. Modifikátory (Shift, Control, Alt atd.)
V předchozích kapitolách jsme se zmínili o druhém parametru předávaném do funkcí on_key_press a on_key_release. Tento parametr je reprezentován celým číslem, jehož jednotlivé bity určují, které modifikátory jsou stisknuty současně s danou klávesou. Rozpoznány mohou být následující modifikátory (ovšem pochopitelně zdaleka ne všechny příslušné klávesy naleznete na jedné klávesnici):
Modifikátor | Poznámka |
---|---|
MOD_SHIFT | |
MOD_CTRL | |
MOD_ALT | není na Mac OS X |
MOD_WINDOWS | není na Mac OS X |
MOD_COMMAND | pouze na Mac OS X |
MOD_OPTION | pouze na Mac OS X |
MOD_CAPSLOCK | |
MOD_NUMLOCK | |
MOD_SCROLLLOCK | |
MOD_ACCEL | může nahradit buď MOD_CTRL nebo MOD_COMMAND |
Na většině klávesnic nalezneme klávesy Shift, Ctrl/Control a Alt, takže test na stisk těchto kláves (společně s další klávesou) může vypadat například takto:
<strong>@window.event</strong>
def on_key_press(symbol, modifiers):
if modifiers & pyglet.window.key.MOD_SHIFT:
foo()
if modifiers & pyglet.window.key.MOD_CTRL:
bar()
if modifiers & pyglet.window.key.MOD_ALT:
baz()
6. Druhý demonstrační příklad: test modifikátorů bez rozlišení, zda se nachází na levé či pravé straně klávesnice
Ve druhém demonstračním příkladu je ukázán jeden ze způsobů otestování stisku základních modifikátorů Shift, Ctrl/Control a Alt. Do příkladu bylo přidáno další návěští (label), do kterého jsou vypisovány informace o tom, které modifikátory jsou stisknuty:
def create_label2():
return pyglet.text.Label("Modifiers:",
font_size=16,
x=window.width//4,
y=window.height//2 - 32,
anchor_x='left',
anchor_y='center')
Vzhledem k tomu, že modifikátory lze stlačit současně, musí logika aplikace vypadat takto:
def display_key_event(symbol, modifiers, action):
text = format("Event: key with code %d %s" % (symbol, action))
label1.text = text
text = "Modifiers: "
if modifiers & pyglet.window.key.MOD_SHIFT:
text = text + "Shift "
if modifiers & pyglet.window.key.MOD_CTRL:
text = text + "Ctrl "
if modifiers & pyglet.window.key.MOD_ALT:
text = text + "Alt "
label2.text = text
on_draw()
Obrázek 2: Modifikátor Shift současně změnil vlastní kód stisknuté klávesy (použito je CZ_QWERTY rozložení).
Úplný zdrojový kód druhého demonstračního příkladu vypadá následovně:
#!/usr/bin/env python
import pyglet
def create_window(width, height):
return pyglet.window.Window(width=width,
height=height,
caption="Pyglet library")
def create_label1():
return pyglet.text.Label("Event:",
font_size=18,
x=window.width//4,
y=window.height//2,
anchor_x='left',
anchor_y='center')
def create_label2():
return pyglet.text.Label("Modifiers:",
font_size=16,
x=window.width//4,
y=window.height//2 - 32,
anchor_x='left',
anchor_y='center')
window = create_window(640, 480)
label1 = create_label1()
label2 = create_label2()
def display_key_event(symbol, modifiers, action):
text = format("Event: key with code %d %s" % (symbol, action))
label1.text = text
text = "Modifiers: "
if modifiers & pyglet.window.key.MOD_SHIFT:
text = text + "Shift "
if modifiers & pyglet.window.key.MOD_CTRL:
text = text + "Ctrl "
if modifiers & pyglet.window.key.MOD_ALT:
text = text + "Alt "
label2.text = text
on_draw()
print(symbol, modifiers)
@window.event
def on_draw():
window.clear()
label1.draw()
label2.draw()
@window.event
def on_key_press(symbol, modifiers):
display_key_event(symbol, modifiers, "pressed")
@window.event
def on_key_release(symbol, modifiers):
display_key_event(symbol, modifiers, "released")
pyglet.app.run()
7. Třetí demonstrační příklad: vizuální zobrazení stisku kláves Shift a Control
Třetí demonstrační příklad je již složitější, protože v něm rozlišujeme stisk modifikátoru na levé či naopak na pravé straně klávesnice (většina klávesnic totiž všechny tři základní modifikátory zdvojuje, i když pravý Alt bývá popsán odlišně). Nyní však nebudeme testovat přímo parametr modifiers, protože ten neumí toto rozlišení provést, ale musíme reagovat přímo na stisk příslušné klávesy. Nejprimitivnější řešení může vypadat takto:
def display_key_event(symbol, modifiers, new_color):
if symbol == pyglet.window.key.LCTRL:
foo()
elif symbol == pyglet.window.key.RCTRL:
bar()
elif symbol == pyglet.window.key.LSHIFT:
baz()
elif symbol == pyglet.window.key.RSHIFT:
xyzzy()
Obrázek 3: Žádná kombinace kláves Ctrl či Shift není stisknuta.
Vykreslení stavu modifikátorů je nyní provedeno odlišně, protože do okna zobrazíme popisky kláves a budeme měnit jejich barvu. Implicitní barva nestlačené klávesy je šedá:
def create_gray_label(text, x, y, anchor_x, anchor_y):
return pyglet.text.Label(text,
font_size=36,
x=x,
y=y,
anchor_x=anchor_x,
anchor_y=anchor_y,
color=GRAY)
Změna barvy příslušného návěští se provede snadno – stisk klávesy změní pozadí na červenou, puštění pak zpět na šedou:
GRAY = (128, 128, 128, 255)
RED = (255, 128, 128, 255)
def display_key_event(symbol, modifiers, new_color):
if symbol == pyglet.window.key.LCTRL:
label_left_control.color = new_color
elif symbol == pyglet.window.key.RCTRL:
label_right_control.color = new_color
elif symbol == pyglet.window.key.LSHIFT:
label_left_shift.color = new_color
elif symbol == pyglet.window.key.RSHIFT:
label_right_shift.color = new_color
on_draw()
@window.event
def on_key_press(symbol, modifiers):
display_key_event(symbol, modifiers, RED)
@window.event
def on_key_release(symbol, modifiers):
display_key_event(symbol, modifiers, GRAY)
Obrázek 4: Je stlačen levý Control a současně i pravý Shift.
Úplný zdrojový kód třetího demonstračního příkladu vypadá následovně:
#!/usr/bin/env python
import pyglet
GRAY = (128, 128, 128, 255)
RED = (255, 128, 128, 255)
def create_window(width, height):
return pyglet.window.Window(width=width,
height=height,
caption="Pyglet library")
def create_gray_label(text, x, y, anchor_x, anchor_y):
return pyglet.text.Label(text,
font_size=36,
x=x,
y=y,
anchor_x=anchor_x,
anchor_y=anchor_y,
color=GRAY)
def create_label_left_control():
return create_gray_label('Ctrl', 10, 10, 'left', 'bottom')
def create_label_right_control():
return create_gray_label('Ctrl', window.width-10, 10, 'right', 'bottom')
def create_label_left_shift():
return create_gray_label('Shift', 10, 60, 'left', 'bottom')
def create_label_right_shift():
return create_gray_label('Shift', window.width-10, 60, 'right', 'bottom')
window = create_window(640, 480)
label_left_control = create_label_left_control()
label_right_control = create_label_right_control()
label_left_shift = create_label_left_shift()
label_right_shift = create_label_right_shift()
def display_key_event(symbol, modifiers, new_color):
if symbol == pyglet.window.key.LCTRL:
label_left_control.color = new_color
elif symbol == pyglet.window.key.RCTRL:
label_right_control.color = new_color
elif symbol == pyglet.window.key.LSHIFT:
label_left_shift.color = new_color
elif symbol == pyglet.window.key.RSHIFT:
label_right_shift.color = new_color
on_draw()
@window.event
def on_draw():
window.clear()
label_left_control.draw()
label_right_control.draw()
label_left_shift.draw()
label_right_shift.draw()
@window.event
def on_key_press(symbol, modifiers):
display_key_event(symbol, modifiers, RED)
@window.event
def on_key_release(symbol, modifiers):
display_key_event(symbol, modifiers, GRAY)
pyglet.app.run()
8. Pole se stavy všech kláves
V předchozím programovém kódu jsme si museli sami hlídat, které klávesy (z těch, které nás zajímají) byly stisknuty a které naopak nikoli. To vede k nutnosti použití stavových proměnných či atributů. Vzhledem k tomu, že se tato činnost ve hrách používá prakticky pořád, nabízí knihovna Pyglet zjednodušení celého procesu – k dispozici je pole obsahující příznaky stisku všech kláves na klávesnici. Příznaky se nastavují (z pohledu programátora) zcela automaticky. Konfigurace se provede takto: nejdříve se musí vytvořit okno, pro něhož klávesy zachytáváme a následně se registruje „KeyStateHandler“:
window = create_window(640, 480)
keys = pyglet.window.key.KeyStateHandler()
window.push_handlers(keys)
Nyní máme k dispozici objekt keys použitelný následujícím způsobem kdekoli v kódu:
if keys[pyglet.window.key.A]:
...
if keys[pyglet.window.key.F1]:
...
if keys[pyglet.window.key._1]:
...
if keys[pyglet.window.key.LCTRL]:
label_left_control.color = RED
else:
label_left_control.color = GRAY
if keys[pyglet.window.key.RCTRL]:
label_right_control.color = RED
else:
label_right_control.color = GRAY
Velkou předností je, že nemusíme používat žádné callback funkce ani si pamatovat stav stisknutých kláves. Tyto operace se sice stále provádí, ale interně knihovnou Pyglet.
Obrázek 5: Není stisknut ani levý ani pravý Control/Ctrl.
9. Čtvrtý demonstrační příklad: využití pole se stavy všech kláves
Ve čtvrtém demonstračním příkladu je ukázáno, jakým způsobem je možné velmi snadno otestovat stav dvou modifikátorů – levé a pravé klávesy Ctrl/Control. To může být užitečné například ve hrách typu pinball atd. Naprosto stejným postupem samozřejmě můžete pracovat i se všemi dalšími klávesami:
#!/usr/bin/env python
import pyglet
GRAY = (128, 128, 128, 255)
RED = (255, 128, 128, 255)
def create_window(width, height):
return pyglet.window.Window(width=width,
height=height,
caption="Pyglet library")
def create_gray_label(text, x, y, anchor_x, anchor_y):
return pyglet.text.Label(text,
font_size=36,
x=x,
y=y,
anchor_x=anchor_x,
anchor_y=anchor_y,
color=GRAY)
def create_label_left_control():
return create_gray_label('Ctrl', 10, 10, 'left', 'bottom')
def create_label_right_control():
return create_gray_label('Ctrl', window.width-10, 10, 'right', 'bottom')
window = create_window(640, 480)
keys = pyglet.window.key.KeyStateHandler()
window.push_handlers(keys)
label_left_control = create_label_left_control()
label_right_control = create_label_right_control()
@window.event
def on_draw():
window.clear()
if keys[pyglet.window.key.LCTRL]:
label_left_control.color = RED
else:
label_left_control.color = GRAY
if keys[pyglet.window.key.RCTRL]:
label_right_control.color = RED
else:
label_right_control.color = GRAY
label_left_control.draw()
label_right_control.draw()
pyglet.app.run()
Obrázek 6: Příklad po stisku pravé klávesy Control/Ctrl.
10. Událost on_text aneb detekce napsaných (Unicode) znaků
Ve chvíli, kdy je zapotřebí pracovat na úrovni jednotlivých znaků či dokonce celých textů, si již nevystačíme se symboly kláves definovanými v modulu pyglet.window.key. Je tomu tak z toho prostého důvodu, že by bylo nutné programově emulovat aktuální rozložení klávesnice (CZ, CZ_QWERTY a stovky dalších variant) a skládat z jednotlivých stisků kláves znaky. Ostatně stačí si jen uvědomit, kolika způsoby se zapisují znaky s českými nabodeníčky na CZ klávesnici (mrtvé klávesy atd.). Aby se zamezilo této neustále se opakující činnosti, nabízí knihovna Pyglet další callback funkci nazvanou on_text:
<strong>@window.event</strong>
def on_text(text):
pass
Této callback funkci se obecně automaticky předává napsaný text, ale ve skutečnosti se prakticky vždy bude jednat o jediný znak.
Obrázek 7: Zápis znaku z původní ASCII.
Obrázek 8: Zápis znaku s tuzemským nabodeníčkem.
11. Pátý demonstrační příklad: použití události typu on_text
Použití výše zmíněné callback funkce on_text je ukázáno v dalším demonstračním příkladu, který na zápis znaku reaguje následujícím způsobem – vypíše znak do okna a současně i na standardní výstup:
@window.event
def on_text(text):
text = format("Event: following text has been entered: '%s'" % text)
label.text = text
print(text)
on_draw()
Úplný zdrojový kód pátého demonstračního příkladu vypadá následovně:
#!/usr/bin/env python
import pyglet
def create_window(width, height):
return pyglet.window.Window(width=width,
height=height,
caption="Pyglet library")
def create_label():
return pyglet.text.Label("Event:",
font_size=18,
x=10,
y=window.height//2,
anchor_x='left',
anchor_y='center')
window = create_window(640, 480)
label = create_label()
@window.event
def on_draw():
window.clear()
label.draw()
@window.event
def on_text(text):
text = format("Event: following text has been entered: '%s'" % text)
label.text = text
print(text)
on_draw()
pyglet.app.run()
12. Problematika pohybu v textu a její řešení: událost typu on_text_motion
Další problém, který je nutné nějakým způsobem vyřešit v těch aplikacích, které pracují s textem, je pohyb kurzoru v textu. Představit si můžeme například hru, do níž je možné zapsat jméno hráče nebo používat chat. Při pohybu kurzoru v textu uživatelé velmi často používají autorepeat, který je automaticky zpracován dnes již poslední callback funkcí nazvanou on_text_motion:
<strong>@window.event</strong>
def on_text_motion(motion):
pass
V parametru motion je možné nalézt tyto hodnoty:
MOTION_UP |
MOTION_DOWN |
MOTION_LEFT |
MOTION_RIGHT |
MOTION_PREVIOUS_WORD |
MOTION_NEXT_WORD |
MOTION_BEGINNING_OF_LINE |
MOTION_END_OF_LINE |
MOTION_PREVIOUS_PAGE |
MOTION_NEXT_PAGE |
MOTION_BEGINNING_OF_FILE |
MOTION_END_OF_FILE |
MOTION_BACKSPACE |
MOTION_DELETE |
Povšimněte si, že některé hodnoty odpovídají stiskům příslušných kláves, jiné různým kombinacím kláves.
Obrázek 9: Detekce stisku a držení šipky doleva.
13. Šestý demonstrační příklad: využití události on_text_motion
V šestém příkladu se detekuje stisk (a držení) kurzorové šipky doleva a doprava:
@window.event
def on_text_motion(motion):
global x
if motion == pyglet.window.key.MOTION_LEFT:
label.text = "Motion: left"
elif motion == pyglet.window.key.MOTION_RIGHT:
label.text = "Motion: right"
print(motion)
on_draw()
Úplný zdrojový kód šestého demonstračního příkladu vypadá takto:
#!/usr/bin/env python
import pyglet
def create_window(width, height):
return pyglet.window.Window(width=width,
height=height,
caption="Pyglet library")
def create_label():
return pyglet.text.Label("Motion:",
font_size=18,
x=10,
y=window.height//2,
anchor_x='left',
anchor_y='center')
window = create_window(640, 480)
label = create_label()
@window.event
def on_draw():
window.clear()
label.draw()
@window.event
def on_text_motion(motion):
global x
if motion == pyglet.window.key.MOTION_LEFT:
label.text = "Motion: left"
elif motion == pyglet.window.key.MOTION_RIGHT:
label.text = "Motion: right"
print(motion)
on_draw()
pyglet.app.run()
Obrázek 10: Pohyb spritu pomocí kurzorových šipek.
14. Sedmý demonstrační příklad: událost on_text_motion a pohyb spritu ve scéně
Poslední demonstrační příklad kombinuje několik technik, zejména pak detekci stisku (a držení) kurzorových kláves a taktéž zobrazení spritů. Po spuštění příkladu se zobrazí sprite, kterým lze na obrazovce pohybovat pomocí kurzorových šipek. Vykreslení spritu je primitivní:
@window.event
def on_draw():
window.clear()
sprite.draw()
Pohyb spritu je řešen v callback funkci on_text_motion:
@window.event
def on_text_motion(motion):
global sprite
if motion == pyglet.window.key.MOTION_LEFT:
sprite.x -= sprite.step
elif motion == pyglet.window.key.MOTION_RIGHT:
sprite.x += sprite.step
elif motion == pyglet.window.key.MOTION_UP:
sprite.y += sprite.step
elif motion == pyglet.window.key.MOTION_DOWN:
sprite.y -= sprite.step
on_draw()
Úplný zdrojový kód sedmého demonstračního příkladu vypadá takto:
#!/usr/bin/env python
import pyglet
def create_window(width, height):
return pyglet.window.Window(width=width,
height=height,
caption="Pyglet library")
def make_sprite(filename, window):
image_stream = open("gnome-globe.png", "rb")
image = pyglet.image.load('gnome-globe.png', file=image_stream)
sprite = pyglet.sprite.Sprite(image)
# vycentrovani spritu
sprite.x = window.width / 2 - image.width / 2
sprite.y = window.height / 2 - image.height / 2
sprite.step = 5
return sprite
window = create_window(640, 480)
sprite = make_sprite("gnome-globe.png", window)
@window.event
def on_draw():
window.clear()
sprite.draw()
@window.event
def on_text_motion(motion):
global sprite
if motion == pyglet.window.key.MOTION_LEFT:
sprite.x -= sprite.step
elif motion == pyglet.window.key.MOTION_RIGHT:
sprite.x += sprite.step
elif motion == pyglet.window.key.MOTION_UP:
sprite.y += sprite.step
elif motion == pyglet.window.key.MOTION_DOWN:
sprite.y -= sprite.step
on_draw()
pyglet.app.run()
15. Repositář s demonstračními příklady
Všechny dnes popsané demonstrační příklady byly uloženy do Git repositáře dostupného na adrese https://github.com/tisnik/presentations. Příklady si můžete v případě potřeby stáhnout i jednotlivě bez nutnosti klonovat celý repositář. Pro jejich spuštění je samozřejmě nutné mít nainstalovanou jak knihovnu Pyglet, tak i podpůrné grafické knihovny OpenGL a GLU (což se většinou provede automaticky v rámci instalace balíčku s Pygletem, viz též úvodní díl tohoto seriálu):
Příklad | Odkaz |
---|---|
69_on_keypress.py | https://github.com/tisnik/presentations/blob/master/pyglet/69_on_keypress.py |
70_keyboard_modifiers.py | https://github.com/tisnik/presentations/blob/master/pyglet/70_keyboard_modifiers.py |
71_shift_ctrl_alt.py | https://github.com/tisnik/presentations/blob/master/pyglet/71_shift_ctrl_alt.py |
72_key_state.py | https://github.com/tisnik/presentations/blob/master/pyglet/72_key_state.py |
73_on_text.py | https://github.com/tisnik/presentations/blob/master/pyglet/73_on_text.py |
74_on_text_motion.py | https://github.com/tisnik/presentations/blob/master/pyglet/74_on_text_motion.py |
75_text_motion_cursor.py | https://github.com/tisnik/presentations/blob/master/pyglet/75_text_motion_cursor.py |
16. Odkazy na Internetu
- Class pyglet.graphics.vertexdomain.VertexList
https://pythonhosted.org/pyglet/api/pyglet.graphics.vertexdomain.VertexList-class.html - Class pyglet.graphics.vertexdomain.VertexDomain
https://pythonhosted.org/pyglet/api/pyglet.graphics.vertexdomain.VertexDomain-class.html - Pyglet: Module Hierarchy
https://pythonhosted.org/pyglet/api/module-tree.html - Learning Modern OpenGL
https://www.codeproject.com/articles/771225/learning-modern-opengl - OpenGL Utility Library
https://en.wikipedia.org/wiki/OpenGL_Utility_Library - GLU Specification
https://www.opengl.org/registry/doc/glu1.3.pdf - The Perlin noise math FAQ
https://mzucker.github.io/html/perlin-noise-math-faq.html - Perlin noise
https://en.wikipedia.org/wiki/Perlin_noise - Perlin Noise Generator (Python recipe)
http://code.activestate.com/recipes/578470-perlin-noise-generator/ - Simplex noise demystified
http://www.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf - glTexEnv - příkaz OpenGL
https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glTexEnv.xml - glGetTexEnv - příkaz OpenGL
https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glGetTexEnv.xml - Pyglet Home Page
https://bitbucket.org/pyglet/pyglet/wiki/Home - Pyglet: dokumentace k verzi 1.2
https://pyglet.readthedocs.io/en/pyglet-1.2-maintenance/ - Dokumentace k verzi 1.2 ve formátu PDF
https://readthedocs.org/projects/pyglet/downloads/pdf/pyglet-1.2-maintenance/ - PyOpenGL
http://pyopengl.sourceforge.net/ - The #! magic, details about the shebang/hash-bang mechanism on various Unix flavours
https://www.in-ulm.de/~mascheck/various/shebang/ - Shebang (Unix)
https://en.wikipedia.org/wiki/Shebang_%28Unix%29 - Domovská stránka systému LÖVE
http://love2d.org/ - Simple DirectMedia Layer (home page)
http://www.libsdl.org/ - Simple DirectMedia Layer (Wikipedia)
https://en.wikipedia.org/wiki/Simple_DirectMedia_Layer - Seriál Grafická knihovna OpenGL
https://www.root.cz/serialy/graficka-knihovna-opengl/ - Pyglet event loop
http://pyglet.readthedocs.io/en/latest/programming_guide/eventloop.html - Decorators I: Introduction to Python Decorators
http://www.artima.com/weblogs/viewpost.jsp?thread=240808 - 3D Programming in Python - Part 1
https://greendalecs.wordpress.com/2012/04/21/3d-programming-in-python-part-1/ - A very basic Pyglet tutorial
http://www.natan.termitnjak.net/tutorials/pyglet_basic.html - Alpha blending
https://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending