Projekt Snake
Die Bewegung der Schlange
Jetzt machen wir wieder einen etwas größeren Schritt.
Wir erinnern uns, die Schlange soll sich ja frei im Fenster bewegen können. Dazu nutzen wir die Tastatur um Befehle entgegen zu nehmen.
Ich habe mich für die Richtungspfeile (" ↑ " , " ↓ " , " ← " und " → ") entschieden, Ihr könnt aber auch jede andere Tastenkombination nutzen.
Die neuen (globalen!) Variablen lauten wie folgt:
...
# Farben RGB (Red, Green, Blue), jeweils 0 - 255
ROT = (255,0,0)
GRUEN = (0,255,0)
BLAU = (0,0,255)
WEISS = (255, 255, 255)
SCHAWRZ = (0, 0, 0)
# Positionen der oberen linken Ecke des Kopfes
snake_x = 400
snake_y = 200
# Groesse des Quadrats
quadrat_seite = 10
# Bewegungen auf der x- und der y-Achse
snake_bewegung_x = 0
snake_bewegung_y = 0
# Geschwindigkeiten
zeit = pygame.time.Clock()
snake_geschwindigkeit = 20
...
Mit snake_x
, snake_y
und quadrat_seite
ersetzen wir gleich die Werte aus dem Zeichnen des Rechtecks.
Die Bewegung findet durch Veränderung der Werte auf der x- oder der y-Achse
statt. Wie genau das funktioniert, schauen wir uns gleich an. Wir brauchen aber 2
Variablen, in denen die die neuen Werte speichern. Das sind
snake_bewegung_x
und snake_bewegung_y
.
Die beiden letzten Variablen brauchen wir für die Wiederholfrequenz in der der
Bildschirm aktualisiert wird. Dazu dient die Funktion pygame.time()
,
sie erwartet einen Wert in Millisekunden, ich habe hier mal 20
angegeben und das gleich in der Variable snake_geschwindigkeit
verpackt.
Ändert das später mal und schaut, was dann passiert. Spielt auch
mal mit den Variablen quadrat_seite
ein paar Konstellationen durch.
Die Spielschleife ändert sich natürlich auch:
...
def spielschleife_aufrufen():
print('in spielschleife_aufrufen')
global spielen, snake_x, snake_y, quadrat_seite, snake_bewegung_x,\
snake_bewegung_y
while spielen:
for event in pygame.event.get():
# Ausgabe auskommentiert
# print(event)
if event.type == pygame.QUIT:
spielen = False
# die Tastatur abfragen
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
snake_bewegung_x = quadrat_seite
snake_bewegung_y = 0
elif event.key == pygame.K_LEFT:
snake_bewegung_x = quadrat_seite * -1
snake_bewegung_y = 0
elif event.key == pygame.K_UP:
snake_bewegung_x = 0
snake_bewegung_y = quadrat_seite * -1
elif event.key == pygame.K_DOWN:
snake_bewegung_x = 0
snake_bewegung_y = quadrat_seite
snake_x += snake_bewegung_x
snake_y += snake_bewegung_y
pygame.draw.rect(fenster, ROT,
[snake_x, snake_y, quadrat_seite, quadrat_seite])
pygame.display.update()
zeit.tick(snake_geschwindigkeit)
...
Sieht viel aus, ist aber nicht kompliziert, wenn man weiß, wie das Zusammenspiel ist.
Da ich mich für globale Variablen entschieden habe, brauchen wir in den Zeilen 4 und 5 die Erweiterung um die neuen Variablen. Das "\" kennzeichnet einen Zeilenumbruch.
In Zeile 9 ist die Ausgabe von event
auskommentiert.
Zwischen Zeile 14 und 26 passieren 2 Dinge.
Zuerst "fangen" wir in Zeile 14 das event
vom Typ
‚eine-Taste-auf-der-Tastatur-wurde-gedrückt’ ab
(pygame.KEYDOWN
).
In den Zeilen 15, 18, 21 und 24 kümmern wir uns nur um die 4 Pfeil-Tasten, alle anderen Tasten werden nicht berücksichtigt.
Falls Ihr andere Tasten nutze wollt, schaut im Internet in der offiziellen Dokumentation vonpygame
nach, die Adresse ist https://www.pygame.org/docs/ref/key.html.
Entscheidet Ihr Euch zum Beispiel für die bei Spielen ebenfalls gängige ‚WASD’-Kombination, wäre das Äquivalent zupygame.K_UP
die Abfrage aufpygame.K_w
zu machen.
Was aber muss passieren, damit wir das Quadrat in Bewegung bekommen?
Ganz einfach, die Position der oberen linken Ecke des Quadrats muss geändert
werden, und zwar genau um die Seitenlänge des Quadrats. Nachfolgendes Bildchen
soll den ersten Schritt nach Start des Fensters symbolisieren.
Los geht es bei uns ja an der Position
- Erfolgt die Bewegung nach rechts muss zum aktuellen Wert der
x-Achse die Seitenlänge des Quadrats addiert werden (also aus400 wird410 ). Der Wert für diey-Achse bleibt bei200 . - Erfolgt die Bewegung nach links muss vom aktuellen Wert
x-Achse die Seitenlänge des Quadrats subtrahiert werden (also aus400 wird390 ). Der Wert für diey-Achse bleibt bei200 . - Erfolgt die Bewegung nach oben muss vom aktuellen Wert der
y-Achse die Seitenlänge des Quadrats subtrahiert werden (also aus200 wird190 ). Der Wert für diex-Achse bleibt unverändert bei400 . - Erfolgt die Bewegung nach unten muss zum aktuellen Wert der
y-Achse die Seitenlänge des Quadrats addiert werden (also aus200 wird210 ) Der Wert für diex-Achse bleibt bei400 .
Nun zur zweiten Aktion, wir weisen die neuen Werte den beiden Variablen
snake_bewegung_x
und snake_bewegung_y
zu. Entweder ist es
dann der Wert von quadrat_seite
selbst (in unserem Fall
also ‚10’), oder der Kehrwert durch die Multiplikation mit -1 (also
‚-10’)
In den Zeilen 28 und 29 erfolgt dann die Anpassung der beiden Variablen
snake_x
und snake_y
.
Die Zeilen 31 und 32 hatten wir schon, allerdings sind jetzt die fixen Werte
400
, 200
, 10
und 10
durch die Variablen ersetzt worden. An der grundsätzlichen Verarbeitung hat
sich also nichts geändert.
Zeile 34 ist neu, hier kommt jetzt die erwähnte zeitliche Komponente
dazu. Wir
befinden uns ja immer noch in der while
-Schleife aus Zeile 6.
Erst,
wenn oben rechts das X geklickt wird, verlassen wir die Schleife
durch setzen der Variablen spielen
auf False
.
Der Aufruf von zeit.tick()
bewirkt, dass so etwas wie eine
‚Pause’ in
der Verarbeitung der Schleife eingebaut wird. Wie groß diese Pause ist,
drückt die Zahl aus, die in der Klammer mitgegeben wird. Sie
repräsentiert den Bruchteil einer Sekunde.
Da wir dafür die Variable snake_geschwindigkeit
definiert und diese
mit ‚20’ vorbelegt haben (Zeile 21 im Codeblock ganz oben), sorgt
zeit.tick(snake_geschwindigkeit)
dafür, dass die
while
-Schleife 20-mal pro Sekunde durchlaufen wird.
Und solange wir keine andere Pfeiltaste drücken, wird die Richtung beibehalten.
Was sehen wir jetzt, wenn wir das Programm laufen lassen und dann mit den Pfeiltasten spielen?
Bei mir sieht das nach einigem Herumspielen so aus:
Schon ganz schick, es bewegt sich zumindest etwas.
Wie man aber sieht, habe ich keine Schlange bewegt sondern es wurde eine Spur gezogen. Auf der rechten Seite bin ich aus dem Fenster gelaufen, das müssen wir ändern!
Inhaltsverzeichnis:
1. Vorwort2. Das Projekt
3. Vorarbeiten
4. Projekt Snake
4.1. Der Funktionsumfang
4.2. Die Planung der Umsetzung
4.3. Das Coden
4.3.1. Das Grundgerüst
4.3.2. Das Fenster
4.3.3. Der Schlangenkopf
4.3.4. Die Bewegung der Schlange
4.3.5. Kleine Verbesserungen
4.3.6. Das Futter platzieren
4.3.7. Die Schlange wächst
4.3.8. Den Spielstand ausgeben
4.3.9. Die Wiederholung
4.3.10. Der finale Stand
5. Abschluss