Für
Janne, Julia, Katrin und Daniel
Die Suche nach Fehlern hat so manchen Programmentwickler schon an den Rand des Wahnsinns getrieben. Zumal die schlimmsten meist so gut verborgen sind, dass man zuerst daran zweifelt, sie jemals zu finden. Etwas falsch zu machen, ist eben fast immer ärgerlich. Vielleicht hilft die folgende kleine Checkliste weiter, die man sich hin und wieder einmal anschauen sollte:
Sind vielleicht scheinbare »Kleinigkeiten« wie z.B. Komma, Punkt, Doppelpunkt vergessen worden?
Sind alle Blöcke einer Programm-Einheit (z.B. hinter if
, while
, for
, try
, def
) eingerückt?
Ist hinter Bedingungen und Funktions-Köpfen ein Doppelpunkt, haben Funktionen ihre nachfolgenden Klammern – auch wenn die Parameterlisten leer sind?
Können Bedingungen z.B. hinter if
oder while
überhaupt erfüllt werden?
Haben Variablen und Parameter, die weiterverarbeitet werden sollen, schon einen (sinnvollen) Wert?
Ist in einer Klassen-Definition ein self
vor einem Attribut oder in der Parameterliste vergessen worden?
Passt bei Zuweisungen der Typ links und rechts vom Zuweisungsoperator (=
)? Stimmen bei der Übergabe von Methodenparametern Typ und Anzahl überein?
Wurde vielleicht in einer Bedingung der Zuweisungsoperator (=
) mit dem Gleichheitsoperator (==
) verwechselt?
Python lässt sich recht einfach installieren. Du musst nur ein paar Schaltflächen anklicken, um die Installation zu steuern. Im Zweifelsfall kannst du dir aber auch von jemandem helfen lassen.
Zuerst musst du das aktuelle Python-Paket herunterladen. Dazu öffnest du deinen Browser (z.B. Google Chrome oder Microsoft Edge) und gibst dort diese Adresse ein:
https://www.python.org/downloads/
Angeboten werden zwei Versionen von Python, die sich nicht nur in einigen Punkten unterscheiden. Wir arbeiten in diesem Buch mit der aktuell neuesten Version Python 3.
Klicke also auf die Schaltfläche, über die der Download von Python 3 angeboten wird. (Während ich dieses Buch geschrieben habe, war 3.6.3 die aktuelle Version.)
Suche und öffne nun das Fenster des Ordners, in den du die Datei heruntergeladen hast – in der Regel ist das der Ordner Download.
Doppelklicke dort auf das Symbol mit dem Namen Python 3 (oder einem ähnlichen Text).
Einen Moment musst du warten, bis das Installations-Programm loslegt.
Achte zuerst darauf, dass vor den Optionen Install launcher for all users und Add Python 3 to PATH ein Häkchen steht.
Dann klicke auf Customize installation, denn wir wollen selber bestimmen, wo das Python-Paket landet.
Im nächsten Fenster kannst du alles so stehen lassen und einfach auf Next klicken – außer du willst einige Features ausschließen.
Sorge dafür, dass vor Install for all users ein Häkchen steht.
Hier kannst du dich entscheiden, in welchen Ordner die Installation erfolgen soll. Sonst kommen deine Dateien in einen AppData-Ordner im Verzeichnis C:\Users.
Gib direkt z.B. D:\Python ein (wie ich). Oder benutze die Schaltfläche Browse, um den Ordner zu finden, in dem Python landen soll. Dann klicke auf Install.
Und die Installation beginnt. Nun heißt es ein bisschen warten und geduldig sein – besonders dann, wenn dein Computer nicht der flotteste ist. Wie schnell es vorangeht, kannst du an einem Fortschrittsbalken mitverfolgen.
Schließlich kommt die Meldung, dass der ganze Prozess erfolgreich abgeschlossen wurde.
Darunter sind einige Zusatzinformation und einige Links. Klicke auf Disable path length limit und anschließend auf Close.
Auf der Seite https://www.python.org/ findest du immer die jeweils aktuelle Python-Version, darüber hinaus auch Dokumentationen und weiteres Material.
Weil Pygame nicht zum Python-Paket gehört, ist eine Extra-Installation nötig. Beginnen wir auch hier mit dem Herunterladen.
Dazu öffnest du den Browser und gehst dort auf eine dieser Download-Seiten:
http://pygame.org/download.shtml
https://sourceforge.net/projects/pygame.mirror/
https://bitbucket.org/pygame/pygame/downloads/
Blättere dort hinunter bis zur Windows-Liste. Wähle dort das letzte Angebot – wir brauchen eine Version, die für Python 3 geeignet ist.
Wahrscheinlich gibt es mittlerweile neuere Versionen. Weil auch Python sich immer weiterentwickelt, musst du eventuell mehrere Dateien herunterladen und ausprobieren, was mit deiner Python-Version zusammen funktioniert.
Klicke (bei Sourceforge) auf Download.
Dann suchst du im Ordner Download das Symbol für die heruntergeladene Datei. Sie trägt einen Namen, in dem pygame vorkommt.
Doppelklicke auf dieses Symbol und starte damit die Installation.
Du kannst das Setup-Programm auch in den Python-Ordner verschieben und von dort aus starten, dann ersparst du dir bei der Installation später eine Einstellung.
Ist die Datei keine MSI-Datei, sondern eine mit der Kennung WHL, dann musst du die Anweisungen in »Pygame installieren 2« benutzen.
Wähle Install for all users, dann klicke auf Next.
Im nächsten Dialogfeld kannst du nur auf Next klicken, wenn das Setup-Programm im Python-Ordner liegt. Sonst öffnest du mit Klick auf Python from another location ein kleines Menü.
Wähle hier den Eintrag Will be installed on local hard drive.
Nun gib den Ordner ein, in dem dein Python-System installiert ist. Dann klicke auf Next.
Wenn dieses Fenster erscheint, kannst du die Installation mit einem Klick auf Finish beenden.
Die erste Installation klappt eigentlich fast immer, leider kann es dennoch passieren, dass sich das pygame
-Modul nicht in ein Python-Programm importieren lässt, weil dort bestimmte Dateien nicht gefunden werden. In einem solchen Fall gibt es hier eine Alternativ-Installation.
Vorher aber sollte das bereits installierte Pygame-Paket wieder entfernt werden. Das geht einfach, indem du das Setup-Programm erneut aufrufst und dort Remove Python 3 pygame wählst und dann auf Finish klickst.
Danach kann Pygame sauber neu installiert werden.
Öffne nun die Eingabeaufforderung von Windows (z.B. über das Start-Menü oder indem du im Suchfenster der Taskleise cmd eingibst).
Wechsle dort mit cd in das Verzeichnis D:\Python.
Dann gib dort diese Befehlszeile ein:
py -m pip install pygame
Nun wird die zu deiner Python-Version passende Pygame-Datei aus dem Internet geholt und in die Python-Unterordner lib und include installiert.
Nun kannst du das Fenster der Eingabeaufforderung schließen, Pygame ist installiert.
Achte darauf, dass in deinem Python-Ordner lib ein Ordner mit dem Namen pygame liegt. Möglicherweise musst du ihn erst aus »site-packages« dorthin kopieren.
Wenn du die Beispiel-Projekte für Python wie auch die Lösungen nutzen willst, lassen sie sich von dieser Seite herunterladen:
http://www.mitp.de/0239
Du kannst sie dann alle in einem Ordner auf deiner Festplatte unterbringen. Ich benutze im Buch einen Ordner namens D:\Python\Projekte. (Im Ordner D:\Python habe ich bei mir auch schon das Python-Paket samt Pygame untergebracht.)
In den letzten Kapiteln hast du zwei Spiele programmiert, die man so, wie sie sind, spielen kann. Oder auch nicht, denn es wäre doch deutlich komfortabler, wenn man in beiden für das Treffen einer Wanze oder das Ausweichen einer Figur vor einem Ball Punkte sammeln könnte. Darum sollten wir uns hier noch kümmern.
Außerdem ist das Spielen mit einer Wanze (oder einem Käfer) nicht so herausfordernd wie mit einer ganzen Insektenschar. Schauen wir mal in diesem Kapitel, was sich da noch machen lässt.
In diesem Kapitel lernst du
wie man Text auf dem Spielfeld anzeigen kann
eine neue Klasse (Game
) kennen
wie man Punkte zählt und sammelt
wie man mehr als eine Wanze jagt
wie man den Timer für die Spielzeit einsetzt
Um in Pygame einen Text auf der Fensterfläche anzuzeigen, braucht man eine »Unterlage«, in die der Text quasi eingebettet wird. In Pygame heißt die Klasse dafür Surface
. Und so erzeugen wir ein passendes Objekt:
Text = pg.Surface((300,50)) Text.fill(Yellow)
Was dabei herauskommt, ist erst mal nichts weiter als eine rechteckige Fläche, die eigentlich schwarz ist, aber durch die fill
-Anweisung machen wir sie gelb, damit sie auf dem Spielfeld (noch) nicht sichtbar ist.
Als Nächstes definieren wir eine Funktion für die Anzeige von Text (→ dodger5.py):
def showMessage(text, Farbe) : global Text Font = pg.font.SysFont
("arial", 48) Text = Font.render
(text, True, Farbe)
Darin müssen wir zuerst eine Schrift haben, wir bedienen uns bei den System-Schriftarten, ich habe Arial mit der Größe 48 ausgesucht. (Probiere ruhig andere Schriftarten und -größen aus.)
Zuletzt wird der aktuelle Text gerendert, sodass man davon auch etwas sehen kann. Dabei kannst du die Anzeigefarbe bestimmen.
Rendern, was war das noch mal? Die Darstellung eines grafischen Objekts wird Rendern genannt. Das kann unter anderem ein Bild oder ein Text sein. Für viele Objekte genügt ein Aufruf von
blit()
, um sie sichtbar zu machen, in unserem Fall muss vorher der anzuzeigende Text in das Surface
-Objekt »eingenäht« werden.
Mit diesem Mitteln könnten wir jetzt die Punkte anzeigen, die der Player sammelt, wenn er dem Ball erfolgreich ausgewichen ist. Dazu brauchen wir eine weitere Funktion (→ dodger5.py):
def setScore(num) : global Punkte Punkte += num showMessage("Punkte: " + str(Punkte), Blue)
Die globale Variable Punkte
, die hier vorkommt, wird am Programmanfang auf 0 gesetzt:
Punkte = 0
Als Parameter wird die Anzahl der Punkte übernommen, um die der Punktestand steigen soll. Die Funktion showMessage()
wird dann dazu benutzt, um die Punktzahl in Blau anzuzeigen. Natürlich muss auch diese Farbe vorher definiert sein:
Blue = (0,0,255)
Erweitere den Quelltext deines Dodger-Programms um die beiden Funktionen und die zugehörigen Variablen.
Nun schauen wir mal, wo wir die neuen Funktionen ins Spiel bringen können. Zum einen soll dort, wo der Player ausgewichen ist, das Punktekonto erhöht werden:
if not Figur.isHit : Ball.move(-1, 0)if
Ball.controlRestart(xMax-50, yMax/2) :setScore
(1)
Wenn die Figur noch nicht getroffen wurde, kann sich der Ball weiterbewegen, dazu startet er neu, falls er sich ganz links, also im Playerbereich befindet. Du erinnerst dich, dass die Methode controlRestart()
einen Rückgabewert hat. Denn können wir hier gut gebrauchen.
Bei erfolgreichem Neustart des Balls wurde der Player ja nicht getroffen, also muss es hier die Punkte geben, die auch sogleich angezeigt werden. Wenn du willst, kannst du großzügiger sein, und den Punktestand auch z.B. in Zehnerschritten erhöhen. Ich war geizig, bei mir kriegt der Player pro Ausweichmanöver nur einen Punkt.
Damit man die Punktanzeige auch wirklich sehen kann, brauchen wir eine weitere blit
-Anweisung:
Fenster.blit(Text, (xMax/2, 10))
Die würde ich vor alle anderen blit
-Zeilen setzen, damit Figur und Ball in den vorderen Ebenen bleiben.
Wenn du dir die Abbildung genau anschaust, dann siehst du, dass ich da noch was hinzugeschmuggelt habe: einen Text fürs Spielende. Diese Zeile steht direkt unter der, in der isHit
sein True
bekommt:
if not Figur.dodge(Ball.y, yMax/2) :
Figur.isHit = True
showMessage
("Game over", Red)
Ist der Player getroffen, wird statt der Punkte »Game over« angezeigt.
Und nun ergänze den Quelltext, starte das Programm und sammle Punkte (→ dodger5.py).
Nun hat mittlerweile der Quelltext unseres Dodger-Programms wieder einen beachtlichen Umfang angenommen, obwohl wir doch den Player und den Ball in Klassen-Dateien ausgelagert haben. Schauen wir mal, ob da nicht mehr drin ist, um den Umfang des Hauptprogramms zu verringern.
Ich denke da vor allem an die ganzen Funktionen, die wir hier vereinbart haben. Was, wenn wir eine neue Klasse definieren und diese Funktionen zu Methoden dieser Klasse machen? Probieren wir es aus.
Erzeuge eine neue Datei und nenne sie z.B. game.py (das war meine Wahl). Markiere im Quelltext von dodger5.py den Bereich zwischen den beiden globalen Variablen (Start
, Punkte
) und der letzten Funktion getTime()
.
Kopiere den gesamten Text in die neue Datei und lösche sie dann im Dodger-Listing (oder schneide aus und füge ein).
Ich habe die neue Klasse etwas kühn Game
genannt, weil dort spielrelevante Methoden untergebracht werden sollen. Du kannst den Bestand nach und nach erweitern, wenn dir ein paar weitere (gute) Methoden einfallen.
Bevor wir uns an die Bearbeitung der Methoden machen, sollte die allererste Zeile in Quelltext von game.py diese sein:
import pygame as pg
Dann folgt der Kopf der Klasse:
class Game :
Kommen wir zu den Methoden. Hier sind sie in einem Rutsch (→ game.py):
# Startwerte und Textfeld erzeugen def __init__(self, Farbe) : self.Start = 0 self.Punkte = 0 self.Text = pg.Surface((300,50)) self.Text.fill(Farbe) # Info anzeigen def showMessage(self, text, Farbe) : self.Font = pg.font.SysFont("arial", 48) self.Text = self.Font.render(text, True, Farbe) # Punkte zählen und anzeigen def setScore(self, num, Farbe) : self.Punkte += num self.showMessage("Punkte: " + \ str(self.Punkte), Farbe) # Timer def getTime(self, Reset) : if Reset : self.Start = pg.time.get_ticks() self.Diff = pg.time.get_ticks() - self.Start return self.Diff
Wie du siehst, sind die Unterschiede nicht sonderlich groß. Neu ist eine init
-Methode, in der ein Textfeld erzeugt wird, das dann zur Anzeige aller Art von Informationen und Meldungen dienen kann. Die setScore
-Methode braucht einen weiteren Parameter, damit die Anzeigefarbe frei gewählt werden kann.
Bauen wir unser neues Klassen-Modul gleich ins Hauptprogramm ein, das jetzt so aussieht (→ dodger6.py):
import pygame as pg import random from dplayer import * from dthing import * fromgame
import * # Startwerte festlegen Red = (255,0,0) Blue = (0,0,255) Yellow = (255,255,0) xMax, yMax = 800, 400 # Pygame starten, Spiel-Elemente erzeugen pg.init() pg.key.set_repeat(20,20) pg.display.set_caption("My Game") Fenster = pg.display.set_mode((xMax, yMax)) Figur = Player(20,30) Ball = Thing("Bilder/ball1.png") Ball.setPosition(xMax-50, yMax/2, True)Spiel
=Game
(Yellow) # Ereignis-Schleife running = True while running : for event in pg.event.get() : if event.type == pg.QUIT : running = False # Tasten abfragen if event.type == pg.KEYDOWN : if event.key == pg.K_UP : Figur.setState(2)Spiel
.getTime(True) if event.key == pg.K_DOWN : Figur.setState(1)Spiel
.getTime(True) # Zeit testen, ggf. Figur zurück in Stand Zeit =Spiel
.getTime(False) if Zeit > 200 : Figur.setState(0) # Ball bewegen, ggf. zurücksetzen if not Figur.isHit : Ball.move(-1, 0) if Ball.controlRestart(xMax-50, yMax/2) :Spiel
.setScore(1, Blue) # Kontrolle, ob Ball im Kontaktbereich if (Ball.x < Figur.x+150) : # Wenn Player nicht ausweicht, Spiel-Ende if not Figur.dodge(Ball.y, yMax/2) : Figur.isHit = TrueSpiel
.showMessage("Game over", Red) # Sprite in Fenster positionieren Fenster.fill(Yellow) Fenster.blit(Spiel
.Text, (xMax/2, 10)) Fenster.blit(Figur.Bild, (Figur.x, Figur.y)) Fenster.blit(Ball.Bild, (Ball.x, Ball.y)) pg.display.update() # Pygame verlassen pg.quit()
Das neue Objekt habe ich Spiel
genannt und so erzeugt:
Spiel = Game(Yellow)
Im Spiel selber werden dann (zum Teil an mehreren Stellen) die Methoden Spiel.getTime()
, Spiel.setScore()
und Spiel.showMessage()
aufgerufen. Beachte, dass auch bei einer blit
-Anweisung der Parameter Text
jetzt zu Spiel
gehört.
Passe deinen Quelltext an und überzeuge dich davon, dass das Programm das Gleiche leistet wie das vorige.
Machen wir jetzt einen Sprung zurück zum vorigen Spiel mit der Wanze. Wie wäre es, wenn wir auch da ein Punktesystem einbauen würden? Eigentlich Blödsinn, wirst du jetzt sagen: Wenn die Wanze tot ist, ist das Spiel vorbei. Stimmt, aber wie wäre es, wenn wir nicht nur eine einzelne, sondern viele Wanzen über das Spielfeld jagen? Und du hast eine bestimmte Zeit zur Verfügung, um sie alle zu jagen? Dann macht eine Punktevergabe durchaus Sinn.
Kramen wir also unser letztes Buggy-Projekt wieder hervor und schauen wir, wie wir aus einer gleich eine Handvoll Wanzen machen. Dazu vereinbaren wir gleich am Anfang eine Variable, deren Wert du nach Belieben ändern kannst, falls dir die Anzahl nicht reicht:
bugMax = 5
Bei der Erzeugung der Figuren brauchen wir zuerst eine (leere) Liste:
Figur = []
Die füllen wir dann über eine for
-Schleife mit Insekten (→ buggy9.py):
for Nr in range(0,bugMax) : xPos = random.randint(100,xMax-100) yPos = random.randint(50,yMax-100) Figur.append(Player(xPos, yPos))
Wie du siehst, habe ich hier zwei Zufallswerte für die Position der kleinen Krabbler benutzt, damit sie bei jedem Spiel woanders auftauchen. In meinem Fall sollte es jetzt fünf Wanzen geben. Auch für die Laufrichtung brauchen wir jetzt Listen, nur so ist es möglich, dass nicht jede Wanze in dieselbe Richtung losläuft. Dazu erzeugen wir zuerst zwei weitere Listen:
xStep = [] yStep = []
Dann packen wir auch die Bestimmung der zufälligen Startrichtung in eine for
-Schleife (→ buggy9.py):
for Nr in range(0,bugMax) : xStep.append(random.randint(0,2)) if xStep[Nr] == 0 : xStep[Nr] = -1 yStep.append(random.randint(0,2)) if yStep[Nr] == 0 : yStep[Nr] = -1
In der Ereignis-Schleife muss dann nach einem Mausklick für jede Wanze einzeln kontrolliert werden, ob sie getroffen wurde:
if event.type == pg.MOUSEBUTTONDOWN : (xPos, yPos) = pg.mouse.get_pos() for Nr in range(0,bugMax) : if (xPos > Figur[Nr].x) \ and (xPos < Figur[Nr].x + 100) \ and (yPos > Figur[Nr].y) \ and (yPos < Figur[Nr].y + 100) : Figur[Nr].destroy()
Gegebenenfalls wird die getroffene Wanze »plattgelegt« (und isKilled
für diese Wanze auf True
gesetzt).
Auch die Grenzkontrolle muss nun für jede Wanze erfolgen (→ buggy9.py):
for Nr in range(0,bugMax) : if (Figur[Nr].x < 0) or (Figur[Nr].x > xMax-190) : xStep[Nr] = -xStep[Nr] if (Figur[Nr].y < 0) or (Figur[Nr].y > yMax-100) : yStep[Nr] = -yStep[Nr]
Das Gleiche gilt für die Ausrichtung der Wanze in Laufrichtung:
for Nr in range(0,bugMax) : Winkel = atan2(-yStep[Nr], xStep[Nr]) Winkel = degrees(Winkel) - 90 Figur[Nr].rotate(Winkel)
Das ist dann aber immer noch nicht alles, auch die move
-Anweisung gibt es für jedes Tierchen extra:
for Nr in range(0,bugMax) : if not Figur[Nr].isKilled : Figur[Nr].step(xStep[Nr]*2, yStep[Nr]*2) pg.time.delay(5)
Wie du siehst, habe ich die Zeitverzögerung hinter die for
-Schleife gesetzt, sonst würde das Spiel immer schneller, je mehr Wanzen erlegt worden sind. (Wenn du das wünschst, nimm die delay
-Anweisung mit in die if
-Struktur und setze den Zeitwert herunter.)
Nun müssen wir zu guter Letzt noch dafür sorgen, dass jede Wanze auch zu sehen ist. Das wird in dieser letzten Schleife erledigt (→ buggy9.py):
for Nr in range(0,bugMax) : Fenster.blit(Figur[Nr].Bild, (Figur[Nr].x, Figur[Nr].y))
Erweitere dein Buggy-Projekt um die Listen-Vereinbarungen und die zahlreichen for
-Schleifen. Am besten in der Reihenfolge, wie sie oben im Text auftauchen. Oder bediene dich bei den Download-Dateien. Dann starte das Programm und klicke platt, was geht.
Kommen wir nun zur Punktevergabe. Denn jetzt lohnt es sich ja, mein Vorschlag wäre, dass es für jede zerquetschte Wanze 50 oder gar 100 Punkte gibt. Und wenn du später das Spielfeld deutlich größer machst und deutlich mehr Wanzen darauf herumlaufen lässt, dann gibt es auch eine Menge Punkte zu sammeln.
Wie gut, dass wir im letzten Dodger-Projekt eine Game-Klasse definiert und eingesetzt haben. Die können wir nämlich hier unbesehen weiterverwenden. Zuerst wird dazu das Game
-Modul eingebunden:
from game import *
Als Nächstes vereinbaren wir ein Spiel-Objekt (diesmal mit grünem Hintergrund):
Spiel = Game(Green)
Sobald eine Wanze getroffen wurde, tritt die setScore
-Methode in Aktion:
Spiel.setScore(50, Blue) Figur[Nr].destroy()
Dabei sollte natürlich Blue
vorher als Farbe definiert worden sein:
Blue = (0,0,255)
Damit dann die Punkte auch angezeigt werden, darf ganz unten diese Zeile nicht fehlen (→ buggy10.py):
Fenster.blit(Spiel.Text, (xMax/3, 10))
Ergänze diese Zeilen und probiere aus, ob du für jeden Treffer deine Punkte bekommst.
Du kriegst mehr, als du erwartet hast? Klar, denn wenn du auf eine tote Wanze klickst, gibt es weiter Punkte. So war das aber nicht gedacht, dem müssen wir gleich einen Riegel vorschieben.
Das geht einfacher als gedacht: Wir überprüfen, ob die angeklickte Wanze eben noch gelebt hat, wenn ja, gibt es Punkte (→ buggy10.py):
if not Figur[Nr].isKilled : Spiel.setScore(50, Blue) Figur[Nr].destroy()
Anschließend wird die Wanze geplättet.
Passe dein Programm und teste es, bis alle Wanzen erlegt sind. Stimmt die erreichte Punktzahl?
Nun wird man immer irgendwann die Höchstpunktzahl erreichen können, der eigentliche Reiz dieses Spiels sollte aber sein, dass man sich dafür schon etwas mehr Mühe geben muss. Und wozu haben wir den Timer der Game
-Klasse? Ändern wir das Programm jetzt noch so um, dass dem Spieler nur eine bestimmte Zeit zur Verfügung steht, um alle oder möglichst viele Wanzen zu plätten. Dazu müssen wir zuerst den Timer starten (→ buggy11.py):
Spiel.getTime(True)
Das muss natürlich außerhalb der while
-Schleife geschehen.
Dann brauchen wir eine Variable, die innerhalb dieser Schleife ständig die aktuelle Zeit erfasst, damit wir kontrollieren können, wann die Spielzeit verstrichen ist:
Zeit = Spiel.getTime(False)
Hilfreich wäre es für den Spieler, wenn diese Zeit auch angezeigt würde. Da wir aber dazu keine passende Methode haben, müssen wir die Game-Klasse um eine erweitern (→ game.py):
def showAll(self, num, Farbe) : self.Punkte += num ptext = " | Punkte: " + str(self.Punkte) ztext = "Zeit: " + str(int(self.Diff/1000)) self.showMessage(ztext+ptext, Farbe)
Die Methode showAll()
fasst die Anzeige von Zeit und Punkten zusammen:
Spiel.showAll(0, Blue)
Hier bedeutet es, dass bei dieser Anzeige keine Punkte hinzuaddiert werden, es geht ja nur um die Anzeige der sich ändernden Zeit.
Auch weiter unten sollte der Aufruf von setScore()
so ersetzt werden (→ buggy11.py):
if not Figur[Nr].isKilled : Spiel.showAll(50, Blue)
Nachdem die Spielzeit vorbei ist, wird das zum einen durch eine entsprechende Meldung angezeigt:
if Zeit > bugMax*1500 : Spiel.showMessage("Game Over", Red) running = False
Dabei habe ich die Spielzeit von der Anzahl der vorhandenen Wanzen abhängig gemacht. Zuerst erscheint die Meldung »Game over«, dann wird running
auf False
gesetzt
Damit nach dem Verlassen der while
-Schleife das Spiel nicht zu abrupt endet, müssen wir ganz unten noch eine kleine Pause einbauen:
pg.time.delay(1500) pg.quit()
Und nun ergänze die Game-Klasse um die showAll
-Methode. Dann füge dem Buggy-Programm die Zeilen für das richtige Timing hinzu. Anschließend kannst du dein Spiel spielen, diesmal wird es aber schwieriger sein, alle Wanzen zu erwischen.
Dass du auch alles bequem herunterladen statt eintippen kannst oder hättest können, habe ich ja eigentlich oft genug erwähnt (www.mitp.de/0239).
Nun sind wir leider am Ende aller Kapitel angelangt. Es gibt bestimmt eine Menge, was in den vergangenen Kapiteln in Sachen Python und Pygame noch nicht behandelt wurde. Aber du verfügst über mehr als solide Grundlagen und bist eigentlich inzwischen in der Lage, die letzten Programme zu verbessern oder selbst neue zu programmieren.
Viel Neues gab es hier nicht, aber immerhin sind noch ein paar Wörter zu deinem Wortschatz hinzugekommen:
|
Klasse für Oberflächen zur Anzeige von Text und Grafik |
|
Klasse für Schriften |
|
Text/Schrift rendern |
Es lohnt auf jeden Fall, sich das anzuschauen, was Pygame noch zu bieten hat, z.B. unter dieser Adresse im Internet:
http://www.pygame.org/docs/
Hier findest du den kompletten Wortschatz dokumentiert. Für Python gibt es die Dokumentation auf dieser Seite:
https://docs.python.org/3/
Noch mehr zum Nachschlagen und Blättern findest du hier:
https://wiki.python.org/moin/FrontPage
Einen (kleinen?) Wermutstropfen gibt es: Alle Seiten sind in englischer Sprache.