image image


Pygame Zero Intro (2): Das Alien quietscht bei Mausberührung

In diesem zweiten Beitrag meiner Erkundung von Pygame Zero möchte ich einen Hauch von Interaktivität in meinem einführenden Beispielprogramm implementieren, denn ohne Interaktion kein Spiel. Der Spieler bekommt die Möglichkeit, das Alien anzuklicken und das Alien reagiert darauf. So werden gleich drei Fliegen mit einer Klatsche geschlagen: Ich lerne, wie man Mausereignisse abfragt, Texte auf dem Bildschirm ausgibt und das Bild eines Actors ändert. Ganz nebenbei spiele ich auch noch ein wenig mit der Zeitsteuerung herum.

image

Wenn das Alien angeklickt wird, soll es Eek! schreien und einen verärgerten Gesichtsausdruck annehmen. Dazu habe ich erst einmal das Bild alien_hurt.png (wieder aus der freien und empfehlenserten Sammlung von Kenney.nl) in dem Ordner images im gleichen Verzeichnis wie das Programm abgelegt, damit es das Bild auch findet. Das nur zur Vorbereitung und damit ich den Platz finde, wo ich die verdiente Erwähnung von Kenney.nl unterbrigen kann.

image

Doch jetzt zur Mausabfrage. Pygame Zero kennt nicht nur einige Befehle zur Maus- und zur Tastaturabfrage, sondern hat auch von der Pygame-Klasse Rect unter anderem alle Methoden zur Kollisionserkennung geerbt. Davon möchte ich jetzt Gebrauch machen. Zuerst einmal den einfachsten Fall: Das Alien reagiert auf den Mausklick, indem »Eek!« in der Kommandozeile ausgegeben wird:

def on_mouse_down(pos):
    if alien.collidepoint(pos):
        print("Eek!")

Das zeigt erst einmal, wie Interaktion im Prinzip funktioniert, ist aber noch nicht sehr befriedigend. Statt einer Ausgabe auf der Kommandozeile wünsche ich mir doch lieber eine Ausgabe auf dem Bildschirm. Dafür stellt Pygame Zero zwei Methoden der Klasse Screen zur Verfügung, die mit einer Vielzahl von Parametern umgehen können: screen.draw.text() und screen.draw.textbox(). Da screen.draw.textbox() die Positionierung massiv vereinfacht, habe ich diese Methode ausgewählt:

        screen.draw.textbox("Eek!", (100, 100, 200, 50))

Mein erster naiver Ansatz, dieses Kommando einfach in on_mouse_down() unterzubringen, brachte nichts, denn dort wird »Eek!« gerade einmal einen Frame lang angezeigt und das ist für das menschliche Auge nicht wahrnehmbar. Also mußte ein Timer her. Das Time-Modul aus Pythons Standardbibliothek ist da jedoch problematisch, da time.sleep() alle Events während der Schlafensperiode blockiert. Glücklicherweise bringt Pygame Zero ein eigenes Clock-Objekt mit, daß diese Beschränkung umgeht. clock.schedule_unique() braucht allerdings eine Callback-Funktion, die es aufruft und so wurden noch zwei weitere Funktionen benötigt: set_alien_hurt() und set_alien_normal(). Außerdem habe ich noch einen globalen Flag hit gebraucht, der gesetzt wird, wenn der Spieler mit der Maus das Alien getroffen hat. Die wichtigen drei Funktionen sehen also nun so aus:

def on_mouse_down(pos):
    if alien.collidepoint(pos):
        set_alien_hurt()

def set_alien_hurt():
    global hit
    alien.image = "alien_hurt"
    hit = True
    clock.schedule_unique(set_alien_normal, 1.0)

def set_alien_normal():
    global hit
    alien.image = "alien"
    hit = False

Hier sieht man dann auch, wie einfach mit der Methode actor.image() das Bild eines Actors geändert werden kann, denn alien_hurt() setzt das neue Bild und den Flag hit auf True um dann mit clock.schedule_unique(set_alien_normal, 1.0) nach einer Sekunde den Callback set_alien_normal() aufzurufen. Diese Funktion gibt dem Alien sein »normales« Bild wieder und setzt hit wieder auf False.

Den Rest erledigt die draw()-Funktion mit einer einfachen Abfrage:

def draw():
    screen.fill((0, 80, 125))
    if hit:
        screen.draw.textbox("Eek!", (100, 100, 200, 50))
    alien.draw()

Testweise habe ich den String in screen.draw.textbox() mal mit ein paar Emojis gefüttert, bekam dann allerdings die Fehlermeldung:

A Unicode character above '\\uFFFF' was found; not supported

Also nicht nur Tkinter, sondern auch Pygame Zero ist nicht vollständig Unicode-fest. Wirklich schade, da ich gerade für Spiele und Simulationen eine große Einsatzmöglichkeit für Emojis sehe.

So, und nun das vollständige Programm, das obigen Sreenshot produziert:

import pgzrun

WIDTH = 400
HEIGHT = 400
TITLE = "🐍🐍 Hällo Alien 🐍🐍"

alien = Actor("alien")
alien.pos = (200, 250)

hit = False

def draw():
    screen.fill((0, 80, 125))
    if hit:
        screen.draw.textbox("Eek!", (100, 100, 200, 50))
    alien.draw()

def update():
    alien.left += 2
    if alien.left > WIDTH:
        alien.right = 0

def on_mouse_down(pos):
    if alien.collidepoint(pos):
        set_alien_hurt()

def set_alien_hurt():
    global hit
    alien.image = "alien_hurt"
    hit = True
    clock.schedule_unique(set_alien_normal, 1.0)

def set_alien_normal():
    global hit
    alien.image = "alien"
    hit = False

pgzrun.go()

Wenn Ihr Euch bei dem Screenshot wundert, daß dort clock.schedule_unique(set_alien_normal, 200.0) steht: Ich bin ein alter Mann und in einer Sekunde bekomme ich keinen Screenshot hin, dafür habe ich mir sicherheitshalber 200 Sekunden gegönnt.

Das Progrämmchen ist sicher nicht der Weisheit letzter Schluß. Insbesondere stört mich, daß ich den Flag hit in zwei Funktionen als global deklarieren mußte. Falls also einer oder eine von Euch da draußen eine elegantere Lösung weiß, bitte ich um Mitteilung in meinen (Email-) Kommentaren.

Ansonsten macht mir das Spielen mit Pygame Zero immer mehr Spaß. Ich werde die Reihe daher fortsetzen. Still digging!

image


(Kommentieren) 

image image



Über …

Der Schockwellenreiter ist seit dem 24. April 2000 das Weblog digitale Kritzelheft von Jörg Kantel (Neuköllner, EDV-Leiter, Autor, Netzaktivist und Hundesportler — Reihenfolge rein zufällig). Hier steht, was mir gefällt. Wem es nicht gefällt, der braucht ja nicht mitzulesen. Wer aber mitliest, ist herzlich willkommen und eingeladen, mitzudiskutieren!

Alle eigenen Inhalte des Schockwellenreiters stehen unter einer Creative-Commons-Lizenz, jedoch können fremde Inhalte (speziell Videos, Photos und sonstige Bilder) unter einer anderen Lizenz stehen.

Der Besuch dieser Webseite wird aktuell von der Piwik Webanalyse erfaßt. Hier können Sie der Erfassung widersprechen.

Diese Seite verwendet keine Cookies. Warum auch? Was allerdings die iframes von Amazon, YouTube und Co. machen, entzieht sich meiner Kenntnis.


Werbung


Werbung


image  image  image
image  image  image


image