Projekt Snake
4.3.7. Die Schlange wächst
Jetzt brauche ich Eure Vorstellungskraft.
Das Wachsen der Schlange ist jetzt eine Mischung von allem, was wir in den vergangenen Kapiteln gemacht haben.
Wir merken uns, wie viele Quadrate wir bisher gegessen haben, und nur für diese Anzahl lassen wir eine Spur ausgeben, wie wir das am Ende von Kapitel 4.3.4 Die Bewegung der Schlange gemacht haben.
- Hat die Schlange also nur den Kopf, ist das, was wir anzeigen auch nur der Kopf.
- Hat die Schlange das erste Futter-Quadrat gegessen, zeigen wir den Kopf und das erste Quadrat an, wir sind also in Summe bei 2 Quadraten. Mit anderen Worten, die Länge der Spur ist dann 2.
- Bei 5 gegessenen Quadraten sind wir dann also bei einer Spur von 6 Quadraten, okay?
Gut, kommen wir dann zum Programmteil. Der neue Code sieht so aus:
###################################################
# Definition der Importe
###################################################
import pygame
import random
###################################################
# Definition der Konstanten und Variablen
###################################################
# Werte fuer das Spielefenster
BREITE = 800
HOEHE = 400
# Spielsteuerung
spielen = True
# Farben RGB (Red, Green, Blue), jeweils 0 - 255
ROT = (255,0,0)
GRUEN = (0,255,0)
BLAU = (0,0,255)
WEISS = (255, 255, 255)
SCHWARZ = (0, 0, 0)
# Positionen der oberen linken Ecke des Kopfes
snake_x = BREITE/2
snake_y = HOEHE/2
# Bewegungen auf der x- und der y-Achse
snake_bewegung_x = 0
snake_bewegung_y = 0
# Geschwindigkeiten
zeit = pygame.time.Clock()
snake_geschwindigkeit = 10
# Groesse des Quadrats
quadrat_seite = 10
# Essen zubereiten
# Liste der x-Positionen
liste_essen_x = []
# Liste der y-Positionen
liste_essen_y = []
# Position von x
essen_x = 0
# Position von y
essen_y = 0
# Liste zur Speicherung des Kopfes und der gefressenen Quadrate
snake_als_liste = []
# Startwert der Laenge der Schlange bei Spielbeginn ist 1 (der Kopf halt...)
snake_laenge = 1
###################################################
# Definition der Funktionen
###################################################
def futter_vorbereiten():
print('in futter_vorbereiten')
e_x = 0
e_y = 0
for i in range (0, int(BREITE/quadrat_seite)):
liste_essen_x.append(e_x)
e_x += quadrat_seite
#print('liste_essen_x = ', liste_essen_x)
for i in range (0, int(HOEHE/quadrat_seite)):
liste_essen_y.append(e_y)
e_y += quadrat_seite
#print('liste_essen_y = ', liste_essen_y)
def fenster_definieren():
print('in fenster_definieren')
pygame.init()
f = pygame.display.set_mode((BREITE,HOEHE))
pygame.display.set_caption('Snake – das Schlangenspiel')
return f
def spielschleife_aufrufen():
print('in spielschleife_aufrufen')
global spielen, snake_x, snake_y, quadrat_seite, snake_bewegung_x,\
snake_bewegung_y, snake_laenge
essen_x = random.choice(liste_essen_x)
essen_y = random.choice(liste_essen_y)
while spielen:
for event in pygame.event.get():
# 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
# Abfrage, ob die Schlange aus dem Fenster verschwindet.
# Wenn ja, dann hoert das Spiel auf
if snake_x >= BREITE or snake_x < 0 or snake_y >= HOEHE or snake_y < 0:
print('Verloren!')
spielen = False
# Wenn nein, wird
# - die Veraenderung als neue Position gespeichert
# Fenster wird neu aufgebaut
else:
snake_x += snake_bewegung_x
snake_y += snake_bewegung_y
fenster.fill(SCHWARZ)
pygame.draw.rect(fenster, GRUEN,
[essen_x, essen_y, quadrat_seite, quadrat_seite])
# aktuelle Position des Kopfes in einer Liste speichern...
snake_kopf = []
snake_kopf.append(snake_x)
snake_kopf.append(snake_y)
#print('snake_als_liste = ', snake_als_liste)
# ... und an die bestehende Liste anhaengen
snake_als_liste.append(snake_kopf)
# der letzte Eintrag wird geloescht, damit der Eindruck entsteht,
# dass sich die Schlange bewegt
if len(snake_als_liste) > snake_laenge:
del snake_als_liste[0]
# die Spur augeben
for snake in snake_als_liste:
pygame.draw.rect(fenster, ROT,
[snake[0], snake[1], quadrat_seite, quadrat_seite])
# das Essen wurde gefangen, also erhoeht sich die Laenge der Schlange um ein
# Quadrat. Dann muss auch noch ein neues Futter-Quadrat platziert werden
if snake_x == essen_x and snake_y == essen_y:
snake_laenge += 1
essen_x = random.choice(liste_essen_x)
essen_y = random.choice(liste_essen_y)
pygame.display.update()
zeit.tick(snake_geschwindigkeit)
def spiel_verlassen():
print('in spiel_verlassen')
pygame.quit()
quit()
###################################################
# Programmstart
###################################################
print('Programmstart!')
futter_vorbereiten()
fenster = fenster_definieren()
spielschleife_aufrufen()
spiel_verlassen()
Die Anpassungen erfolgen in der spielschleife_aufrufen()
-Funktion.
Dort zuerst wieder die Nutzung der globalen Variablen ab Zeile 50.
Die gößten Veränderungen erfolgen im else
-Zweig der if
-Abfrage zur
Bestimmung, ob die Schlange aus dem Fenster gelaufen ist. Durch die Kommentare im Code sollte eigentlich klar sein, was passiert, oder?
Die aktuelle Position des Kopfes der Schlange wird also bei jedem Durchlauf der
Schleife in der lokalen Liste snake_kopf
gespeichert, diese lokale
Liste wird dann an die nächste, globale Liste snake_als_liste
angehängt (Zeilen 128 bis 134).
Die Position des vormals letzten Quadrates wird gelöscht, sodass beim
update
des Fensters (Zeile 153) der Eindruck entsteht, dass die
Schlange sich bewegt.
In Zeile 148 wird dann (wie im vorigen Kapitel angedeutet) geprüft, ob die beiden x- und y-Werte von Schlange und Essen übereinstimmen, dann ist das Fressen gefunden. Die Länge der Schlange wird um 1 erhöht, sodass die Spur ab diesem Zeitpunkt (also für den nächsten Durchlauf) ein Quadrat mehr mit ausgibt.
Zum Ende des Kapitels lassen wir das ganze mal laufen. Bei mir sieht das dann so aus:
Läuft!
Prima, ich bin stolz auf Euch!
Momentan wissen wir aber noch nicht, wie lang die Schlange tatsächlich ist. Und wir müssen das Spiel auch immer wieder neu starten, das geht doch bestimmt besser, oder?
Klar...
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