image image


image

Pizza Plane Stage 2: Aufrufen oder zurückrufen?

In dieser ersten Fortsetzung (hier geht es zu Teil 1) meines kleinen Tutorials zur Spieleprogrammierung mit TigerJython und der Bibliothek GameGrid möchte ich Euch zeigen, wie Ihr den kleinen, roten Doppeldecker mit Hilfe der Cursor-Tasten steuern könnt:

GameGrid kann die Tastatur auf zwei verschiedene Arten abfragen, einmal durch

  1. Pollen: Hier prüft man ständig mit der Methode isKeyPressed() aus GameGrid, ob eine Taste gedrückt wurde, oder
  2. durch die Verwendung von KeyEvents: Hier wird die Callbackfunktion keyCallback() aufgerufen, die mit dem benannten Parameter keyPressed oder keyReleased in makeGamegrid() registriert werden muß. keyCallback() ist eine Funktion der Spielewelt, keine (Klassen-) Methode.

Doch der Reihe nach. Hier erst einmal das vollständige Programm mit »Pollen« (Variante 1):

from gamegrid import *
import os

WIDTH = 720
HEIGHT = 480

DATAPATH = os.path.join(os.getcwd(), "data")
BGWIDTH = 1067   # Breite des Hintergrundbildes
BGWIDTH2 = 533   # BGWIDTH//2 (aufgerundet)

class Background(Actor):
    
    def __init__(self):
        Actor.__init__(self, True, os.path.join(DATAPATH, "desert.png"))
        self.speed = -1
        
    def act(self):
        self.move(self.speed)
        if self.getX() < -BGWIDTH2:
            self.setX(BGWIDTH + BGWIDTH2)

class Plane(Actor):
    
    def __init__(self):
        Actor.__init__(self, True, os.path.join(DATAPATH, "planered.png"), 3)
        self.timer = 5
        self.updown = 2
        
    def act(self):
        if isKeyPressed(38):    # UP
            if self.getY() > 20:
                self.setY(self.getY() - self.updown)
        if isKeyPressed(40):    # DOWN
            if self.getY() < HEIGHT - 20:
                self.setY(self.getY() + self.updown)
        if self.timer == 0:
            self.showNextSprite()
            self.timer = 5
        self.timer -= 1

win = makeGameGrid(WIDTH, HEIGHT, 1, Color.GRAY, True)
win.setTitle("Pizza Plane Stage 2")
win.setSimulationPeriod(20)

bg1 = Background()
bg2 = Background()
win.addActor(bg1, Location(BGWIDTH2, 260))
win.addActor(bg2, Location(BGWIDTH + BGWIDTH2, 260))
redBaron = Plane()
win.addActor(redBaron, Location(70, 200))

win.show()
win.doRun()

Hier ist isKeyPressed() Teil der act()-Methode und wird in jeder Simulationsperiode aufgerufen. Der Nachteil dieser Methode ist einmal, daß – wenn die Taste zu kurz gedrückt wird – der Tastendruck verpaßt werden kann. Außerdem wird das Event nicht verbraucht, es kann also auch mehrmals während einer Simualtionsperiode zum Actor durchgereicht werden.

Das alles geschieht bei der Callback-Funktion nicht. Um diese zu implementieren, muß sie erst einmal in makeGameGrid() registriert werden:

win = makeGameGrid(WIDTH, HEIGHT, 1, Color.GRAY, True, keyPressed = keyCallback)

Das Registrieren der Callback-Methode erfolgt ohne die eventuell vorhandenen Parameter, also auch ohne Klammern!

Dann kann die act()-Methode der Klasse Plane(Actor) auf die Bewegung des Propellers reduziert werden:

    def act(self):
        if self.timer == 0:
            self.showNextSprite()
            self.timer = 5
        self.timer -= 1

Und last but not least muß die Callback-Funtion keyCallbach(e) (jetzt natürlich mit Parameter e) auf GameGrid-Ebene definiert werden:

def keyCallback(e):
    keyCode = e.getKeyCode()
    if keyCode == 38:    # UP
        if redBaron.getY() > 30:
            redBaron.setY(redBaron.getY() - redBaron.updown)
    if keyCode == 40:    # DOWN
        if redBaron.getY() < HEIGHT - 20:
            redBaron.setY(redBaron.getY() + redBaron.updown)

Wenn man diese beiden Implementierungen miteinander vergleicht, wird man feststellen, daß in der Rückruf-Version die Auf- und Abwärts-Bewegungen des Fliegers mehr »ruckeln«. Das liegt daran, daß beim Callback das Event »konsumiert« wird, es wird also auf jeden Fall, aber auch nur genau einmal während einer Simulationsperiode zum Actor durchgereicht. Das ist in vielen Fällen ein erwünschtes Verhalten, im Falle unseres kleinen, roten Fliegers bevorzuge ich allerdings die erste Methode mit dem »Pollen«, die Bewegung wirkt hierbei fließender und organischer.

Ihr seht also, daß man sich schon beim Enturf eines Spieles Gedanken über die Event-Behandlung machen sollte: »Gehört« das Event der Spielewelt (wie zum Beispiel bei einer Multi-Agenten-Simulation)? Dann ist sicher die Callback-Funktion angebracht. Oder gehört das Event eher zum Actor (wie im Falle des kleinen, roten Doppeldeckers)? Dann ist meistens die Methode des Pollens das Mittel der Wahl.

Beide Versionen des Spiels habe ich (mit allen Assets) in mein GitLab-Repositorium hochgeladen: pizzaplane2.py ist die Version mit der direkten Tastatursteuerung (»Pollen«), während pizzaplane2cb,py die Version mit der Callback-Methode ist.


(Kommentieren) 

image image



Über …

Der Schockwellenreiter ist seit dem 24. April 2000 das Weblog digitale Kritzelheft von Jörg Kantel (Neuköllner, EDV-Leiter Rentner, 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

Diese Spalte wurde absichtlich leergelassen!


Werbung


image  image  image
image  image  image


image