Rechteck: rect.py
import pygame shape = pygame.surface.Surface ( ( 500, 500 ) ) pygame.draw.rect ( shape, ( 0, 250, 0 ), ( 100, 100, 300, 300 ), 5 ) pygame.image.save ( shape, "rect.tga" )
Polygon: polygon.py
import pygame shape = pygame.surface.Surface ( ( 500, 500 ) ) points = list() points.append ( ( 250, 100 ) ) points.append ( ( 400, 250 ) ) points.append ( ( 250, 400 ) ) points.append ( ( 100, 250 ) ) pygame.draw.polygon ( shape, ( 0, 250, 0 ), points, 5 ) pygame.image.save ( shape, "polygon.tga" )
Kreis: circle.py
import pygame shape = pygame.surface.Surface ( ( 500, 500 ) ) pygame.draw.circle ( shape, ( 0, 250, 0 ), ( 250, 250 ), 200, 5 ) pygame.image.save ( shape, "circle.tga" )
Ellipse: ellipse.py
import pygame shape = pygame.surface.Surface ( ( 500, 500 ) ) pygame.draw.ellipse ( shape, ( 0, 250, 0 ), ( 100, 200, 300, 100 ), 5 ) pygame.image.save ( shape, "ellipse.tga" )
Bogen: arc.py
import pygame import math shape = pygame.surface.Surface ( ( 500, 500 ) ) pygame.draw.arc ( shape, ( 0, 250, 0 ), ( 100, 200, 300, 100 ), 0, math.radians ( 270 ), 5 ) pygame.image.save ( shape, "arc.tga" )
Linie: line.py
import pygame shape = pygame.surface.Surface ( ( 500, 500 ) ) pygame.draw.line ( shape, ( 0, 250, 0 ), ( 100, 100 ), ( 400, 400 ), 5 ) pygame.image.save ( shape, "line.tga" )
Das Zeichenmodul draw stellt noch drei weitere Funktionen bereit, die sich allesamt mit dem Zeichnen von Linien beschäftigen. lines akzeptiert eine Python-Liste von Koordinaten und zeichnet eine Linie zwischen allen Listeneinträgen. Anders als polygon schließt es den Linienzug aber nicht automatisch: Dazu müssen Sie das Argument closed auf True setzen.
Die Funktionen aaline und aalines arbeiten prinzipiell wie ihre Gegenstücke ohne Präfix, verwenden jedoch Antialiasing. Die Linienbreite beträgt stets ein Pixel plus den umgebenden Weichzeichnungsbereich. Statt width heißt hier das letzte Argument blending. Geben Sie dafür True an, rechnet die Funktion überdeckte Pixel mit ein, statt sie zu überschreiben.
Listing 4 nutzt die vorgestellten Funktionen, um eine klassische optische Illusion zu erzeugen: Es zeichnet ausschließlich gerade Linien, um eine Kurve zu erzeugen (Abbildung 9). Entfernen Sie die Kommentarzeichen (#) vor den Zeilen 14 und 15, sehen Sie quasi in Zeitlupe, wie das funktioniert.
Listing 4
# Datei lineCurve.py import pygame import time size = 600 pygame.display.init() screen = pygame.display.set_mode ( ( size, size ) ) for i in range ( 0, size, 25 ): pygame.draw.line ( screen, ( 0, 250, 0 ), ( 0, i ), ( i, size ), 1 ) pygame.draw.line ( screen, ( 0, 250, 0 ), ( i, 0 ), ( size, i ), 1 ) pygame.draw.line ( screen, ( 0, 250, 0 ), ( size - i, 0 ), ( 0, i ), 1 ) pygame.draw.line ( screen, ( 0, 250, 0 ), ( i, size ), ( size, size - i ), 1 ) #time.sleep ( .5 ) #pygame.display.flip() pygame.display.flip() raw_input() pygame.quit()
Bildschirm neu aufbauen
Ein Neuaufbau des gesamten Bildschirms dauert recht lange, insbesondere auf schwachbrüstigen Plattformen wie dem Raspberry Pi, aber das soll nicht bedeuten, dass Sie flip() nie verwenden dürfen. Wollen Sie etwa einen bildschirmfüllenden Hintergrund verwenden oder möchten das Ausgabefenster mit Linien unterteilen, dann rufen Sie dazu zum Abschluss Ihrer Setup-Routine ruhig flip() auf. Im Anschluss sorgen Sie dann für optimale Performance, indem Sie nur noch jene Bildteile auffrischen, die sich auch tatsächlich geändert haben.
Ein Beispiel dafür liefert das Dame-Spielbrett aus Listing 5. Jede Member-Funktion der Klasse checkers kümmert sich dabei laufend um die von ihr veränderten Bereiche. Über append versorgen Sie die Listen blackCheckers, redCheckers und clearList mit Koordinaten in Form von Tupeln. Der Ursprung des Bretts (0, 0) bezeichnet die linke obere Ecke (Abbildung 10).

Abbildung 10: Das Spielbrett und einige Dame-Steine. Durch Anhängen der Koordinaten an die Liste der roten beziehungsweise schwarzen Stücke erzeugen Sie zusätzliche Steine.
Ein Aufruf von checkers.update() leert alle Felder in der clearList, indem er sie mit der Feldfarbe überschreibt. Dann zeichnet er gemäß der Listen blackCheckers und redCheckers die Spielsteine. Falls sich dadurch eine Änderung auf dem Bildschirm ergibt, liefert die Zeichenfunktion ein rect zurück, das nun in die refreshList wandert. Nach dem Abarbeiten aller internen Zeichenfunktionen übergibt checkers.update() die refreshList an pygame.update(), das seinerseits die Änderungen auf den Bildschirm ausgibt.
Listing 5
# Datei checkers.py
import pygame
class checkers:
def __init__ ( self, screen ):
self.board = list()
self.blackCheckers = list()
self.redCheckers = list()
self.clearList = list()
self.refreshList = list()
blackRow = list()
redRow = list()
self.screen = screen
for i in range ( 4 ):
blackRow.append ( ( 128, 0, 0 ) )
blackRow.append ( ( 10, 10, 10 ) )
redRow.append ( ( 10, 10, 10 ) )
redRow.append ( ( 128, 0, 0 ) )
for i in range ( 4 ):
self.board.append ( blackRow )
self.board.append ( redRow )
def drawBoard ( self ):
x = 0
y = 0
for row in self.board:
for square in row:
pygame.draw.rect ( self.screen, square, ( x * 50, y * 50, 50, 50 ), 0 )
x += 1
x = 0
y += 1
pygame.display.flip()
def drawCheckers ( self ):
for address in self.blackCheckers:
refreshRect = pygame.draw.circle ( self.screen, ( 0, 0, 0 ), ( address [ 0 ] * 50 + 25, address [ 1 ] * 50 + 25 ), 20, 0 )
self.refreshList.append ( refreshRect )
for address in self.redCheckers:
refreshRect = pygame.draw.circle ( self.screen, ( 200, 0, 0 ), ( address [ 0 ] * 50 + 25, address [ 1 ] * 50 + 25 ), 20, 0 )
self.refreshList.append ( refreshRect )
def clearSpace ( self ):
for address in self.clearList:
refreshRect = pygame.draw.rect ( self.screen, self.board [ address [ 0 ] ] [ address [ 1 ] ], ( address [ 0 ] * 50, address [ 1 ] * 50, 50, 50 ), 0 )
self.refreshList.append ( refreshRect )
def update ( self ):
self.clearSpace()
self.drawCheckers()
pygame.display.update ( self.refreshList )
self.refreshList = list()
pygame.display.init()
screen = pygame.display.set_mode ( ( 640, 480 ) )
game = checkers ( screen )
game.drawBoard()
game.redCheckers.append ( ( 3, 0 ) )
game.blackCheckers.append ( ( 4, 2 ) )
game.clearList.append ( ( 3, 0 ) )
game.clearList.append ( ( 5, 0 ) )
game.update()
raw_input()
pygame.quit()
Ausblick: Diagramme
Mit den vorgestellten Ausgabefunktionen lassen sich auch komplexe Ausgaben rendern, wie etwa ein Diagramm samt Achsen, Beschriftungen und Datenkurve. Abbildung 11 beispielsweise visualisiert rund 8000 von einem Thermo- und Hygrometer im Büro des Autors erfasste Datenpunkte, die in Form einer CSV-Datei vorliegen.
Das zugehörige Programm lineGraph.py finden Sie als Listing auf der Heft-DVD dieser Ausgabe. Über die Klasse graph gibt es ein Raster, Achsen, Achsmarken, Beschriftungen und eine Liniengrafik aus, wobei hauptsächlich die bereits vorgestellten Funktionen zum Einsatz kommen. Darüber hinaus initialisiert graph das Zeichensatz-Modul von Pygame, um die Beschriftungen auszugeben.













