Python Tutorial
- jetzt Python programmieren lernen

viele Gegner fürs Spiel

Um jetzt aus unserem bisher einen Gegner mehr zu machen, müssen wir uns überlegen in welchem Element wir diese speichern. Unter Python bietet sich dafür Listen an. Also bauen wir unseren bisherigen Bereich für den Gegner um zu viele Gegner gespeichert in Listen.

Für den Start nehmen wir 5 Gegner.

Wie erstellen eine Liste:

# Gegner
# gegnerBild = pygame.image.load("bilder/varroa.png")
# gegnerX = random.randint(W/2, W-50)
# gegnerY = random.randint(50, H-50)
# gegnerbewegung = 5

gegnerBild = []
gegnerX = []
gegnerY = []
gegnerbewegung = []

Wir legen die Zahl der Gegner in einer Variablen fest:

anzahlgegner = 5

Über eine for-Schleife lassen wir nun unsere Gegner als Liste erstellen:

for x in range(anzahlgegner):
    gegnerBild.append(pygame.image.load("bilder/varroa.png"))
    gegnerX.append(random.randint(W/2, W-50))
    gegnerY.append(random.randint(50, H-50))
    gegnerbewegung.append(5)

Ab jetzt müssen wir bei jeder Aktion, die wir für einen Gegner machen (egal ob bewegen oder Kontrolle auf Treffer), für alle unsere Gegner durchführen.

Gehen wir unser bestehendes Programm durch und ändern die entsprechenden Stellen:

Aus dem Code für einen Gegner:


    gegnerY += gegnerbewegung

    if gegnerY < 10:
        gegnerbewegung *= -1
        gegnerX -= 30

    if gegnerY > H - 50:
        gegnerbewegung *= -1
        gegnerX -= 30

Wird nun folgender Code für unsere Gegner, die aus der Liste kommen. Da nach einem Treffer die Anzahl der Gegner sich ändert, lassen wir uns die Anzahl der Einträge die Liste über len() jeweils berechnen:

    for x in range(len(gegnerBild)):
        gegnerY[x] += gegnerbewegung[x]

        if gegnerY[x] < 10:
            gegnerbewegung[x] *= -1
            gegnerX[x] -= 30

        if gegnerY[x] > H - 50:
            gegnerbewegung[x] *= -1
            gegnerX[x] -= 30

Und zum Überprüfen auf einen Treffer:

    if kugelstatus == True:
        kugelX += kugelXbewegung

        for x in gegnerBild:
            if kollisionskontrolle(kugelX,kugelY,gegnerX[x], gegnerY[x]) == True:

Und beim Zeichnen der Gegner:

    for x in range(len(gegnerBild)):
        gegner(gegnerX[x], gegnerY[x])

Wobei wir die Funktion erweitern über die Nummer des Gegners:

def gegner(nr, x, y):
    fenster.blit(gegnerBild[nr], (x, y))

Was nun auch im Aufruf beachtet werden muss:

    for x in range(len(gegnerBild)):
        gegner(x, gegnerX[x], gegnerY[x])

Und wenn sich kein Tippfehler eingeschlichen hat, wuselt es auf dem Bildschirm:

durch viele Gegner wuselt es auf dem Bildschirm
durch viele Gegner wuselt es auf dem Bildschirm

Jetzt soll auch bei einem Treffer der entsprechende Gegner verschwinden. Getroffen ist schließlich getroffen!

Dazu löschen wir aus unserer Liste den entsprechenden Gegner:

        for x in gegnerBild:
            if kollisionskontrolle(kugelX,kugelY,gegnerX[x], gegnerY[x]) == True:
                # Kugel hat getroffen
                # print("Kugel hat getroffen")
                siegpunkte += 1
                print("aktueller Stand der Siegpunkte: ", siegpunkte)
                kugelstatus = False

                # Gegner Nr. x löschen
                del gegnerBild[x]
                del gegnerX[x]
                del gegnerY[x]
                del gegnerbewegung[x]

Allerdings stürzt nun unser Programm bei einem Treffer ab. Was passiert da. Wir löschen ein Element aus unserer Liste und versuchen die alte Anzahl von Listenelementen durchzugehen.

Unsere Variable mit x enthält nicht das, was wir glauben, dass diese enthält. Eine Liste wird nach dem löschen automatisch mit einem neuen Index versehen.

Und hier kommt dann gezieltes debuggen zum Einsatz. Wir wollen unser Programm vor dem Crash anhalten.

Wir wissen, dass es ein Problem nach dem Treffer und löschen im Index gibt. Also geben wir da unserem Programm ein exit() mit und starten das Programm mit dem Paramater -i

python3 -i varroa-invaders.py

Jetzt kommt man sehr schnell darauf, dass wir unsere x so nicht verwenden können. Wir basteln uns eine Hilfvariable mit dem Namen durchgang, die wir bei 0 starten und bei jedem Durchgang erhöhen.

Findet ein Treffer statt, dann können wir den Listeneintrag mit der Nummer von „durchgang“ löschen.

        durchgang = 0
        for x in gegnerBild:
            if kollisionskontrolle(kugelX-30,kugelY-25,gegnerX[durchgang], gegnerY[durchgang]) == True:
                # Kugel hat getroffen
                # print("Kugel hat getroffen")
                siegpunkte += 1
                print("aktueller Stand der Siegpunkte: ", siegpunkte)
                kugelstatus = False

                del gegnerNr[durchgang]
                del gegnerBild[durchgang]
                del gegnerX[durchgang]
                del gegnerY[durchgang]
                del gegnerbewegung[durchgang]

            durchgang += 1