A pygame multimédiás könyvtár
Károlyi Péter Márton · 2021.05.31.
A pygame egy platformfüggetlen multimédiás függvénykönyvtár. A programozók számára egy egységes felületet biztosít a grafikus megjelenítéshez, hangok megszólaltatásához, billentyűk, egér és botkormányok kezeléséhez. A pygame-mel megírt program működik különféle Windows verziókon, de Linuxokon, Mac OS X-en, és még néhány okostelefonon is.
A pygame egy platformfüggetlen multimédiás modul. A programozók számára egy egységes felületet biztosít a grafikus megjelenítéshez, hangok megszólaltatásához, billentyűk, egér és botkormányok kezeléséhez, miközben az egyes géptípusok, operációs rendszerek különbségeit elfedi. Így a pygame-mel megírt program működik különféle Windows verziókon, de Linuxokon, Mac OS X-en, és még néhány okostelefonon is.
A pygame.gfxdraw
modullal vonalakat, köröket és egyéb primitíveket rajzolhatunk ki. De van beépített modul szöveg képernyőre írására tetszőleges betűtípussal: pygame.font
, hang és zene megszólaltatására: pygame.mixer
és képfájlok (pl. PNG, JPG) kirajzolására is: pygame.image
.
A könyvtár egyszerűen telepíthető pip-pel, Windowoson a pip install pygame
parancs beírásával (ha megfelelően van telepítve a Python), Linuxon pedig pip3 install pygame
paranccsal. Thonny használata esetén a Tools / Manage Packages
menüponton keresztül érhető el.
Alább látható az első program. Ez kirajzol néhány kört a képernyőre, utána pedig addig vár, amíg a felhasználó be nem zárja az ablakot a nagy piros X-szel.
Az első lépés a pygame könyvtár inicializálása, ezt az pygame.init()
nevű függvénnyel tehetjük meg. Ez a függvény az összes pygame alrendszert (display, mixer, font) inicializálja.
Ezután létrehozunk egy 440×360 képpont méretű ablakot az pygame.display.set_mode()
hívással. Ennek egy tuple-ban, zárójelezve kell megadni az ablak méretét, a további paramétereivel az ablak tulajdonságai (pl. átméretehező-e) és a színmélység állítható. Ezeket most alapbeállításon hagyjuk. A következő sorral az ablak címét állítjuk: pygame.display.setcaption()
, ezután pedig kezdődhet a rajzolás!
import math
import pygame
import pygame.gfxdraw
def main():
# pygame inicializálás
pygame.init()
# ablak megnyitás
window = pygame.display.set_mode((440, 360))
pygame.display.set_caption('pygame példaprogram')
# színek
red = pygame.Color(255, 0, 0)
green = pygame.Color(0, 255, 0)
blue = pygame.Color(0, 0, 255)
# pozíció, sugár
x = 100
y = 100
r = 50
# kör
pygame.gfxdraw.circle(window, x, y, r, red)
pygame.gfxdraw.circle(window, x + r, y, r, green)
pygame.gfxdraw.circle(window, math.floor(x + r * math.cos(3.1415 / 3)), math.floor(y - r * math.sin(3.1415 / 3)), r, blue)
x = 280
y = 100
# antialias kör
pygame.gfxdraw.aacircle(window, x, y, r, red)
pygame.gfxdraw.aacircle(window, x + r, y, r, green)
pygame.gfxdraw.aacircle(window, math.floor(x + r * math.cos(3.1415 / 3)), math.floor(y - r * math.sin(3.1415 / 3)), r, blue)
x = 100
y = 280
# kitöltött kör
pygame.gfxdraw.filled_circle(window, x, y, r, red)
pygame.gfxdraw.filled_circle(window, x + r, y, r, green)
pygame.gfxdraw.filled_circle(window, math.floor(x + r * math.cos(3.1415 / 3)), math.floor(y - r * math.sin(3.1415 / 3)), r, blue)
x = 280
y = 280
# áttetsző színek
translucent_red = pygame.Color(255, 0, 0, 96)
translucent_green = pygame.Color(0, 255, 0, 96)
translucent_blue = pygame.Color(0, 0, 255, 96)
# áttetsző kör
pygame.gfxdraw.filled_circle(window, x, y, r, translucent_red)
pygame.gfxdraw.filled_circle(window, x + r, y, r, translucent_green)
pygame.gfxdraw.filled_circle(window, math.floor(x + r * math.cos(3.1415 / 3)), math.floor(y - r * math.sin(3.1415 / 3)), r, translucent_blue)
# az elvégzett rajzolások a képernyőre
pygame.display.update()
# várunk kilépésre
quit = False
while not quit:
event = pygame.event.wait()
if event.type == pygame.QUIT:
quit = True
# ablak bezárása
pygame.quit()
main()
A program köröket rajzol, négyféleképpen. Az első három körnél egyszerűen kiszínezi azokat a képpontokat (pixel), amelyek a körívre esnek. A második háromnál ennél okosabb. Ahol a körív nem pont a képpontra esik, ott a szomszédos képpontok között színátmenetet képez. Ezt az eljárást úgy nevezik, hogy antialiasing. Így a rajz szebb, a körív nem annyira recegős.
Kör rajzolásához meg kell adni a felületet, amire rajzolunk, a kör pozícióját, sugarát és a színét. Színt tároló változót a pygame.Color()
-ral hozhatunk létre, ennek többféleképpen is megadható a kívánt szín, például:
- A három színkomponens (vörös, zöld, kék) és az átlátszatlanság 0-tól 255-ig való megadásával:
pygame.Color(255, 0, 0, 255)
- A szín HTML jelölésével, hexadecimálisan:
pygame.Color('#FF0000FF')
Tehát a 255, 0, 0
vagy '#FF0000'
jelöli a vöröset, a 255, 255, 255
vagy '#FFFFFF'
pedig a fehéret. A negyedik paraméter az átlátszatlanságot adja meg, ennek 0 értéke a teljesen átlátszót 255 értéke pedig a teljesen átlátszatlant jelenti. Ez látszik a jobb alsó sarokban, ahol a köröknél az érték 255 helyett csak 96. Így azok színei keverednek. Ha nem adunk meg átlátszatlanságot, alapértelmezetten 255 lesz.
Miután elvégeztük az összes rajzolást, meg kell hívni a pygame.display.update()
függvényt, hogy az elkészült rajzot megjelenítsük. A rajzolások először csak a memóriában történtek, és igazából a hívás hatására kerül ki minden az ablakba. Ez azért előnyös, mert így a felhasználó nem fogja látni, ahogy egyesével jelennek meg az elemek, hanem csak a végeredményt – animációnál ez fontos lesz. A további rajzolásokkal a meglévő képet módosítjuk; az eredmény pedig egy újabb pygame.display.update()
hatására jelenik meg.
A pygame.gfxdraw
modul néhány rajzeleme (grafikai primitíve):
pygame.gfxdraw.pixel(felület, x, y, szín)
- képpont rajzolásapygame.gfxdraw.line(felület, x1, y1, x2, y2, szín)
- szakaszpygame.gfxdraw.circle(felület, x, y, r, szín)
- körpygame.gfxdraw.aacircle(felület, x, y, r, szín)
- antialias körpygame.gfxdraw.filled_circle(felület, x, y, r, szín)
- kitöltött körpygame.gfxdraw.trigon(felület, x1, y1, x2, y2, x3, y3, szín)
- háromszögpygame.gfxdraw.aatrigon(felület, x1, y1, x2, y2, x3, y3, szín)
- antialias háromszögpygame.gfxdraw.filled_trigon(felület, x1, y1, x2, y2, x3, y3, szín)
- kitöltött háromszögpygame.gfxdraw.rectangle(felület, téglalap, szín)
- téglalappygame.gfxdraw.box(felület, téglalap, szín)
- kitöltött téglalap
A téglalapok rajzolása annyiban bonyolultabb a többi rajzelemnél, hogy nem koordinátákat kell megadni, hanem téglalap típusú objektumokat, amelyeket Rect(x, y, szélesség, magasság)
formában lehet létrehozni.
Az egyszerű, konzolos programok lineárisan működnek: a print()
-tel mondhatunk valamit a felhasználónak, az input()
-tal pedig kérdezhetünk tőle valamit. Nem gond az, hogy az input()
megakasztja a programot, mert amíg nincs meg a bemenő adat, addig úgysem tudna továbbhaladni a program. Egy játéknál, meg általában a grafikus programoknál ez nincs így. A programnak itt egyszerre több bemenete van: a billentyűzetre és az egérre is reagálnia kell, arról nem is beszélve, hogy ha a felhasználó épp nem nyúl semelyikhez, akkor is folytatódnia kell a képernyőn látható eseményeknek. Nem akadhat meg a játék attól, hogy éppen nem nyomtuk meg egyik gombot sem!
Ezért találták ki az eseményvezérelt programozást. A pygame a programhoz beérkező eseményeket összegyűjti (billentyűzet, egérmozdulatok, időzítések, ablak bezárása), és azokat keletkezésük sorrendjében adja nekünk. Ezt a programnak egy eseményhurokban (event loop) kell feldolgoznia, amely nagyon egyszerű:
while fut_a_program:
# megvárjuk a következő eseményt
event = pygame.event.wait()
# típus szerinti esetszétválasztás
if event.type == pygame.VALAMI:
# egyik fajta esemény feldolgozása
...
elif event.type == pygame.MASIK:
# másik fajta esemény feldolgozása
...
A kezelendő esemény a pygame.event.wait()
függvénnyel kérhetjük le. Ennek típusát a type
attribútuma tartalmazza, amelynek pár jellemző értéke:
pygame.QUIT
: kilépés, a felhasználó az X-re kattintott az ablak fejlécébenpygame.MOUSEMOTION
: egérmozgáspygame.MOUSEBUTTONDOWN
: egérgomb lenyomásapygame.KEYDOWN
: billentyű lenyomása
Az event
objektum az esemény típusától függően további információkat tartalmaz. Billentyű lenyomása esetén például az event.key
tárolja a lenyomott billentyű kódját. Egérgomb lenyomása esetén pedig az event.pos
tartalmazza a kurzor pozícióját, az event.button
pedig a lenyomott gomb azonosítóját. Az event.pos
attribútum egy tuple, amelynek 0. indexű adata az x koordináta, 1. indexű pedig az y koordináta. Szükség esetén ezt kicsomagolhatjuk két külön változóba is:
x, y = event.pos # x = event.pos[0] és y = event.pos[1]
Az alábbi programban rajzolni lehet az egérrel. A működést a kód közepén lévő eseményhurok irányítja. A bal gombbal lehet rajzolni, a jobb gombbal pedig törölni az ablak tartalmát. Az eseményvezérlés kellemes vonása, hogy a program gyakorlatilag semennyire sem terheli le a számítógépet. Amíg nincs esemény, addig ugyanúgy alszik, ahogyan azt egy input()
-ra várakozás esetén is teszi.
import pygame
import pygame.gfxdraw
def main():
# pygame inicializálás
pygame.init()
# ablak megnyitás
window = pygame.display.set_mode((440, 360))
pygame.display.set_caption('pygame példaprogram')
# kirajzolás, hogy ne üres ablakkal kezdjünk
pygame.display.update()
# az eseményvezérelt hurok
quit = False
click = False
prev_x = 0
prev_y = 0
while not quit:
drawn = False
event = pygame.event.wait()
# egér kattintás
if event.type == pygame.MOUSEBUTTONDOWN:
# bal gomb = 1, középső gomb = 2, jobb gomb = 3
if event.button == 1:
click = True
prev_x, prev_y = event.pos
elif event.button == 3:
window.fill(pygame.Color('#000000'))
drawn = True
# egérgomb elengedése
if event.type == pygame.MOUSEBUTTONUP:
if event.button == 1:
click = False
# egér mozgás
if event.type == pygame.MOUSEMOTION:
x, y = event.pos
if click:
pygame.gfxdraw.line(window, prev_x, prev_y, x, y, pygame.Color('#FFFFFF'))
drawn = True
# a következő mozdulat eseményhez
prev_x, prev_y = x, y
# ablak bezárása
if event.type == pygame.QUIT:
quit = True
if drawn:
pygame.display.update()
pygame.quit()
main()
Maga az eseményhurok ennél a progamnál tulajdonképpen egy állapotgép; az egyes események jelentése eltérő attól függően, hogy mik történtek a múltban. Például az egérmozdulatnál csak akkor rajzolunk, ha előzőleg egy kattintás eseményt már feldolgoztunk. Minden mozdulatnál megjegyezzük a koordinátákat, hogy a legközelebbi ugyanilyen eseménynél tudjuk, honnan hova kell húzni a vonalat.
Előbb arról volt szó, hogy a program futásának nem szabad megszakadnia amiatt, mert eseményre vár – és aztán jött egy program forráskódja, amely nem csinál semmit, azaz alszik az események között. Hogy fog akkor a játék tovább futni, amíg a felhasználó nem nyúl se a billentyűzethez, se az egérhez? Nagyon egyszerű: létre kell hozni egy időzítőt, amely adott időközönként generál egy eseményt. Ha létrejön az esemény, annak hatására fel fog ébredni az eseményhurok – de fel fog ébredni a billentyűzet vagy az egér hatására is.
Időzítőt létrehozni az pygame.time.set_timer()
függvénnyel lehet. Ennek paraméterei a következők: 1) milyen esemény generálódjon, 2) milyen időközönként (ezredmásodperc). A hívás tehát így néz ki:
pygame.time.set_timer(pygame.USEREVENT, 20)
Az így létrehozott időzítőket kitörölni úgy lehet, hogy az adott eseményhez tartozó időzítőt 0ms-re állítjuk, tehát a pygame.USEREVENT
időzítőt így:
pygame.time.set_timer(pygame.USEREVENT, 0)
Amennyiben több időzítőre is szükségünk van a pygame.USEREVENT
és a pygame.NUMEVENTS
közötti számokat használhatjuk (pl. pygame.USEREVENT + 1
).
Az időzítő használatához az eseménykezelő hurkot kell a pygame.USEREVENT
típusú események feldolgozásával kiegészíteni, tehát a labdát pattogtató program így néz ki:
import pygame
import pygame.gfxdraw
# ablak mérete és labda sugara
WINDOW = 360
BALL_R = 10
# labda helyzete és sebessége
class Ball:
def __init__(self):
self.x = WINDOW // 2
self.y = WINDOW // 2
self.vx = 3
self.vy = 2
def main():
# pygame inicializálás
pygame.init()
# ablak megnyitás
window = pygame.display.set_mode((360, 360))
pygame.display.set_caption('pygame példaprogram')
# objektum létrehozása
ball = Ball()
# időzítő hozzáadása: 20ms; 1000 ms / 20 ms -> 50 fps
pygame.time.set_timer(pygame.USEREVENT, 20)
quit = False
# szokásos eseményhurok
while not quit:
event = pygame.event.wait()
# felhasználói esemény: ilyeneket generál az időzítő függvény
if event.type == pygame.USEREVENT:
# kitöröljük az előző pozíciójából (nagyjából)
pygame.gfxdraw.filled_circle(window, ball.x, ball.y, BALL_R, pygame.Color('#202040'))
# kiszámítjuk az új helyet
ball.x += ball.vx
ball.y += ball.vy
# visszapattanás
if (ball.x < BALL_R or ball.x > WINDOW - BALL_R):
ball.vx *= -1
if (ball.y < BALL_R or ball.y > WINDOW - BALL_R):
ball.vy *= -1
# újra kirajzolás, és mehet a képernyőre
pygame.gfxdraw.filled_circle(window, ball.x, ball.y, BALL_R, pygame.Color('#8080FF'))
pygame.display.update()
if event.type == pygame.QUIT:
quit = True
# időzítő törlése
pygame.time.set_timer(pygame.USEREVENT, 0)
pygame.quit()
main()
Itt nagyon fontos, hogy csak a kép teljes megrajzolása után hívjuk meg az pygame.display.update()
-et. Ha a törlés után is meghívnánk, akkor az animáció villódzna (flicker), így viszont szép, folytonos a megjelenítés. Törölni viszont kell, hiszen mindig az előzőleg megrajzolt képet módosítjuk.
A képfájlok beolvasása egyszerű feladat: a pygame.image
modulnak van egy load()
nevű függvénye. Ennek paramétere a betöltendő kép, ami elég sokféle formátumú lehet (a pygame dokumentációja szerint JPG, PNG, GIF (non-animated), BMP, PCX, TGA (uncompressed), TIF, LBM (and PBM), PBM (and PGM, PPM), XPM). A függvény visszatérési értéke a betöltött képet tartalmazó felület, egy pygame.Surface
típusú objektum.
A felület nagyon hasonló az ablakként létrehozott felületre, csak épp nincs sehol megjelenítve. Ahhoz, hogy a képünk a képernyőn látszódjon azt (vagy annak megfelelő részét) át kell másolnunk az ablak felületére. Ezt a blit()
nevű függvény segítségével tudjuk megtenni. Ennek első paramétere a másolandó felület, a második paramétere a második paramétere a beillesztés helye, opcionális harmadik paramétere pedig egy Rect
, ami a másolandó területet jelöli ki. A harmadik paraméter elhagyása esetén a teljes forrásfelületet másoljuk.
Tehát a lenti kód a window
felület (82, 74)
-es pozíciójába másolja az image
felület azon részét, melyet a (10, 10)
bal felső sarkú, (62, 62)
méretű téglalap (négyzet) határoz meg.
window.blit(image, (82, 74), pygame.Rect((10, 10), (62, 62)))
Az alábbi programban kihasználjuk azt, hogy a kép egy részét is lehet másolni. A program tartalmaz egy Pieces
objektumot, ami az egyes bábuk pozícióját és méretüket tartalmazza. A szokásos inicializálás után a res
könyvtárban található pieces.png
nevű képről három sakkbábut másolunk a képernyőre.
import pygame
import pygame.gfxdraw
class Pieces:
def __init__(self):
# a figurák koordinátái a képen
self.W_KING = (10, 10)
self.W_QUEEN = (72, 10)
self.W_ROOK = (134, 10)
self.W_BISHOP = (196, 10)
self.W_KNIGHT = (258, 10)
self.W_PAWN = (320, 10)
self.B_KING = (10, 70)
self.B_QUEEN = (72, 70)
self.B_ROOK = (134, 70)
self.B_BISHOP = (196, 70)
self.B_KNIGHT = (258, 70)
self.B_PAWN = (320, 70)
# a figurák mérete a képen
self.SIZE = (62, 62)
# kép betöltése
self.image = pygame.image.load('pieces.png')
def main():
# objektum létrehozása
pieces = Pieces()
# pygame inicializálás
pygame.init()
# ablak megnyitás
window = pygame.display.set_mode((320, 200))
pygame.display.set_caption('pygame példaprogram')
# rajz készítése
window.fill(pygame.Color('#90E090'))
window.blit(pieces.image, (82, 74), pygame.Rect(pieces.W_KING, pieces.SIZE))
window.blit(pieces.image, (144, 74), pygame.Rect(pieces.B_PAWN, pieces.SIZE))
window.blit(pieces.image, (206, 74), pygame.Rect(pieces.W_KNIGHT, pieces.SIZE))
# ki a képernyőre
pygame.display.update()
# szokásos várakozás a kilépésre
quit = False
while not quit:
event = pygame.event.wait()
if event.type == pygame.QUIT:
quit = True
pygame.quit()
main()
Szövegeket a pygame.font
modul segítségével lehet a képernyőre írni. Először a pygame.font.Font()
vagy a pygame.font.SysFont()
meghívásával be kell tölteni egy betűtípust. A két módszer közötti különbség, hogy a Font()
-nak egy betűtípus filet kell megadni, a SysFont()
-nak pedig egy az operációs rendszerbe telepített betűtípus nevét. Mindkét függvény második paramétere a méret és visszatérési értékük a betöltött betűtípus. Például:
font = pygame.font.SysFont('Arial', 32)
A betöltött betűtípussal ezután a font.render()
függvénnyel tudunk írni. Ennek az első paramétere a szöveg, amit ki akarunk írni, a második paramétere, hogy szeretnénk-e antialiast, a harmadik pedig, hogy milyen színnel írjon. A negyedik opcionális paraméter a háttér színét határozza meg, ha ezt nem adjuk meg átlátszó háttérre írunk. Például az "Pygame" szöveg kiírása átlátszó háttérre, fehérrel:
white = pygame.Color('#FFFFFF')
text = font.render('Pygame', True, white)
A render()
nem közvetlenül a képernyőre írja a szöveget, hanem egy felületre, amit nekünk kell a képernyőre másolni. Erről az előző fejezetben volt szó, ezek alapján a szöveg másolása a window
felület bal felső sarkába így néz ki:
window.blit(text, (0, 0))
Betűtípusokat a Windows C:\Windows\Fonts
mappájában, vagy a Linux /usr/share/fonts/truetype
mappájában lehet találni. Meg a neten egy csomó helyen, csak sajnos az ingyenes betűtípusokból hiányozni szokott a hosszú ő
és az ű
betű. A lenti rajz a Liberation Serif nevű betűtípust használja. A linkre kattintva letölthető fájlt a projekt mappájába kell tenni.
LiberationSerif-Regular.ttf letöltése
import random
import pygame
import pygame.gfxdraw
def randomcolor():
return pygame.Color(random.randrange(256), random.randrange(256), random.randrange(256), 64)
def main():
# pygame inicializálás
pygame.init()
# ablak megnyitás
window = pygame.display.set_mode((480, 200))
pygame.display.set_caption('pygame példaprogram')
white = pygame.Color('#FFFFFF')
red = pygame.Color('#FF0000')
# háttér véletlenszerű elhelyezkedésű és színű körökkel
for i in range(500):
pygame.gfxdraw.filled_circle(window,
random.randrange(0, 480),
random.randrange(0, 200),
random.randrange(10, 15),
randomcolor())
# betűtípus betöltése, 32 pont magasságal
font = pygame.font.SysFont('Arial', 32)
# különféle kiírások
text = font.render('No AntiAlias', False, white)
window.blit(text, ((480 - text.get_width()) / 2, 20))
text = font.render('With Background', False, white, red)
window.blit(text, ((480 - text.get_width()) / 2, 60))
text = font.render('Yes AntiAlias', True, white)
window.blit(text, ((480 - text.get_width()) / 2, 100))
text = font.render('Még ékezettel is működik', True, white, red)
window.blit(text, ((480 - text.get_width()) / 2, 140))
# ki a képernyőre
pygame.display.update()
# szokásos várakozás a kilépésre
quit = False
while not quit:
event = pygame.event.wait()
if event.type == pygame.QUIT:
quit = True
pygame.quit()
main()
A billentyűzet kezelése pygame-ben nem nagy ördöngősség: pygame.KEYDOWN
eseményt kapunk egy billentyű megnyomásánál, pygame.KEYUP
eseményt az elengedésénél. Az esemény adatait tároló strktúrában az alábbi adattagok érhetőek el:
event.key
: a lenyomott billentyű azonosítój.event.mod
: módosító billentyűk (shift, ctrl stb.) Mivel egyszerre több módosító is le lehet nyomva, egy bitenkénti ÉS & művelettel kell megvizsgálni azt, amelyik érdekes. A módosítók lenyomásakor külön esemény is érkezik.
Játékokban, ahol arra vagyunk kíváncsiak, hogy nyomva van-e tartva egy billentyű, nekünk kell külön megjegyezni azt. Ez egyszerűen megoldható egy logikai típusú változóval, amelynek értékét pygame.KEYDOWN
esemény esetén igazra, pygame.KEYUP
esemény esetén pedig hamisra állítjuk. Az alábbi példaprogramban pontosan ez történik. A balra ←
és jobbra →
nyilakat nyomva tartva lehet változtatni a háromszögek színét. Az Esc
gomb pedig az ablak bezárásához hasonlóan kilép a programból.
import pygame
import pygame.gfxdraw
def main():
# pygame inicializálás
pygame.init()
# ablak megnyitás
window = pygame.display.set_mode((350, 200))
pygame.display.set_caption('pygame példaprogram')
quit = False
left = False
right = False
draw = True
while not quit:
if draw:
color = pygame.Color("#00C000") if left else pygame.Color("#FF0000")
pygame.gfxdraw.filled_trigon(window, 50, 100, 150, 50, 150, 150, color)
color = pygame.Color("#00C000") if right else pygame.Color("#FF0000")
pygame.gfxdraw.filled_trigon(window, 300, 100, 200, 50, 200, 150, color)
pygame.display.update()
draw = False
event = pygame.event.wait()
if event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
left = False
draw = True
if event.key == pygame.K_RIGHT:
right = False
draw = True
if event.key == pygame.K_ESCAPE:
quit = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
left = True
draw = True
if event.key == pygame.K_RIGHT:
right = True
draw = True
if event.type == pygame.QUIT:
quit = True
pygame.quit()
main()
Az alábbi példaprogram egy szöveg beolvasását végző függvényt tartalmaz. Kell neki a LiberationSerif-Regular.ttf nevű fájl, amelyet az előző program is használt.
import random
import pygame
import pygame.gfxdraw
def input_text(x, y, width, height, bg_color, fg_color, font, surface):
clip = surface.get_clip()
destination = pygame.Rect(x, y, width, height)
surface.set_clip(destination)
user_input = ''
enter = False
quit = False
while (not quit) and (not enter):
# szöveg kirajzolása
pygame.gfxdraw.box(surface, destination, bg_color)
pygame.gfxdraw.rectangle(surface, destination, fg_color)
text = font.render(user_input + '|', True, fg_color)
surface.blit(text, destination)
pygame.display.update()
event = pygame.event.wait()
if event.type == pygame.KEYDOWN:
# enter: bevitel vége
if event.key == pygame.K_RETURN:
enter = True
# backspace: utolsó karakter törlése
elif event.key == pygame.K_BACKSPACE:
user_input = user_input[:-1]
# egyébként meg hozzáadjuk a beírt szöveghez
else:
user_input += event.unicode
if event.type == pygame.QUIT:
# visszatesszük a sorba, mert sok mindent nem tudunk vele kezdeni
pygame.event.post(event)
quit = True
surface.set_clip(clip);
return user_input
def randomcolor():
return pygame.Color(random.randrange(256), random.randrange(256), random.randrange(256))
def main():
white = pygame.Color('#FFFFFF')
black = pygame.Color('#000000')
pygame.init()
window = pygame.display.set_mode((480, 200))
pygame.display.set_caption('pygame szöveg bevitele')
font = pygame.font.SysFont('Arial', 32)
# szöveg beolvasása
for i in range(200):
pygame.gfxdraw.filled_circle(window,
random.randrange(480),
random.randrange(200),
random.randrange(20, 25),
randomcolor())
pygame.display.update()
user_input = input_text(40, 80, 400, 40, black, white, font, window)
# szöveg kirajzolása
pygame.gfxdraw.box(window, pygame.Rect(0, 0, 480, 200), black)
for i in range(200):
pygame.gfxdraw.filled_circle(window,
random.randrange(480),
random.randrange(200),
random.randrange(20, 25),
randomcolor())
text = font.render(user_input, True, white)
window.blit(text, ((480 - text.get_width()) / 2, (200 - text.get_height()) / 2))
pygame.display.update()
quit = False
while not quit:
event = pygame.event.wait()
if event.type == pygame.QUIT:
quit = True
pygame.quit()
main()