Mit Verzweigungen können Code-Blöcke nur unter bestimmten Bedingungen ausgeführt werden. Eine Bedingung ist ein Ausdruck der True
oder False
ergibt.
# Bedingungen
Um zu entscheiden, ob ein Code-Block ausgeführt werden soll, wird immer eine Bedingung überprüft. Dies kann ein mathematischer Ausdruck sein.
- Zahlen können mit den Vergleichsoperatoren
<
,>
,>=
,<=
,==
und!=
verglichen werden. - Variablen vom Typ
bool
haben den WertTrue
oderFalse
- Zudem gibt es Unterprogramme welche eine Wahrheitswert zurückliefern
x > 12 # True wenn x grösser als 12
y <= HEIGHT # True wenn y kleiner oder gleich wie HEIGHT
keyboard.a # True wenn die Taste "A" gedrückt ist
zorg.collidepoint(pos) # True wenn die Koordinaten "pos" auf den Actor "zorg" fallen
2
3
4
5
6
# Wenn-dann (if
)
Wenn Bedingung wahr, dann mache dies
if True/False:
mach_etwas()
mach_weiter()
2
3
4
- Zeile 1
True/False
wird ersetzt mit Ausdruck derTrue
oderFalse
ergibt- Zeile 2
mach_etwas()
wird ersetzt mit beliebigem Code.- Wird nur ausgeführt wenn der obige Ausdruck
True
ergibt. - Ist eingerückt.
- Zeile 4
mach_weiter()
wird ersetzt mit Code der immer ausgeführt wird.- Ist nicht mehr eingerückt.
# Beispiel
Unser Alien besitzt eine konstante horizontale Geschwindigkeit vx
und eine vertikale Geschwindigkeit vy
die durch die Beschleunigung GRAVITATION
verändert wird. Mit drei if
können die Situationen abgefangen werden, wenn der Alien den unteren, den linken oder den rechten Rand berührt:
def update(dt):
zorg.vy = zorg.vy + dt * GRAVITATION
zorg.y = zorg.y + dt * zorg.vy
zorg.x = zorg.x + dt * zorg.vx
if zorg.bottom > HEIGHT:
zorg.bottom = HEIGHT
zorg.vy = -zorg.vy
if zorg.left > WIDTH:
zorg.right = 0
if zorg.right < 0:
zorg.left = WIDTH
2
3
4
5
6
7
8
9
10
11
12
13
14
- ab Zeile 6
- Wenn die Füsse des Aliens das Fenster verlassen, dann wird die vertikale Geschwindigkeit «gespiegelt» – der Alien springt am unteren Rand ab. Zur Sicherheit wird der Alien zusätzlich auf den untersten Punkt gesetzt.
- ab Zeile 10
- Wenn der linke Rand des Aliens rechts aus dem Bild verschwindet, dann wird er auf den linken Rand des Fensters gesetzt
- ab Zeile 13
- Wenn der rechte Rand des Aliens links aus dem Bild verschwindet, dann wird er auf den rechten Rand des Fensters gesetzt
Aufgabe
Baue eine Überprüfung ein, so dass der Alien das Fenster nicht mehr verlassen kann. Du kannst entweder ein wrap
machen («links raus» heisst «rechts wieder rein») oder einfach ein Block, so dass er am Rand nicht mehr weiter kann.
# Wenn-dann-sonst-wenn-dann (if-elif
)
Wenn Bedingung wahr, dann mache dies, sonst wenn andere Bedingung wahr, dann mache das
if True/False:
mach_dies()
elif True/False:
mach_das()
elif True/False:
mach_jenes()
mach_weiter()
2
3
4
5
6
7
8
# Beispiel: Tastatur-Steuerung
Wir wollen unseren Alien mit den drei Tasten ←, → und SPACE steuern: Rechts und links setzt die horizontale Geschwindigkeit auf einen festen Wert. Die Leertaste erhöht die vertikale Geschwindigkeit nach oben.
def on_key_down(key):
if key == keys.RIGHT:
zorg.vx = SPEED
elif key == keys.LEFT:
zorg.vx = -SPEED
elif key == keys.SPACE:
zorg.vy = zorg.vy - 10
2
3
4
5
6
7
Aufgabe
Baue eine Tastatursteuerung ein. Überlege dir folgende Punkte:
- Welche Tasten möchtest du verwenden?
- Was soll ein Tastendruck machen?
# Wenn-dann-sonst (if-else)
oder auch: Wenn-dann-sonst-wenn-dann-sonst-wenn-dann-…-sonst (if-elif-else
)
Wenn Bedingung wahr, dann mache dies, sonst mach das
if True/False:
mache_dies()
else:
mache_das()
2
3
4
# Beispiel
Wir könnten z.B. überprüfen, ob bei einem Mausklick, ein Actor
getroffen wird oder nicht:
def on_mouse_down(pos):
if zorg.collidepoint(pos):
print("Treffer!")
else:
print("Daneben!")
2
3
4
5
- Zeile 1
- Wir definieren das Unterprogramm das bei einem Mausklick aufgerufen werden soll.
- Zeile 2
collidepoint
liefert True, wenn derActor
zorg
mit den Mauskoordinatenpos
«kollidiert» – also die Mauskoordinaten im Bereich des Aliens liegen.
Aufgabe
Versuche auch eine Maussteuerung einzubauen. Was könnte man damit erreichen?
# Zusammenfassung if
in Python
Alles zusammen lässt sich nun kombinieren zu:
if True/False:
mache_dies()
elif True/False:
mache_das()
else:
mache_jenes()
2
3
4
5
6
Hinweis
- Die If-Struktur in Python startet zwingend mit einem
if
. - Dann folgen 0-∞
elif
. - Am Schluss kann ein
else
stehen.
# Ereignisse in Pygame-Zero
Hierbei handelt es sich um spezielle Unterprogramme, die von Pygame-Zero automatisch aufgerufen werden, wenn ein entsprechendes Ereignis eintritt. Als Argumente erhalten wir Details zum Ereignis (Mauskoordinaten, welche Maus-Taste wurde gedrückt, welche Keyboard-Taste wurde getippt, …). Anhand dieser Details können wir entscheiden wie sich das Ereignis auf unser Spiel auswirkt.
# Tastatur
Bei den Tastatur-Ereignissen entscheidet man zwischen Taste runterdrücken und wieder loslassen. Beide von den Ereignissen aufgerufene Unterprogramme erhalten als Argument die gedrückte Taste:
def on_key_down(key):
print(key, "wurde runtergedrückt")
def on_key_up(key):
print(key, "wurde losgelassen")
2
3
4
5
Die komplette Liste der überprüfbaren Tasten findet man hier:
https://pygame-zero.readthedocs.io/en/stable/hooks.html#buttons-and-keys (opens new window)
# Maus
Die Ereignisse der Maus werden in drei Unterprogrammen zusammengefasst: «Maustaste heruntergedrückt», «Maustaste losgelassen» und «Maus verschoben»:
def on_mouse_down(pos, button):
print("Mouse button", button, "clicked at", pos)
def on_mouse_up(pos, button):
print("Mouse button", button, "released at", pos)
def on_mouse_move(pos, rel, buttons):
print("Mouse moved", button, "released at", pos, "relative distance", rel)
2
3
4
5
6
7
8
Bei allen drei Unterprogrammen können ein, mehrere und auch alle Argumente weggelassen werden!
# Clock
Ein weiteres wichtiges Ereignis sind gestellte Timer. So können wir irgendwann einen Timer starten. Wenn dieser abläuft, wird ein Unterprogramm aufgerufen:
def on_mouse_down(pos):
if zorg.collidepoint(pos):
zorg_hurt()
clock.schedule_unique(zorg_normal, 1)
else:
print("Daneben!")
def zorg_hurt():
zorg.image = "alien_hurt"
def zorg_normal():
zorg.image = "alien"
2
3
4
5
6
7
8
9
10
11
12
Solche Timer setzen wir mit clock.schedule
. Als Argument geben wir den Namen des Unterprogrammes an (ohne Klammern! – wir rufen es ja noch nicht auf) und die Dauer des Timers in Sekunden.
clock
kennt neben schedule
noch zwei weitere Befehle:
- schedule_unique – Event nur ein mal auslösen
- schedule_interval – Event immer wieder in zeitgleichen Abständen aufrufen
- unschedule – ein Event deaktivieren (nur 1. Argument)
# komplettes Beispiel
Wenn wir alle Teile dies
"""
Autor: S. Forster
Datum: 11.12.2019
Beschreibung: Alien lässt sich steuern mit Gravitation
"""
WIDTH = 600
HEIGHT = 500
SPEED = 80
zorg = Actor('alien')
zorg.x = 100
zorg.y = 100
zorg.vx = SPEED
zorg.vy = 0
BROWN = 120,102,102
EARTHBLUE = 12,23,200
MARSRED = 200,23,20
GRAVITATION = 20
GROUND = Rect((0, HEIGHT-60), (WIDTH, 60))
def zorg_hurt():
zorg.image = "alien_hurt"
def zorg_normal():
zorg.image = "alien"
def draw():
screen.clear()
screen.draw.filled_circle((120,20), 30, MARSRED)
screen.draw.filled_circle((480,320), 180, EARTHBLUE)
screen.draw.filled_rect(GROUND, BROWN)
zorg.draw()
def update(dt):
zorg.vy = zorg.vy + dt * GRAVITATION
zorg.y = zorg.y + dt * zorg.vy
zorg.x = zorg.x + dt * zorg.vx
if zorg.bottom > HEIGHT:
zorg.bottom = HEIGHT
zorg.vy = -zorg.vy
if zorg.left > WIDTH:
zorg.right = 0
if zorg.right < 0:
zorg.left = WIDTH
def on_key_down(key):
if key == keys.RIGHT:
zorg.vx = SPEED
elif key == keys.LEFT:
zorg.vx = -SPEED
elif key == keys.SPACE:
zorg.vy = zorg.vy - 10
else:
print("Die Taste", key, "ist nicht belegt ;-)")
def on_mouse_down(pos, button):
if zorg.collidepoint(pos):
zorg_hurt()
clock.schedule_unique(zorg_normal, 1)
else:
print("Daneben!")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# Weitere Steuerungsmöglichkeiten
Die Keyboard-Tasten können auch im Game-Loop abgefragt werden. Dies kann man verwenden um Steuerung zu programmieren, die nicht auf einzelne Ereignisse reagieren. Z.B. bei einem Jump & Run à la Mario würde der Sprung als Ereignis programmiert, die Seitwärtsbewegung aber im Game-Loop abgefragt werden.
Mehrere Tasten können gleichzeitig gedrückt sein!
def update(dt):
...
if keyboard.right:
zorg.vx = zorg.vx + 1
if keyboard.left:
zorg.vx = zorg.vx - 1
if keyboard.space:
zorg.vy = zorg.vy - 2
...
2
3
4
5
6
7
8
9
keyboard.right
ist sozusagen eine Variable. Sie kann True
oder False
sein, je nachdem ob die Taste momentan gedrückt ist oder nicht.
Aufgabe
Schaffst du es, die Steuerungen zu kombinieren und das Alien wie bei einem Jump & Run herumrennen zu lassen?