Einführung in Pygame
I
n diesem Kapitel lernst du, mit der Python-Bibliothek Pygame in WebTigerPython einfache 2D-Spiele zu entwickeln, die auch auf Tablets laufen. Pygame ist eine Bibliothek für Python, mit der du ganz einfach eigene Spiele programmieren kannst. Sie bietet dir Werkzeuge um Grafiken anzuzeigen, Figuren zu bewegen und auf Tastendrücke und Mausklicks zu reagieren. Du kennst bereits die wesentlichen Python-Grundlagen (Variablen, Schleifen, Bedingungen Funktionen, Listen, Dictionaries, Tupel) und wirst nun lernen, interaktive Spiele mit Grafiken, Animationen und Benutzersteuerung zu erstellen.
Wenn ein Pygame-Programm aus einer Python--Entwicklungsumgebung oder der Console gestartet wird (s. Abbildung links), besteht das Grafik-Fenster aus einer Titelzeile mit dem Namen des Programms, Buttons zum Schließen und Ausblenden in der Titelzeile sowie einer Zeichenfläche. Im WebTigerPython wird das Pygame-Fenster als rahmenlose Fläche im Grafik-Fenster angezeigt, ohne Fenstertitel oder Schließen-Button (s.Abbildung rechts). Da der Schließen-Button WebTigerPython nicht vorhanden ist, beenden wir ein Programm durch Klick mit der rechten Maustaste. Da das bei Tablets nicht funktioniert, musst du bei diesesn Geräten ein Programm vorläufig durch Touch auf die rote Stopp -Taste beenden.
Das folgende Programm öffnet ein hellgraues Rechteck als Zeichenfläche. Das Pygame-Fenster wird in der linken unteren Ecke mit der angegebenen Breite und Höhe in das WTP Grafik-Fenster eingefügt. Kopiere das Programm mit dem Kopiere-Button in die Zwischenablage, öffne Webtigerpython und füge das Programm aus der Zwischenablage in das Editor-Fenster ein (rechte Maustaste, einsetzen). Starte das Programm und schließe es mit der rechten Maustaste oder drücke auf einem Tablet den Stopp-Button von WTP.
Programm 1.
import pygame
WIDTH = 650
HEIGHT = 450
WHITE = (255, 255, 255)
BLACK = (0, 0, 0, 0)
RED = (255, 0, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
LIGHTGREY = (240, 240, 240)
def init():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Ein leeres Fenster")
screen.fill(LIGHTGREY)
pygame.display.flip()
clock = pygame.Clock()
return screen, clock
def handle_events():
running = True
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
return running
def main():
screen, clock = init()
running = True
while running:
running = handle_events()
clock.tick(60)
pygame.quit()
main()
Struktur eines Pygame-Prgramms
Jedes Pygame-Programm beginnt mit dem Import der Pygame-Bibliothek. Dann folgt die Deklaration der benötigten Konstanten, wie in unserem ersten Bespiel verschiedene Farben als RGB-Tupel, die Breite und Höhe des Pygame-Fensters. Außerdem enthält jedes Programm mindestens die drei Funktionen init(), handle_events() und main():
init()
Die Funktion init zeichnet das Pygame-Grafikfenster in der angegebenen Farbe..
Wichtige Pygame-Anweisungen
| Zeile | Erläuterung |
|---|---|
| 14 | Alle benötigten Pygame-Module werden gestartet. |
| 15 | Das Grafikfenster mit der angegebenen Höhe und Breite wird gezeichnet. |
| 16 | Mit dieser Anweisung kann dem Programm ein Name gegeben werden, der normalerweise in der Titelzeile des Fensters erscheint. Hat in WTP keine Wirkung |
| 18 | Das Grafikfenster wird mit der Farbe HELLGRAU gefüllt. |
| 19 | Das Grafikfenster wird aktualisiert, damit alle Änderungen sichtbar werden. |
| 20 | Das Grafikfenster wird zur weiteren Verwendung zurückgegeben. |
DIese Fuktion kann für alle Programme aus Programm 1 übernommen werden. Lediglich die Hintergrundfarbe des Fensters sollte bei Bedarf geändert werden. Die Größe kann durch Verändern der Konstanten WIDTH und HEIGHT angepasst werden.
def handle_events()
Diese Funktion verarbeitet alle im Programm vorkommenden Ereignisse wie zum Beispiel Tastatureingaben sowie Mausclicks und -bewegungen. Alle Ereignisse (englisch events) werden von pygame in einer Event-Liste gesammelt. Diese Funktion wird regelmäßig aufgerufen . Wenn die Event-Liste nicht leer ist, werden nacheinander alle gesammelten Ereigniss bearbeitet solange die Funktion nicht durch return beendet wird. In unserem ersten Beispiel wird lediglich mit event.type == pygame.MOUSEBUTTONDOWN abgefragt, ob eine Maustaste gedrückt wurd und mit event.button == 3, ob es die rechte Maustaste war. Wenn beide Bedingungen erfüllt sind, gibt die Funktion den Wert False zurück und das Programm wird beendet. Wenn die Rückgabe True ist, läuft das Programm weiter. Startet man ein pygame-Programm in einer nicht browserbasierten Entwicklungsumgebung sind die hier auskommentierten Zeilen 24 und 25 zwingend erforderlich, um das Programm über den roten Schließen-Button beenden zu können.
def main()
Diese Funktion ist das sogeannte "Hauptprogramm". Zunächst wird mit screen = init() das Grafikfenster erzeugt und in der Variablen screen gespeichert. Die Variable running , deren Wert bestimmt, ob das Programm läuft, wird auf True gesetzt. In der sich anschließenen Programm-Schleife wird kontinuierlich die Funktion handle_events aufgerufen. Erst wenn diese den Wert False zurückliefert wird die Variable running auf False gesetzt und die Schleife und damit das Programm beendet. pygame.quit() bereinigt den Speicher.
Das Programm wird durch den Aufruf von main() gestartet.
|
Bearbeite jetzt Aufgabe 1 unter dem Reiter Aufgabe 1. |
Formen zeichnen
In diesem Abschnitt lernst du, geometrische Formen mit Pygame zu zeichnen. Wenn du die Funktion
def draw_shapes(screen):
# Gefülltes Rechteck
pygame.draw.rect(screen, BLUE, (50, 50, 100, 50))
# Rechteck nur mit Rand
pygame.draw.rect(screen, RED, (200, 50, 100, 50), 4)
# Rechteck mit Füllung und sichtbarem Rand
pygame.draw.rect(screen, GREEN, (350, 50, 100, 50))
pygame.draw.rect(screen, RED, (350, 50, 100, 50), 4)
# Gefüllter Kreis
pygame.draw.circle(screen, RED, (100, 180), 40)
# Kreis nur mit Rand
pygame.draw.circle(screen, BLUE, (250, 180), 40, 4)
# Kreis mit Füllung und sichtbarem Rand
pygame.draw.circle(screen, GREEN, (400, 180), 40)
pygame.draw.circle(screen, RED, (400, 180), 40, 4)
#Bogen
pygame.draw.arc(screen, (0, 0, 0), (100, 220, 300, 120), math.radians(0), math.radians(180), 6)# Gefülltes Polygon (Dreieck)
pygame.draw.polygon(screen, GREEN, [(100, 300), (150, 360), (50, 360)])
# Polygon nur mit Rand
pygame.draw.polygon(screen, BLUE, [(250, 300), (300, 360), (200, 360)], 4)
# Polygon mit Füllung und sichtbarem Rand
pygame.draw.polygon(screen, RED, [(400, 300), (450, 360), (350, 360)])
pygame.draw.polygon(screen, BLUE, [(400, 300), (450, 360), (350, 360)], 4)
pygame.display.flip()
in das erste Programm hinter der Funktion init() einfügst und in der main-Funktion vor der Schleife draw_shapes(screen) aufrufst, wird nebenstehendes Bild gezeichnet. Bei allen Zeichenanweisungen für Formen ist der erste Parameter die von init gelieferte Variable screen, dann folgt die Farbe als RGB-Tupel bzw. vorher definierte Konstante, dann verschiedene Parameter (Tupel oder einzelne Werte), die von der zu zeichnenden Form abhängen. So muss man bei Rechtecken ein Vier-Tupel mit x und y-Koordinate der linken oberen Ecke sowie Breite und Höhe angeben, bei einem Kreis ein Tupel mit den Koordinaten des Mittelpunktes und den Radius, bei einem Polygon werden die Koordinaten der Ecklunkte in einer Liste an die Zeichenfunktion übergeben. Wenn man als letzten Parameter zusätzlich eine Zahl einfügt, die die Rahmenbreite der Figur festlegt, wird nur der Rahmen in der angegebenen Farbe ohne Füllung gezeichnet, fehlt dieser Parameter wird eine in der angegebenen Farbe gefüllte Figur gezeichnet. Die folgendeTabelle listet alle wesentlichen Zeichenfunktionen von Pygame auf:
| Funktion | Bedeutung | Wichtige Parameter |
|---|---|---|
| pygame.draw.rect(screen, col, rect, width) | Zeichnet den Rahmen eines Rechtecks mit den angegebenen Maßen. Die Farbe (col) bestimmt die Rahmenfarbe und width die Breite des Rahmens in Pixel. | screen: Grafikfenster col: (R,G,B)-Tupel rect: (x, y, width, height)-Tupel width: int als Rahmenbreite |
| pygame.draw.rect(screen, col, rect) | Zeichnet ein mit der angegebenen Farbe ausgefülltes Rechteck mit den angegebenen Maßen. | screen: Grafikfenster col: (R,G,B)-Tupel rect: (x, y, width, height)-Tupel |
| pygame.draw.circle(screen, col, center, radius, width) | Zeichnet den Rand eines Kreises mit dem angegebenen Mittelpunkt und dem Radius. Der Rand wird in der angegebenen Farbe mit der angegebenen Breite gezeichnet.. | screen: Grafikfenster ;col: (RGB)-Tupel center: (x, y)-Tupel radius: int width: int als Rahmenbreite |
| pygame.draw.circle(screen, col, center, radius) | Zeichnet einen Kreis mit dem angegebenen Mittelpunkt und dem angegebenen Radius, gefüllt mit der angegebenen Farbe. | screen: Grafikfenster: col: (RGB)-Tupel center: (x, y)-Tupel radius: int |
| pygame.draw.line(screen, col, start_point, end_point, width) | Zeichnet eine gerade Linie vom Startpunkt zum Endpunkt mit der angegebenen Breite in der angegebenen Farbe. | screen: Grafikfenster col: (RGB)-Tupel start_point: (x1, y1) end_point: (x2, y2) width: Linienbreite |
| pygame.draw.ellipse(screen, col, rect, width) | Zeichnet den Rand einer Ellipse, die von dem angegebenen Rechteck (unsichtbar) umrahmt wird. Der Rand wird in der angegebenen Farbe mit der angegebenen Breite gezeichnet. | screen: Grafikfenster col: (R,G, B)-Tupel rect: (x, y, width, height) width: int als Rahmenbreite |
| pygame.draw.ellipse(screen, col, rect). | Zeichnet eine Ellipse, die von dem angegebenen Rechteck (unsichtbar) umrahmt wird, gefüllt mit der angegebenen Farbe. | screen: Grafikfenster col: (R,G, B)-Tupel rect: (x, y, width, height) |
| pygame.draw.polygon(screen, col, points, width) | Zeichnet den Rand eines Vielecks, indem die in der Liste enthaltenen Punkte verbunden werden. | screen: Grafikfenster col: (R,G,B) - Tupel points: Liste von (x, y) width: int als Rahmenbreite |
| pygame.draw.polygon(screen, col, points) | Zeichnet ein Vielecks, indem die in der Liste enthaltenen Punkte verbunden werden. Das Vieleck wird mit der angegebenen Farbe gefüllt | screen, farbe punkte: Liste von (x, y) |
| pygame.draw.arc(screen, col, rect, start_angle, stop_angle, width) | Zeichnet einen Kreisbogen- Das angegebene Rechteck gibt den Rahmen einer Ellipse an, von der der angegebene Bogen ausgeschnitten uwrd. Die beiden Winkel im Bogenmaß bestimmen den Ausschnitt des Ellipsenbogens. | screen: Grafikfenster col: (R,G,B)-Tupel rect: (x, y, width, height)-Tupel, das die Ellipse beschreibt, von der der Bogen ein Teil ist. start_angle: Der Startwinkel des Bogens (im Bogenmaß), gemessen vom rechten Rand der Ellipse gegen den Uhrzeigersinn. bogenmass = math.radian(winkel) stop_angle: Der Endwinkel des Bogens (im Bogenmaß). width: Die Strichbreite des Bogens |
Hier ist das vollständige Programm, das du kopieren und in WebTigerPython einfügen kannst.
Programm 2
import pygame
import math
WIDTH = 650
HEIGHT = 450
BLUE = (0, 0, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
LIGHTGREY = (240, 240, 240)
def init():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Ein leeres Fenster")
screen.fill(LIGHTGREY)
pygame.display.flip()
clock = pygame.Clock()
return screen, clock
def draw_shapes(screen):
# Gefülltes Rechteck
pygame.draw.rect(screen, BLUE, (50, 50, 100, 50))
# Rechteck nur mit Rand
pygame.draw.rect(screen, RED, (200, 50, 100, 50), 4)
# Rechteck mit Füllung und sichtbarem Rand
pygame.draw.rect(screen, GREEN, (350, 50, 100, 50))
pygame.draw.rect(screen, RED, (350, 50, 100, 50), 4)
# Gefüllter Kreis
pygame.draw.circle(screen, RED, (100, 180), 40)
# Kreis nur mit Rand
pygame.draw.circle(screen, BLUE, (250, 180), 40, 4)
# Kreis mit Füllung und sichtbarem Rand
pygame.draw.circle(screen, GREEN, (400, 180), 40)
pygame.draw.circle(screen, RED, (400, 180), 40, 4)
#Zeichnet einen Bogen
pygame.draw.arc(screen, (0, 0, 0), (100, 220, 300, 120), math.radians(0), math.radians(180), 6)
# Gefülltes Polygon (Dreieck)
pygame.draw.polygon(screen, GREEN, [(100, 300), (150, 360), (50, 360)])
# Polygon nur mit Rand
pygame.draw.polygon(screen, BLUE, [(250, 300), (300, 360), (200, 360)], 4)
# Polygon mit Füllung und sichtbarem Rand
pygame.draw.polygon(screen, RED, [(400, 300), (450, 360), (350, 360)])
pygame.draw.polygon(screen, BLUE, [(400, 300), (450, 360), (350, 360)], 4)
pygame.display.flip()
def handle_events():
running = True
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
return running
def main():
screen, clock = init()
draw_shapes(screen)
running = True
while running:
running = handle_events()
clock.tick(60)
pygame.quit()
main()
|
Bearbeite jetzt die Aufgabe 2 unter dem Reiter Aufgabe 1. |
Bisher haben wir nur verschiedene zweidimenstionale Grafiken programmiert. Pygame bietet aber auch die Möglichkeit Text im Grafikfenster abzubilden. Die folgende Funktion zeichnet den als Parameter an text_string übergebenen Text an der Position (0,0) in das Grafikfenster.
def draw_text(screen, text_string):
font = pygame.font.Font(None, 48)
text = font.render(text_string, True, (255, 255, 255))
text_rect = text.get_rect()
screen.blit(text, text_rect)
Die Ausgabe von Texten im Grafikfenster erfolgt in 4 Schritten:
- font = pygame.font.Font(Schriftart, Schriftgröße)
Dies Anweisung erzeugt eine Schriftart. Die Schriftart kann als String (z.B. "Arial", "Comic Sans MS",..) beliebig gewählt werden, ebenso die Schriftgröße als ganze Zahl in Punkten. Gibt man für die Schriftart None ein, wird die Systemschrift genommen. - text = font.render(Text, True, Farbe als RN-Tupel) Diese Anweisung wandelt den Text in eine Grafik um, Als erster Parameter wird der zu zeichnende Text übergeben, der zweite Parameter sollte immmer True sein, damit die Schrift schön glatt geschrieben wird, dann folgt die Schriftfarbe als RGB-Tuperl oder als Konstante.
- text_rect = text.get_rect()
In dieser Anweisung wird text_rect das Rechteck der Schriftgrafik als 4-Tupel zugewiesen. Die ersten beiden Komponenten des Tupesl sind der Startpunkt 0,0. Möchte man die Bildgrafik zentriert auf den Bildschirm schreiben verwendet man die Anweisung text_rect = text.get_rect(enter=(WIDTH // 2, HEIGHT // 2)) - screen.blit(text, text_rect)
Diese Anweisung zeichnet den Text. Anstelle von text_rect kann man auch ein Koordinatentupel als Startpunkt für den Text eingeben und dann die 3. Anweisung weglassen.
|
Teste die Funktion in WebTigerPython. Verwende dabei verschiedene Schriftarten und Schriftgrößen sowie verschiedene Positionen des Textes |

Als Anwendungsbeispiel programmieren wir eine Digitaluhr, die neben der Zeit auch das aktuelle Datum anzeigt. Zunächst müssen wir noch klären, wie man in Python an die aktuelle Zeit und das aktuelle Datum kommt.
Die folgende Funktion liest die aktuelle Zeit und das aktuelle Datum ein und gibt die Daten als formatierte Strings zurück.
from datetime import datetime
def get_current_time():
now = datetime.now()
time_str = now.strftime("%H:%M:%S")
date_str = now.strftime("%d.%m.%Y")
return time_str, date_str
| Zeile | Erläuterung |
|---|---|
| 1 | Die Funktion datetime wird von der Bibliothek datetime importiert |
| 4 | Der Variablen now wird das aktuelle Datum und die aktuelle Zeit zugewiesen. |
| 5 | Der Variablen time_str wird ein formatierteer String der aktuellen Zeit zugewiesen. |
| 6 | Der Variablen date_str wird ein formatierter String des aktuellen Datums zugewiesen. |
| 7 | Der Zeit- und der Datumsstring werden zurückgegeben. |
|
Entwickle mithilfe der Funktionen get_current_time und draw_text das Programm zur Simulation einer Digitaluhr. Beachte: Der Bildschirm muss einmal pro Sekunde aktualisiert werden. |
import pygame
from datetime import datetime
WIDTH = 650
HEIGHT = 450
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
LIGHTGREY = (240, 240, 240)
DARKGREY = (50, 50, 50)
def init():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen.fill(BLACK)
pygame.display.flip()
return screen
def draw_digital_clock(screen, time_str):
# Font für die Digitaluhr
font = pygame.font.Font(None, 120)
text = font.render(time_str, True, GREEN)
text_rect = text.get_rect(center=(WIDTH // 2, HEIGHT // 2))
screen.blit(text, text_rect)
def draw_date(screen, date_str):
# Font für das Datum
font = pygame.font.Font(None, 36)
text = font.render(date_str, True, WHITE)
text_rect = text.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 100))
screen.blit(text, text_rect)
def handle_events():
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 3: # Rechte Maustaste
return False
return True
def main():
clock = pygame.time.Clock()
screen = init()
running = True
while running:
# Aktuelle Zeit holen
now = datetime.now()
time_str = now.strftime("%H:%M:%S")
date_str = now.strftime("%d.%m.%Y")
# Bildschirm löschen
screen.fill(BLACK)
# Uhr zeichnen
draw_digital_clock(screen, time_str)
draw_date(screen, date_str)
# Display aktualisieren
pygame.display.flip()
# Events verarbeiten
running = handle_events()
# FPS begrenzen
clock.tick(1) # 1 FPS für Sekundenaktualisierung
pygame.quit()
main()
Mit der Software python.net-schulbuch.de ist es auch möglich, Bilder im Grafikfenster abzubilden. Wir entwickeln hier ein Programm, das nebenstehendes Bild zeichnet. Bevor die Python-Entwicklungsumgebung Bilder anzeigen kann, müssen diese zunächst hochgeladen werden.
Mit den folgenden Links kannst du die beiden Bilder auf deinen Rechner herunterladen: Fußballfeld Fußball
Wenn du auf den Link klickst, öffnet sich eine neue Webseite mit dem Bild. Klick dann mit der rechten Maustaste auf das Bild und wähle in dem sich öfnnenden Menü den Punkt "Bild sichern" um es auf deinem Rechner zu speichern.
Bevor ein Bild mit Netbhuch-Python in einem Programm verwendet werden kann, muaa es erst in die Entwicklungsumgebung hochgeladen werden. Gehe dabei in folgenden Schritten vor:
vorhergehender Absatz
| Schritt | Beschreibung | Bild |
|---|---|---|
| 1. | Öffne im Browser python.net-schulbuch.de | ![]() |
| 2. | Wähle im Hamburger-Menü das Layout Canvas + Output + Dateien | ![]() |
| 3. | Dateien hochladen im Hamburger Menü klicken. Die Datei fussballfeld.png auf deinem Rechner suchen und öffnen. Anschließdend die Datei fussball.png hochladen. Wenn du beide Dateien beim Hochladen auswählst, kannst du sie auch auf einmal in die Entwicklungsumgebung holen. | ![]() |
| 4. | Die hochgeladenen Dateien werden im Datei-Verzeichnis angezeigt. | ![]() |
Um Bilder mit einem Python-Programm anzeigen zu können, müssen wir sie zunächst aus dem internen Python-Dateisystem in das Programm laen. Daüfr verwenden wir folgende Funktion.
def load_images():
fussballfeld = pygame.image.load("fussballfeld.png")
ball = pygame.image.load("fussball.png")
ball_klein = pygame.transform.scale(ball,(30,30))
return fussballfeld, ball_klein
Erläuterung
| Zeile | Erläuterung |
|---|---|
| 2 | Das Bild mit dem Dateinamen fussballfeld.png wird aus dem internen Python-Speicher geladen und der Variablen fussballfeld zugewiesen. |
| 3 | Das Bild mit dem Dateinamen fussball.png wird aus dem internen Python-Speicher geladen und der Variablen ball zugewiesen. |
| 4 | Das Bild wird auf die Größe 30 x 30 Pixel verkleinert und der Variablen ball_klein zugewiesen. |
| 5 | Die Funktion gibt die beiden geladenen Bilder zurück |
Um eine Bild zeichnen zu können verwenden wir die Methode blit(bild, Position) des Objekts screen, die eine Grafik auf dem screen platziert. Die Grafik wird aber erst nach dem nächsten Aufruf von flip sichtbar. Der Parameter Position ist ein Zweier-Tupel, das die Position der linken oberen Ecke des Bildes auf dem screen angibt. Wir Verwenden folgendefunktion, um ein Bild zu zeichnen.
def draw_image(screen, img, pso):
screen.blit(img, pos)
Das folgende Programm zeichnet das oben abgebildete Bild eines Fußßballplatzes mit einem(zu großen) Bal auf dem Elfmeterpunkt.
import pygame
WIDTH = 640
HEIGHT = 400
WHITE = (255, 255, 255)
LIGHTGREY = (240, 240, 240)
def init():
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Fußballfeld")
screen.fill(WHITE)
pygame.display.flip()
return screen
def handle_events():
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
return True
def load_images():
fussballfeld = pygame.image.load("fussballfeld.png")
ball = pygame.image.load("fussball.png")
ball_klein = pygame.transform.scale(ball,(30,30))
return fussballfeld, ball_klein
def draw_image(screen, img, pos):
screen.blit(img, pos)
def main():
screen = init()
clock = pygame.time.Clock()
feld, ball = load_images()
running = True
while running:
draw_image(screen, feld,(0,0))
draw_image(screen, ball, (305, 190))
running = handle_events()
clock.tick(60)
pygame.display.flip()
pygame.quit()
main()
|
Lösung
Wichtiger Hinweis


