Spieler in Pygame wird nicht angezeigt

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
markusglnn
User
Beiträge: 2
Registriert: Montag 30. Oktober 2023, 08:13

Code: Alles auswählen

import pygame, sys



pygame.init()

########################################################################

#-----------------------------------------------------------------------
clock = pygame.time.Clock()
FPS = 60
#-----------------------------------------------------------------------
#Fenster definieren
fenster_Breite = 1280
Fenster_Hoehe = 800
fenster = pygame.display.set_mode((fenster_Breite,Fenster_Hoehe), pygame.DOUBLEBUF)


pygame.display.set_caption("Plattformer")


#-----------------------------------------------------------------------
# Bilder laden #############################################################################
hintergrund = pygame.image.load("Assets/hintergrund.png").convert_alpha()

laufen_rechts = [pygame.image.load("Assets/laufen_rechts/1.png").convert_alpha(), pygame.image.load("Assets/laufen_rechts/2.png").convert_alpha(),pygame.image.load("Assets/laufen_rechts/3.png").convert_alpha(), pygame.image.load("Assets/laufen_rechts/4.png").convert_alpha(), pygame.image.load("Assets/laufen_rechts/5.png").convert_alpha(),
                 pygame.image.load("Assets/laufen_rechts/6.png").convert_alpha(), pygame.image.load("Assets/laufen_rechts/7.png").convert_alpha(), pygame.image.load("Assets/laufen_rechts/8.png").convert_alpha()]

laufen_links =  [pygame.image.load("Assets/laufen_links/1.png").convert_alpha(), pygame.image.load("Assets/laufen_links/2.png").convert_alpha(),pygame.image.load("Assets/laufen_links/3.png").convert_alpha(), pygame.image.load("Assets/laufen_links/4.png").convert_alpha(), pygame.image.load("Assets/laufen_links/5.png").convert_alpha(),
                 pygame.image.load("Assets/laufen_links/6.png").convert_alpha(), pygame.image.load("Assets/laufen_links/7.png").convert_alpha(), pygame.image.load("Assets/laufen_links/8.png").convert_alpha()]

stehen = [pygame.image.load("Assets/stehen/1.png").convert_alpha(), pygame.image.load("Assets/stehen/2.png").convert_alpha(),  pygame.image.load("Assets/stehen/3.png").convert_alpha(),  pygame.image.load("Assets/stehen/4.png").convert_alpha(),  pygame.image.load("Assets/stehen/5.png").convert_alpha(),
          pygame.image.load("Assets/stehen/6.png").convert_alpha(),  pygame.image.load("Assets/stehen/7.png").convert_alpha(),  pygame.image.load("Assets/stehen/8.png").convert_alpha(),  pygame.image.load("Assets/stehen/9.png").convert_alpha(),  pygame.image.load("Assets/stehen/10.png").convert_alpha()]

springen = [pygame.image.load("Assets/spieler_springen/1.png").convert_alpha(), pygame.image.load("Assets/spieler_springen/2.png").convert_alpha(),pygame.image.load("Assets/spieler_springen/3.png").convert_alpha(), pygame.image.load("Assets/spieler_springen/4.png").convert_alpha(), pygame.image.load("Assets/spieler_springen/5.png").convert_alpha(),
                 pygame.image.load("Assets/spieler_springen/6.png").convert_alpha(), pygame.image.load("Assets/spieler_springen/7.png").convert_alpha(), pygame.image.load("Assets/spieler_springen/8.png").convert_alpha()]


############################################################################################


class Spieler(pygame.sprite.Sprite):
    def __init__(self, x, y, geschw, breite, hoehe, sprung, spieler_Richtung, schritte_Rechts, schritte_Links):
        self.x = x
        self.y = y
        self.geschw = geschw
        self.breite = breite
        self.hoehe = hoehe
        self.sprung = sprung
        self.spieler_Richtung = spieler_Richtung
        self.schritte_Rechts = schritte_Rechts
        self.schritte_Links = schritte_Links
        self.sprung2 = False

    
    def laufen (self, liste):
        if liste[0]:
            self.x -= self.geschw
            self.spieler_Richtung = [1,0,0,0]
            self.schritte_Links += 1
        if liste[1]:
            self.x += self.geschw
            self.spieler_Richtung = [0,1,0,0]
            self.schritte_Rechts += 1


    def resetSchritte (self):
        self.schritte_Links = 0
        self.schritte_Rechts = 0

    def stehen( self ):
        self.spieler_Richtung = [0,0,1,0]
        self.resetSchritte()


    def sprungSetzen( self ):
        if self.sprung == -16:
            self.sprung2 = True
            self.sprung = 15


    def springen( self ):
        if self.sprung2:
            self.spieler_Richtung = [0, 0, 0, 1]
            if self.sprung >= -15 :
                n = 1
                if self.sprung < 0 :
                    n = -1
                self.y -= (self.sprung ** 2) * 0.25 * n
                self.sprung -= 1
            else:
                self.sprung2 = False
    def spieler_zeichnen( self ):

        if self.schritte_Rechts == 63 :  # nach 63 schritte beginnt die Animation von vorne
            self.schritte_Rechts = 0

        if self.schritte_Links == 63 :
            self.schritte_Links = 0

        # Zeichnet den Spieler mit den entsprechenden Animationsbildern
        # Teilen durch 8 sorgt dafür, dass die Anomation in einem langsameren Tempo durchgeht.
        # % len(laufen_rechts), % len(laufen_links), % len(stehen) stellt sicher, dass der Zähler innerhalb des gültigen Bereichs für die Anzahl der Bilder bleibt.
        # Das % (Modulo) -Operator gibt den Rest der Division zurück. In diesem Fall wird der Zähler nach der Division durch 8 auf den Rest bezogen,
        # um den aktuellen Frame-Index zu erhalten. Das hilft, sicherzustellen, dass der Index nicht außerhalb des Bereichs der verfügbaren Bilder liegt.
        if self.spieler_Richtung == [0] :
            aktueller_Frame = (self.schritte_Rechts // 8) % len(laufen_rechts) # geteilt durch 8, weil ich 8 Bilder in der Datei hab für die Animation
            fenster.blit(laufen_rechts[aktueller_Frame], (self.x, self.y))
        if self.spieler_Richtung == [1] :
            aktueller_Frame = (self.schritte_Links // 8) % len(laufen_links)
            fenster.blit(laufen_links[aktueller_Frame], (self.x, self.y))
        if self.spieler_Richtung == [2] :
            fenster.blit(stehen,(self.x, self.y))
        if self.spieler_Richtung == [3] :
            fenster.blit(springen,(self.x, self.y))

def zeichnen():
    fenster.blit(hintergrund, (0, 0))
    spieler1.spieler_zeichnen()
    pygame.display.update()

# Rechteckerstellung, damit der Player mit dem Rechteck kolidiert und nicht aus dem Bildschirm läuft

linkewand = pygame.draw.rect(fenster, (0,0,0), (-2,0,2,800), 0 )
rechtewand = pygame.draw.rect(fenster, (0,0,0), (1281,0,2,800), 0)

#-----------------------------------------------------------------------
#HintergrundMusik 
musik = pygame.mixer.music.load("Assets/hintergrundMusik.wav")
pygame.mixer.music.play(-1)   # -1 damit die Musik dauerhaft läuft
pygame.mixer.music.set_volume(0.03)  #Somit stellt man die Lautstärte auf 50%

#------------------------------------------------------------------------
# Spieler als Objekt erstellen. Die Angaben in der Klasse stehen in der Klasse.
spieler1 = Spieler(250, 650, 5, 120 ,140, -16, [0,0,1,0], 0,0)
#########################################################################
run = True

while run:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    spielerRechteck = pygame.Rect(spieler1.x, spieler1.y, 120, 140)
    keys = pygame.key.get_pressed()


    if keys[pygame.K_RIGHT] and spieler1.x + 120 < fenster_Breite:
        spieler1.laufen([0,1,0,0])

    elif keys[pygame.K_LEFT] and spieler1.x > 0:
        spieler1.laufen([1,0,0,0])
    else:
        spieler1.stehen()
        (spieler1.stehen())

    if keys[pygame.K_UP]:
        spieler1.sprungSetzen()


    if keys[pygame.K_RIGHT] and keys[pygame.K_LSHIFT] and spieler1.x + 120 < fenster_Breite:
        spieler1.laufen([0,1])

    if keys[pygame.K_LEFT] and keys[pygame.K_LSHIFT]and spieler1.x > 0:
        spieler1.laufen([1,0])



    spieler1.springen()


    zeichnen()

    clock.tick(FPS) 
    
pygame.mixer.music.stop()    
pygame.quit()[code]

[b]
Mein Spieler wird im Spiel nicht angezeigt. Die Bilder werden richtig geladen. Wenn ich spieler1.stehen() in der Schleife auf Print setze, dann kommt None in der Konsole raus. Dasselbe gilt auch für die anderen sachen.
Gibt es vielleicht noch eine andere Lösung eine Figur zu animieren ?
[/b]
Sirius3
User
Beiträge: 17872
Registriert: Sonntag 21. Oktober 2012, 17:20

Konstanten werden prinzipiell komplett GROSS geschrieben. Alle Variablen und Methoden dagegen komplett klein. Bei Dir mischen sich alle möglichen Schreibweisen, z.B. fenster_Breit mit kleinem f und Fenster_Hoehe mit großen F.
Aller ausführbarer Code (also alles außer Definitionen) muß in Funktionen stehen, üblicherweise hat man eine Funktion main, die das Hauptprogramm darstellt.
Ausführbarer Code und Definition zu mischen macht man auf keinen Fall.
Kommentare sollen dem Leser erklären warum etwas passiert, ein Kommentar, der nur aus Minuszeichen oder Gittern besteht, ist nicht sehr hilfreich.
sys wird importiert aber nicht benutzt.
Beim Laden der Bilder hast Du viel kopierten Code, das solltest Du in Funktionen und Schleifen organisieren.
Alles was Funktionen brauchen, müssen sie über ihre Argumente bekommen, benutze keine globalen Funktionen.
Benutze keine kryptischen Abkürzungen, wenn Du geschwindigkeit meinst, dann schreib das auch.
`liste` in `laufen` ist ein sehr schlechter Variablenname, weil er nichts aussagt.
0 und 1 für die boolschen Werte False und True benutzt man nicht, weil es ja die Werte explizit gibt.
Was die Einzelnen Werte in spieler_richtung bedeuten, ist unklar, das sollte durch eine bessere Datenstruktur ersetzt werden.
Es ist unklar, was sprung2 von sprung unterscheidet, die Attribute brauchen also bessere Namen.
`spieler_zeichnen` benutzt einige globale Variablen.
`spieler_richtung` ist eine Liste mit Booleans, in spieler_zeichnen vergleichst Du die aber mit einelementigen Listen, das kann nicht funktionieren.
`stehen` und `springen` sind auch Listen mit Bildern, so wie jetzt kann blit nicht funktionieren.

`zeichnen` greift auch auf einige globale Variablen zu.
Warum hat der Spieler eine 1?
`spielerRechteck` wird nicht benutzt, sollte aber dann eine Methode der Spieler-Klasse sein.
Warum rufst Du spieler1.stehen zweimal auf? Und warum ist der zweite Aufruf geklammert?
Was soll der Aufruf von spieler1.laufen mit einer Liste mit nur 2 Argumenten?

Eine erste Überarbeitung könnte so aussehen:

Code: Alles auswählen

import pygame
from pathlib import Path

FPS = 60
FENSTER_BREITE = 1280
FENSTER_HOEHE = 800
ASSETS_PATH = Path(__file__).parent / "Asserts"

def load_asset(asset, count):
    return [
        pygame.image.load(ASSETS_PATH / asset / f"{i}.png").convert_alpha()
        for i in range(1, count + 1)
    ]


class Spieler(pygame.sprite.Sprite):
    def __init__(self, x, y, geschwindigkeit , breite, hoehe, sprung, spieler_richtung, schritte_rechts, schritte_links):
        self.x = x
        self.y = y
        self.geschw = geschwindigkeit 
        self.breite = breite
        self.hoehe = hoehe
        self.sprung = sprung
        self.spieler_richtung = spieler_richtung
        self.schritte_rechts = schritte_rechts
        self.schritte_links = schritte_links
        self.sprung2 = False
        self.laufen_rechts = load_asset("laufen_rechts", 8)
        self.laufen_links = load_asset("laufen_links", 8)
        self.stehen = load_asset("stehen", 10)
        self.springen = load_asset("spieler_springen", 8)


    def laufen(self, richtungen):
        if richtungen[0]:
            self.x -= self.geschwindigkeit
            self.spieler_richtung = [True, False, False, False]
            self.schritte_links += 1
        if richtungen[1]:
            self.x += self.geschwindigkeit
            self.spieler_richtung = [False, True, False, False]
            self.schritte_rechts += 1


    def reset_schritte(self):
        self.schritte_links = 0
        self.schritte_rechts = 0


    def stehen(self):
        self.spieler_richtung = [False, False, True, False]
        self.reset_schritte()


    def sprung_setzen(self):
        if self.sprung == -16:
            self.sprung2 = True
            self.sprung = 15


    def springen(self):
        if self.sprung2:
            self.spieler_richtung = [False, False, False, True]
            if self.sprung >= -15:
                n = -1 if self.sprung < 0 else 1
                self.y -= (self.sprung ** 2) * 0.25 * n
                self.sprung -= 1
            else:
                self.sprung2 = False


    def spieler_zeichnen(self, fenster):
        if self.schritte_rechts == 63:  # nach 63 schritte beginnt die Animation von vorne
            self.schritte_rechts = 0

        if self.schritte_links == 63:
            self.schritte_links = 0

        # Zeichnet den Spieler mit den entsprechenden Animationsbildern
        # Teilen durch 8 sorgt dafür, dass die Anomation in einem langsameren Tempo durchgeht.
        # % len(laufen_rechts), % len(laufen_links), % len(stehen) stellt sicher, dass der Zähler innerhalb des gültigen Bereichs für die Anzahl der Bilder bleibt.
        # Das % (Modulo) -Operator gibt den Rest der Division zurück. In diesem Fall wird der Zähler nach der Division durch 8 auf den Rest bezogen,
        # um den aktuellen Frame-Index zu erhalten. Das hilft, sicherzustellen, dass der Index nicht außerhalb des Bereichs der verfügbaren Bilder liegt.

        # TODO: hier ist noch einiges falsch
        if self.spieler_richtung == [0]:
            aktueller_frame = (self.schritte_rechts // 8) % len(self.laufen_rechts) # geteilt durch 8, weil ich 8 Bilder in der Datei hab für die Animation
            fenster.blit(self.laufen_rechts[aktueller_frame], (self.x, self.y))
        if self.spieler_richtung == [1]:
            aktueller_frame = (self.schritte_links // 8) % len(self.laufen_links)
            fenster.blit(self.laufen_links[aktueller_frame], (self.x, self.y))
        if self.spieler_richtung == [2]:
            fenster.blit(self.stehen, (self.x, self.y))
        if self.spieler_richtung == [3]:
            fenster.blit(self.springen, (self.x, self.y))


def zeichnen(fenster, hintergrund, spieler):
    fenster.blit(hintergrund, (0, 0))
    spieler.spieler_zeichnen()
    pygame.display.update()


def main():
    pygame.init()
    clock = pygame.time.Clock()
    fenster = pygame.display.set_mode((FENSTER_BREITE, FENSTER_HOEHE), pygame.DOUBLEBUF)
    pygame.display.set_caption("Plattformer")

    hintergrund = pygame.image.load(ASSETS_PATH / "hintergrund.png").convert_alpha()

    # Rechteckerstellung, damit der Player mit dem Rechteck kolidiert und nicht aus dem Bildschirm läuft
    # TODO: wird nicht benutzt
    linkewand = pygame.draw.rect(fenster, (0,0,0), (-2,0,2,800), 0 )
    rechtewand = pygame.draw.rect(fenster, (0,0,0), (1281,0,2,800), 0)

    #HintergrundMusik 
    musik = pygame.mixer.music.load(ASSETS_PATH / "hintergrundMusik.wav")
    pygame.mixer.music.play(-1)   # -1 damit die Musik dauerhaft läuft
    pygame.mixer.music.set_volume(0.03)  #Somit stellt man die Lautstärte auf 50%

    spieler = Spieler(250, 650, 5, 120, 140, -16, [False, False, True, False], 0, 0)

    run = True
    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

        keys = pygame.key.get_pressed()
        if keys[pygame.K_RIGHT] and spieler.x + 120 < FENSTER_BREITE:
            spieler.laufen([False, True, False, False])
        elif keys[pygame.K_LEFT] and spieler.x > 0:
            spieler.laufen([True, False, False, False])
        else:
            spieler.stehen()

        if keys[pygame.K_UP]:
            spieler.sprung_setzen()

        if keys[pygame.K_RIGHT] and keys[pygame.K_LSHIFT] and spieler.x + 120 < FENSTER_BREITE:
            spieler.laufen([False, True])

        if keys[pygame.K_LEFT] and keys[pygame.K_LSHIFT]and spieler.x > 0:
            spieler.laufen([True, False])

        spieler.springen()
        zeichnen(fenster, hintergrund, spieler)
        clock.tick(FPS) 
        
    pygame.mixer.music.stop()    
    pygame.quit()


if __name__ == "__main__":
    main()
Hier sind nur die offensichtlichen Fehler korrigiert. Die angesprochenen logischen Fehler darfst Du selbst reparieren.
markusglnn
User
Beiträge: 2
Registriert: Montag 30. Oktober 2023, 08:13

Also erstens. DANKE! Ich bin neu und nehme deine Kritik dankend an. :)
Wie man sieht, bin ich Anfänger im coden .

Ich danke dir für die Hinweise bezüglich der Variablen, Konstanten und Funktionen .
Ich setz mich jetzt erstmal hin und schau mir alle Zeilen an und schaue was genau passiert und was genau du verändert hast. :)

Ich denke aber, dass ich alles verstehen werde und keine weitere Fragen mehr folgen werden.

Ich danke dir!!!!
Antworten