Kollisionen und Textausgaben¶
Lernziele
- Kollisionen
- Textausgabe
- Pixel-Kollisionen
Kollisionen¶
Als Nächstes wollen wir überprüfen, wann sich zwei Sprites überschneiden, sprich sich berühren.
Dazu machen wir ein erstes kleines Spiel.
Wir benutzen dazu die Vorlage aus dem vorherigen Kapitel,
d.h. zwei Spieler (die farbigen Räder player1 und player2) und eine Münze (coin).
Vorlage: Download HIER.
Die Spieler sollen die Münze einfangen. Wer sie zuerst berührt, der erhält einen Punkt. Eine neue Münze soll wiederum zufällige irgendwo auf dem Bildschirm auftauchen. Das Testen einer Berührung, sprich einer Kollision, muss natürlich in der Hauptschleife geschehen. Zwecks Übersichtlichkeit lagern wir diese Funktionalität, Kollision überprüfen, in eine Funktion aus und rufen die Funktion in der Hauptschleife dann auf.
Dazu erstellen wir im Block "Globale Funktionen definieren" eine Kollisions-Funktion check_collisions().
Das machen wir jetzt; führe dazu die folgenden Schritte aus:
-
Erstelle eine neue Funktion mit dem Namen
check_collisions()und sorge dafür, dass sie in der Hauptschleife aufgerufen wird. -
Es ist einer der vielen Vorteile von Sprites, dass man die Kollision von zwei Sprite-Objekten mit einem einzigen Befehl abfragen kann. Hier benutzen wir die Kollisionsabfrage
py.sprite.collide_rect(player1,coin) == True, um zu überprüfen ob sichplayer1undcoinberühren bzw.player2undcoin. Wie der Name der Funktioncollide_rect()bereits sagt, wird überprüft, ob sich die entsprechenden Rechtecke der betroffenen Sprites überlagern.Benutze den Befehl
collide_rect()in dercheck_collisions()Funktion und erstelle bei einer Berührung eine entsprechende Ausgabe auf der Konsole, z.B. "Kollision". Dies einfach mal, um es zu testen. -
Wenn
player1die Münzecoinzuerst berührt, dann soll sich die Münze an einen beliebigen neuen Ort verschieben. Der Spieler erhält dann einen Punkt.Definiere dazu eine neue Eigenschaft in der
Player()-Klasse, d.h. füge das Attributself.pointsder Klasse hinzu. In diesem Attributself.pointswerden einfach die Punkte des entsprechenden Players gespeichert. -
Wenn
player2aber die Münzecoinzuerst berührt, dann wird selbstverständlich dessen Kontostand um eins erhöht. -
Bei einer Berührung soll zusätzlich der aktuelle Kontostand auf der Konsole mittels print Befehel ausgegeben werden. Dies könnte dann so aussehen:
Textausgabe¶
Natürlich wäre es viel praktischer, wenn wir den Punktestand direkt auf dem Spielfenster ausgeben könnten, statt nur in der Konsole. Gehe dazu die folgenden Punkte der Reihe nach durch.
-
Definiere dazu zuoberst beim Block "Pygames initialisieren" eine Schrift und ihre Grösse, die geladen werden soll:
-
Das Schreiben und darstellen des Punktestandes auf dem Bildschirm lagern wieder in eine neue Funktion
draw_score()aus, damit die Hauptschleife übersichtlich bleibt. Erstelle eine solche Funktion. -
Erstelle in der Funktion
draw_score()eine neue Variable, z.B.text_string, und speichere in ihr den aktuellen Punktestand als String. -
Danach legen wir die Farbe fest und wandeln den String
text_stringin ein grafisches Textobjekt (Bild) um. Dies geht wie folgt:-
Textobjekt erstellen:
- Textobjekt auf dem Bildschirm darstellen:
-
-
Wenn du jetzt noch dafür sorgst, dass die Funktion
draw_score()in der Hauptschleife aufgerufen wird, sollte der Punktestand nun auf dem Bildschirm erscheinen.So sollte es jetzt aussehen:
-
Noch ein weiteres Textobjekt: Lass neben dem Punktestand auch noch die Zeit anzeigen, wie lange das Spiel bereits am Laufen ist.
- Die Pygame Funktion
py.time.get_ticks()könnte dir helfen. - Versuche das selbstständig im Code zu implementieren.
- Mehr Infos zur Funktion
py.time.get_ticks()findest in der Dokumentation.
Mögliche Ausgabe:
- Die Pygame Funktion
Pixel-Kollision¶
Im obigen Beispiel wird eine Kollision festgestellt, wenn sich die den Objekten zu Grunde liegenden Rechtecke überschneiden. Eine kleine Anpassung des Bauplans, d.h. der Klassen, genügt, um erst bei einer effektiven Bildüberschneidung eine Kollision zu melden. Kurz: "Melde erste eine Kollision, wenn sich die Pixel der jeweiligen Objekte überlappen."
-
Definiere in allen Klassen (also im Bauplan) eine neue Eigenschaft
self.mask. In diesen "Mask" Attributen sollen die nicht transparenten Pixel des Bildes gespeichert werden. Dies geschieht mittels der Funktionpy.mask.from_surface(). In der Klasse sollte das dann so aussehen: -
Aufgepasst: Das "Mask" Attribut ändert sich nach jedem Kostümwechsel. D.h. nach jedem Kostümwechsel muss
self.maskaktualisiert werden (dem neuen Bild entsprechend). -
Nun muss nur noch die Kollision mit einer neuen Kollisions-Funktion überprüft werden und fertig. Ersetze nun
py.sprite.collide_rect(player1, munze) == Truedurch die neue Abfrage -
Überprüfe dein Programm.





