Homepage von Papa

Projekt Snake

Das Futter platzieren

Kommen wir zur Nahrung der Schlange.

Das Futter besteht aus Quadraten, die genauso groß sind, wie der Kopf der Schlange. In unserem Fall also 10 Pixel breit und 10 Pixel hoch. Um das Futter farblich von der Schlange zu unterscheiden, wählen wir grün.

Das Erscheinen des Futters im Fenster erfolgt genau wie das Erzeugen des Schlangenkopfes. Wir duplizieren also die Zeilen mit der Anweisung pygame.draw.rect.

pygame.draw.rect(fenster, ROT, [snake_x, snake_y, quadrat_seite, quadrat_seite])

und setzen statt "snake" einfach "essen" ein und nehmen als Farbe GRUEN:

pygame.draw.rect(fenster, GRUEN, [essen_x, essen_y, quadrat_seite, quadrat_seite])

fertig.

Aber wie finden wir jetzt die Werte für essen_x und essen_y?

Da wird es jetzt etwas knifflig. Mit der Bibliothek random() haben wir ja ein Werkzeug, das uns Zufallszahlen aus einem vorher definierten Zahlenpool liefert, also eigentlich kein Problem.

Ich greife mal vor auf das nächste Kapitel. Wie prüfen wir, dass die Schlange das Essen gefunden hat?

Na, wenn snake_x und essen_x gleich sind UND wenn snake_y und essen_y gleich sind, dann ist die Schlange genau über dem Futter.

Und das ist auch schon der Knackpunkt. Die Schlange bewegt sich in 10er Schritten nach links, rechts, oben und unten. Sollte die Funktion random() die x-Position 142 ausgewählt haben, schaffen wir es nie, unseren Happen zu essen, weil wir entweder mit x = 140 oder x = 150 ankommen.

Blöd...

Ich habe mir nun überlegt, dass random() sich gleich aus 10er Schritten bedienen soll, sowohl für die x-Achse, als auch für die y-Achse. Für genau diese Art von Verarbeitung gibt es in Python die Listen.

Wir erstellen und also 2 Listen, eine für die Werte der x-Achse , und eine für die Werte der y-Achse.

Das lassen wir vor der Spielschleife tun, damit diese das ganze Spiel über zur Verfügung stehen. Dazu wird eine neue Funktion bereitgestellt (futter_vorbereiten()), den Code gibt es gleich unten.

Schauen wir uns also den Code dazu an:

###################################################
#  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 = 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

# 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

###################################################
#  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 j 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

    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
        # - und das 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])
            pygame.draw.rect(fenster, ROT, 
                             [snake_x, snake_y, quadrat_seite, quadrat_seite])
            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()

Den Import haben wir ja schon besprochen.

Die Deklaration der (globalen) Variablen erfolgt ab Zeile 42. Zunächst haben wir die beiden Listen für die Positionen auf der x-Achse (Zeile 42) bzw. der y-Achse (Zeile 44).

Die konkreten Werte essen_x bzw. essen_y starten mit 0.

Nun zur Funktion futter_vorbereiten() ab Zeile 54.

Was passiert darin?

Mit e_x und e_y haben wir 2 lokale(!) Variablen, die nur in dieser Funktion angesprochen werden.

Es folgt die Schleife zur Ermittlung der Werte für die x-Achse (ab Zeile 58). Mit int(BREITE/quadrat_seite) lassen wir das Programm selbst bestimmen, wann die Schleife zu Ende ist. Aktuell haben wir 800 / 10, also nach 80 Durchläufen ist Ende.

In der Schleife selbst addieren wir zum aktuellen Wert von e_x die Seitenlänge des Quadrats dazu (Zeile 59) und hängen den neuen Wert e_x an das Ende der Liste (Zeile 60).

Der erste Eintrag in der Liste ist also die 0, der zweite die 10 und so weiter, der 80. Eintrag ist dann 790.

Klar soweit, oder? Falls nicht, aktiviert mal die Ausgaben in der Zeile 61, dann wird das klar.

Die 2. Schleife erstellt analog die Liste für die Werte des y-Achse .

In der Spielschleife selbst, müssen wir auch Änderungen vornehmen, diese sind ab Zeile 81 zu finden.

Bevor es in die Schleife geht, besorgen wir uns eine x- und eine y-Koordinate aus den beiden erzeugten Listen.

Das Ausgeben des Futter-Quadrats machen wir direkt vor dem Ausgeben der Schlange, also in den Zeilen 118-119.

Jetzt bleibt uns nur noch, die Funktion futter_vorbereiten() aufzurufen, dazu fügen wir Zeile 138 ein.

Prima, damit sind wir auch mit der Erstellung des Futters und der Platzierung im Fenster durch.

Wenn wir das Programm laufen lassen, sieht das bei mir so aus:
Cool

Allerdings macht das jetzt noch nicht so viel Spaß, weil die Schlange das Futter nicht aufnimmt.

Genau das gehen wir im nächsten Kapitel an.

  • Zurück
  • Weiter

Inhaltsverzeichnis:

1. Vorwort
2. 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

© by Papa. Die Seite ist online seit 2020.

Menu

  • Startseite
  • Projekte
    • Übersicht aller Projekte
    • Nachbau Snake
    • Taschenrechner
  • Helferlein
    • Übersicht Hilfprogramme
    • Fonts in pygame
    • Quellcode nach HTML
    • Text nach HTML
  • Impressum
  • Disclaimer

Modal content goes here