Python Tutorial
- jetzt Python programmieren lernen

Aufräumen unseres Grundgerüsts für Pygame-Anwendungen

Wir haben im Kapitel Pygame Einführung ein Grundaufbau erstellt. Diesen wollen wir in diesem Kapitel optimieren und aufräumen. Denn je mehr Übersicht, desto schneller und mehr Spaß macht die Entwicklung von Spielen.

Gehen wir Logisch wie im Flussdiagramm gezeigt nach den einzelnen Bereichen vor.

Grundgerüst für Ablauf in Pygame

Schritt 1: Import und initialisieren der Pygame-Bibliothek

Nach dem Start wird als erstes die Pygame-Bibliothek importiert und initialisiert. Ohne den Import des Moduls können wir dieses auch nicht nutzen. Daher ist das der erste Schritt in unserem Programm, alle benötigten Module zu importieren:

# Importieren u. initialisieren der Pygame-Bibliothek
import pygame

Namensraum („namespace“) importieren

Jetzt können wir uns durch den Import des Namensraums (das englische „namespace“ ist geläufiger) viel Tipparbeit sparen. Ohne dass wir im „normalen“ Bereich unseres Programmes die Namen verfügbar machen, müssten wir immer den „namespace“ dazuschreiben. Wenn wir zu. Beispiel „pygame.KEYDOWN“ abfragen wollen, reicht nach dem Import von „pygames.locals“ in den allgemeinen Namensraum „*“ dann direkt die Abfrage „KEYDOWN“. Natürlich will man nicht von jeglichem Modul, dass man importiert auch die verwendeten Namen direkt verfügbar machen, da sonst schnell ein unübersichtliches Chaos entsteht. Für uns macht es aber Pygame-Programm deutlich übersichtlicher. Als zweite Zeile kommt also der „namespace“-import:

# Importieren u. initialisieren der Pygame-Bibliothek
import pygame
from pygame.locals import *

Die Auswirkungen an einem Beispiel: somit wird später aus der deutlich längeren Zeile für die Nutzerabfrage:

if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):

dann die optimierte kürze Zeile:

if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):

Diese Zeile benötigen wir später in diesem Kapitel zum Schritt 4. Hier nur als Verständnisbeispiel!

Sollte der Import des Namespaces nicht erfolgt sein, erhalten wir dann für die optimierte Zeile einen NameError: „NameError: name 'QUIT' is not defined“.

Kürzer ist schöner und unübersichtlicher

Initialisieren (starten) von Pygame

Nur der import reicht nicht auch. Wir müssen das Modul Pygame auch initialisieren – wollte man es in deutsch sagen: „das Modul starten“. Das ist unsere dritte Anweisung in unserem ersten Block:

# Importieren u. initialisieren der Pygame-Bibliothek
import pygame
from pygame.locals import *
pygame.init()

Jetzt können wir Pygame nutzen – sehen aber noch nichts davon. Also öffnen wir erst einmal eine Ausgabe, sprich ein Fenster. Für das Fenster benötigen wir Angaben wie die Breite und die Höhe. Wir benötigen also Konstanten.

Schritt 2: Variablen und Konstanten definieren

Wir definieren unsere Konstanten für unser Ausgabefenster. Konstanten sind es deshalb, da sich die Fenstergröße in der Regel nicht ändert. Wobei im Python es direkt eine Konstanten-Definition gibt, sondern eher der Konvention (sprich die Festlegung, so macht man es am besten), dass KONSTANTENNAMEN komplett in Großbuchstaben geschrieben werden.

Wir benötigen eine Breite und eine Höhe. Bisher haben wir für jede Variable und Konstante eine extra Zeile in Python erstellt. Das werden wir nun für logisch zusammengehörige Variablen nicht mehr machen und Python erlaubt auch sehr einfach die Wertzuweisung in einer Zeile.

Für die Breite nutzen wir ein großes „W“ und für die Höhe ein großes „H“. Das große H ist jedem sofort klar. Hier kommt das „H“ aus dem Wort „Höhe“. Hier haben wir den Zufall, dass das Englische Wort für Höhe auch mit „h“ beginnt: „height“.

Bei der Breite kommt das große „W“ von dem Anfangsbuchstaben des englischen Worts „widht“. Da es üblich ist, verwenden wir diese 2 Werte mit dieser Bezeichnung und als Konstante:

# Variablen/KONSTANTEN setzen
W, H = 800, 600

Hier sind auch genutzte Farben gut untergebracht. Für die Fensterfarbe benötigen wir zum Beispiel später auch eine Hintergrundfarbe. Wir setzen hier die deutschen Namen als Konstanten. Wem englische Bezeichnungen lieber sind, kann natürlich auch mit englischen Namen arbeiten:

# Variablen/KONSTANTEN setzen
W, H = 800, 600

# Farben setzen
SCHWARZ = ( 0, 0, 0)
WEISS   = ( 255, 255, 255)

Den Bereich für die Variablen erweitern wir nach und nach, wenn wir die entsprechenden Werte in unserem Programm benötigen.

Unser bisher entstandener kompletter Code:

# Importieren u. initialisieren der Pygame-Bibliothek
import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
SCHWARZ = ( 0, 0, 0)
WEISS   = ( 255, 255, 255)

Schritt 3: Definieren und Öffnen eines neuen Fensters

Für ein Fenster benötigen wir mehrere Angaben. Wir benötigen für das Fenster unbedingt eine Breite und eine Höhe. Der Fenstertitel wäre schön (ist aber nicht zwingend notwendig.

Um das Fenster zu setzen, wir die Anweisung „display.set_mode()“ aufgerufen. Die Bezeichnung „display“ in Python ist nicht wirklich glücklich (eigentlich würde man von der Logik her eher an „screen“ denken) aber so ist es halt. Unsere Zuweisung zu der Variable „fenster“ ist einigermaßen verständlich. Allerdings kann die Ausgabe auch „fullscreen“ erfolgen (was dann nicht mehr so in die Fenster-Denkweise passt). Aber zum Verständnis ist „fenster“ als Bezeichnung gut.

fenster = pygame.display.set_mode((W, H))

Zum Setzen des Titels im Fensterkopf benötigen wir folgenden Befehl:

fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Titel für Fensterkopf")

Als letzten Angabe wollen wir noch die Uhr verfügbar machen, damit wir später die Häufigkeit der Aktualisierung einstellen können:

fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Titel für Fensterkopf")
clock = pygame.time.Clock()

Unser bisher entstandener Code komplett:

# Importieren u. initialisieren der Pygame-Bibliothek
import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
SCHWARZ = ( 0, 0, 0)
WEISS   = ( 255, 255, 255)

# Definieren und Öffnen eines neuen Fensters
fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Titel für Fensterkopf")
clock = pygame.time.Clock()

Es wird für einen Bruchteil einer Sekunde ein Fenster angezeigt und schon ist unser Programm wieder beendet. Wir benötigen also ein Hauptprogramm, dass länger läuft. Das wird im vierten Bereich umgesetzt.

Schritt 4: unsere Hauptprogramm in einer Endlosschleife

Bisher haben wir für unser Hauptprogramm eine Variable erstellt, die auf True gesetzt und in in einer while-Schleife abgefragt.

Wenn wir eine Endlosschleife erstellen wollen, können wir auch direkt while True: verwenden. Wird das Programm durch die Escape-Taste oder durch das entsprechende im Fensterkopf beendet, können wir direkt das Programm über pygame.quit() beenden.

Innerhalb unseres Hauptprogrammes kommt die Abfrage für die Nutzeraktion. Diese haben wir uns bereits beim Schritt 1 angesehen. Somit haben wir folgenden Code:

# Importieren u. initialisieren der Pygame-Bibliothek
import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
SCHWARZ = ( 0, 0, 0)
WEISS   = ( 255, 255, 255)

# Definieren und Öffnen eines neuen Fensters
fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Titel für Fensterkopf")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while True:
    # Überprüfen, ob Nutzer eine Aktion durchgeführt hat
    for event in pygame.event.get():
        # Beenden bei [ESC] oder [X]
        if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
            pygame.quit()

Schritt 5: Logik des Spiels

Innerhalb der Hauptschleife ist es sehr sinnvoll, die Logik vom Spiel von der Ausgabe zu trennen. Dadurch entsteht sauberer Code und verschiedene Aktionen können vor einer Ausgabe abgefangen werden. Die Ausgabe selber wird dann in Schritt 6 machen. Noch gibt es nur einen Platzhalter für unsere Spielelogik.

    # Spiellogik

Schritt 6: Fenster aktualisieren

Jetzt wird Hintergrund, alle Spielfiguren gezeichnet und das Inhalt des Fensters aktualisiert. Es wird also nicht jede einzelne Figur platziert und sofort gezeichnet, sondern erst werden alle Elemente platziert und dann alle auf einen Streich in der Fensteranzeige aktualisiert. Das beschleunigt unser Programm.

    # Spielfeld löschen
    fenster.fill(HGFARBE)

    # Spielfeld/figuren zeichnen

    # Fenster aktualisieren
    pygame.display.flip()
    clock.tick(FPS)

Bei den Refresh-Zeiten bei clock.tick(FPS) muss die Konstante oben im Programm in unseren Bereich von Schritt 2 noch gesetzt werden.

Unser Grundgerüst, dass wir in den folgenden Kapiteln verwenden

Hier der komplette Code, der uns in Zukunft als Grundgerüst für jede Pygame-Anwendung dient.

# Importieren u. initialisieren der Pygame-Bibliothek
import pygame
from pygame.locals import *
pygame.init()

# Variablen/KONSTANTEN setzen
W, H = 800, 600
FPS  = 60
SCHWARZ = ( 0, 0, 0)
WEISS   = ( 255, 255, 255)

# Definieren und Öffnen eines neuen Fensters
fenster = pygame.display.set_mode((W, H))
pygame.display.set_caption("Titel für Fensterkopf")
clock = pygame.time.Clock()

# Schleife Hauptprogramm
while True:
    # Überprüfen, ob Nutzer eine Aktion durchgeführt hat
    for event in pygame.event.get():
        # Beenden bei [ESC] oder [X]
        if event.type==QUIT or (event.type==KEYDOWN and event.key==K_ESCAPE):
            pygame.quit()

    # Spiellogik

    # Spielfeld löschen
    fenster.fill(WEISS)

    # Spielfeld/figuren zeichnen

    # Fenster aktualisieren
    pygame.display.flip()
    clock.tick(FPS)