Biblioteka PyGame. Pomoc z kodem gry Space invaders

0

Witam, uczę się programować w pythonie przez tworzenie gry Space Invaders od podstaw korzystając z biblioteki Pygame. Otóż mam problem ponieważ dodałem 1 rząd kosmitów i teraz nie wiem jak zmienić mój kod, żeby było 5 rzędów po 11 kosmitów jak w prawdziwej grze.

Oto kod jaki napisałem w tej chwili:

def initialize(self):

  self.invaders = []
        xPos = 512
        for i in range(11):
            invader = Invader.Invader()
            invader.setXPos(xPos)
            invader.setYPos(100)
            self.invaders.append(invader)
            xPos += 50

def update(self):
        for i in range(11):
            self.invaders[i].moveHorizontal(self.alienSpeed * self.alienDirection)

            if self.invaders[0].getXPos() < 96:
                self.alienDirection = +1

                xPos = 96
                for i in range(11):
                    self.invaders[i].moveVertical(4)
                    self.invaders[i].setXPos(xPos)
                    xPos = xPos + self.invaderImg.get_width()

            if self.invaders[10].getXPos() > 924:
                self.alienDirection = -1

                xPos = 924 - self.invaderImg.get_width() * 10
                for i in range(11):
                    self.invaders[i].moveVertical(4)
                    self.invaders[i].setXPos(xPos)
                    xPos = xPos + self.invaderImg.get_width()

def draw(self):
        for i in range(11):
            self.screen.blit(self.invaderImg, self.invaders[i].getPosition())
        pygame.display.flip()

Dodam, że ten kod działa bez problemu ale nie mam pojęcia jak dodać kolejne 4 rzędy po 11 kosmitów, żeby to wszystko działało.

0

Nie zagłębiałem się w kod, ale chyba potrzebujesz dwuwymiarowej tablicy, albo chociaż pętli "podwójnej", coś jak:

for i in range(11):
for j in range(5):
dodaj_kosmite(i,j)

To tylko przykład, a nie gotowy kod ;)

0

za dużo błędów wyskakuje, nie mam pojęcia jak to wykonać, żeby działało. Próbowałem dodać podwójną pętle ale sie buguje.

0

Zamień 11 na 44 i będziesz miał to co chciałeś :) Jeśli dobrze zrozumiałem problem

0

Chyba o to chodzi:

for j in range(4):
for i in range(11):

i zmień indeksowanie w nawiasach kwadratowych [ ], pamiętaj też o wcięciach (4 spacje).

0

to jeszcze coś takiego daj:

invader.setYPos(100)

zamien na to:

invader.setYPos(100 * j)

Oczywiście musisz mieć podwójną pętle - jak wyżej. Liczbę 100 możesz zmienić na mniejszą jakby się nie mieściło na ekranie ;)

0

Tak wygląda ten kod po zmianie:

        self.invaders = []
        xPos = 512
        for row in range(5):
            for col in range(11):
                invader = Invader.Invader()
                invader.setXPos(xPos)
                invader.setYPos(10 * row)
                self.invaders.append(invader)
                xPos += 50

Nic się nie zmieniło nadal jak widać na obrazu jest tylko jeden rząd.
user image

Jeszcze wyśle klase z której są tworzeni kosmici, może tutaj jest jakiś błąd.

class Invader:
    def __init__(self):
        self.__alienXPos = 0
        self.alienYPos = 0

    def setXPos(self, x):
        self.__alienXPos = x

    def setYPos(self, y):
        self.__alienYPos = y

    def getXPos(self):
        return self.__alienXPos

    def getYPos(self):
        return self.__alienYPos

    def getPosition(self):
        return (self.__alienXPos, self.__alienYPos)

    def moveHorizontal(self, amount):
        self.__alienXPos = self.__alienXPos + amount

    def moveVertical(self, amount):
        self.__alienYPos = self.__alienYPos + amount
0

Sprawdź w źródle czy konstruktor masz dobrze przepisany (wygląda trochę dziwnie):

def __init__(self):
    self.__alienXPos = 0
    self.alienYPos = 0
	
		
W poniższym kodzie: 

    self.invaders = []
    xPos = 512
    for row in range(5):
        for col in range(11):
            invader = Invader.Invader()
            invader.setXPos(xPos)
            invader.setYPos(100+ 10 * row)
            self.invaders.append(invader)
            xPos += 50		
			
kombinuj z wywołaniem funkcji:

            invader.setXPos(xPos)
            invader.setYPos(100+ 10 * row)

Spróbuj tak:

            invader.setXPos(xPos)
            invader.setYPos(300+ 50 * row)	

itd. itd:

            invader.setXPos(xPos)
            invader.setYPos(500+ 75 * row)	
			
Nie rozumiem, dlaczego pierwszy obiekt ma x=512, nie wiem jak dokładnie są liczone współrzędne. (0,0) jest w lewym górnym rogu?
0

Podpinając się do tematu, czy jest jakaś różnica jakby się ustawiło wartość pola klasy przez settera zamiast w konstruktorze?

0
java.util.Scanner napisał(a):

Podpinając się do tematu, czy jest jakaś różnica jakby się ustawiło wartość pola klasy przez settera zamiast w konstruktorze?

Tu jest właśnie przez metodę klasy ustawiane wartości.

Wywołanie konstruktora jest puste:

invader = Invader.Invader()

A czy jest jakaś różnica? MZ nie, ale to niech inni się wypowiedzą ;)

0

Próbowałem to robić w różne sposob z tych przez was podanych i nic nie wychodzi. Jedyną szansą jest skorzystanie z dwuwymiatrowej tablicy albo zrobienie listy list w których można byłoby zrobić rzędy i kolumny ale nie wiem jak to wykonać. :/

Dodam też, że z aktualnym kodem po wydrukowaniu tej listy w konsoli pokazuje się, że jest 55 obiektów dodanych ale ich jakoś nie widać.
user image

Ten problem z tymi rzędami kosmitów to jest jedyny problem który uniemożliwia mi dokończenie tej gry.

0

Przenieś xPos = 512 do pierwszej pętli. Tworzysz kolejne wiersze kosmitów, lecz cały czas zwiększasz wartość na osi X.

0

Dobra potrzebuje teraz waszej pomocy. Wydaje mi się, że ten kod powinien już działać. Tworzy mi 55 obiektów kosmitów.

        
self.invaders = []
yPos = 100
    for row in range(5):
        xPos = 512
        for col in range(11):
            invader = Invader.Invader(xPos, yPos)
            self.invaders.append(invader)
            xPos += 50
        yPos += 40 

Tylko teraz mam problem bo nie widać tego w grze i nie wiem jak zmienić kod rysowania, żeby mi wyświetlało wszystkich kosmitów na ekranie.
Tutaj wam pokazuje ten kod funkcji draw.

def draw(self, gametime):              
for row in range(5):
    for col in range(11):
        self.screen.blit(self.invaderImg, self.invaders[col].getPosition())
pygame.display.flip()

Aktualnie ten kod pokazuje mi nadal tylko jeden rząd kosmitów.

0

Masz tablicę 55 obiektów, a wyciągasz do rysowania tylko pierwsze 11 sztuk. Robisz to 5 razy. Wykorzystaj zmienną row tak, aby po wyrysowaniu pierwszych 11 kosmitów program nie rysował od początku elementu 1-11 tylko 12-22 itd. :)

1
def draw(self, gametime):              
for alien in range(55):
        self.screen.blit(self.invaderImg, self.invaders[alien].getPosition())
pygame.display.flip() 

Każdemu z alienów przypisałeś już odpowiedni X i Y. Po prostu narysujmy każdy obiekt z tablicy.

0

bo powinieneś zerować współrzędną X po każdym przejściu pętli. Tak żeby wyrysowało jedenastkę, zerujesz i od nowa.....

1 użytkowników online, w tym zalogowanych: 0, gości: 1