Pygame Bildschirm von Objekten leeren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
cypher28
User
Beiträge: 24
Registriert: Mittwoch 8. Dezember 2021, 00:54

Hallo zusammen,

mit welcher Methode kann ich den gesamten Bildschirm komplett von vorherigen Objekten leeren?

Ich habe ein Menu mit 3 verschieden Seiten. Durch drücken jeweiliger Buttons kann ich durch die Menüs hin und her klicken.
Das Problem ist aber, das zwar die "rect" Objekte aus dem vorherigen Menü nicht mehr gezeichnet werden, wenn ich durchklicke. Diese sind aber immer noch vorhanden. Merkt man dadurch, wenn man auf die selbe Fläche klickt, wir die entsprechende Methode des Buttons ausgeführt, obwohl dieser nicht dargestellt wird.
Ich hoffe ich konnte es Beschreiben. Zum Beispiel habe ich in einem Menü-Fenster ein "Zurück"-Button. Wenn ich Wenn ich draufklicke, komme ich wie gewünscht zurück. Wenn ich aber wieder auf dieselbe Fläche klicke, wo vorher das "Zurück" Button war, reagiert das Game wieder drauf.

Code: Alles auswählen

....
while gameStart:
            
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    return
                #user, password
                if event.type == pygame.MOUSEBUTTONDOWN:
                    if user_rect.collidepoint(event.pos):
                        active_user = True
                        active_password = False
                    elif password_rect.collidepoint(event.pos):
                        active_password = True
                        active_user = False
                    elif createAccountButton_rect.collidepoint(event.pos):
                        user_input = ''
                        password_input = ''
                        createAccount = True
                        login = False
                        game = False
                        menueGame = False
                    elif backButton_rect.collidepoint(event.pos):
                        user_input = ''
                        password_input = ''
                        createAccount = False
                        login = True
                        game = False
                        menueGame = False
                    elif setAccountButton_rect.collidepoint(event.pos):
                        user_input = ''
                        password_input = ''
                        createAccount = False
                        login = False
                        game = False
                        menueGame = True
                    elif startGameButton_rect.collidepoint(event.pos):
                        createAccount = False
                        login = False
                        game = True
                        menueGame = False
                    else:
                        active_user = False
                        active_password = False
                        

.....

ein Ausschnitt vom GameLoop

ich dachte das vielleicht nach jeder if-Abfrage screen.fill(0,0,0) methode helfen würde, aber leider ohne Erfolg.
Benutzeravatar
__blackjack__
User
Beiträge: 14005
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@cypher28: Die Beschreibung hat ja nichts mit dem Bildschirm/der Darstellung zu tun, sondern das Dein Code anscheinend auf Klicks in Bereichen reagiert egal ob da ein Button angezeigt wird oder nicht.

Was beim Code auffällt sind die vielen Wiederholungen und boole'schen Variablen. Statt da immer eine auf `True` und die anderen alle auf `False` zu setzen, wäre es besser eine Variable zu haben die den Zustand vermerkt. Vielleicht etwas vom Typ `enum.Enum`. Oder eine Funktion die für den jeweiligen Bildschirm zuständig ist. Oder gar ein Objekt das auch gleich den ganzen Zustand für den jeweiligen Bildschirm verwaltet.

Namen werden in Python per Konvention klein_mit_unterstrichen geschrieben.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
cypher28
User
Beiträge: 24
Registriert: Mittwoch 8. Dezember 2021, 00:54

Vielen dank für die Info.
Ich weis, es ist aktuell noch sehr unsauberer code. Das mit der Konvention muss ich noch anpassen, danke für den Hinweis.
Gibt es denn aber eine Methode, mit der man die Bildschirmfläche wieder frei machen kann? Ich habe leider keine gefunden welches mein Problem beheben müsste.

Nach jedem klick auf ein Button, werden die entsprechenden "Blit" Methoden aktiviert oder deaktiviert, scheinen aber noch imaginär vorhanden zu sein, da die entsprechenden Flächen auf Klicks noch reagieren oder sogar
neu gezeichnete Buttons überdecken.

Code: Alles auswählen

import pygame
from model import HistoryList, Matchfield, Figure, Sound, Walls

#colors
YELLOW = (255,255,0)
GREEN = (0, 136, 0)
PURPLE = (128,0,128)
color_active = GREEN
color_passive = (105, 105, 105)
#color = color_passive

#Login Example
user = 'User'
password = 'password'

#set Title
pygame.display.set_caption("Frogger")

#background Game
backgroundMenue = pygame.image.load("graphics/menu.png")
backgroundGame = pygame.image.load("graphics/background.png")
size = width, height = (1000, 1000)
screen = pygame.display.set_mode(size)
#objekt Game
loginView = Matchfield(backgroundMenue, screen)
gameView = Matchfield(backgroundGame, screen)

#player
frogImage = pygame.image.load("graphics/frog_u.png")
frogRect = pygame.Rect(420, 915, 80, 80)
speedFrog = 100
#object player
frog = Figure(frogImage, speedFrog, frogRect)

#obstacle car1
car1Image = pygame.image.load("graphics/car1.png")
car1Rect = pygame.Rect(750, 720, 80, 80)
car1speed = 5
#object
car1 = Figure(car1Image, car1speed, car1Rect)

#obstacle car2
car2Image = pygame.image.load("graphics/car2.png")
car2Rect = pygame.Rect(750, 620, 80, 80)
car2speed = 4
#object
car2 = Figure(car2Image, car2speed, car2Rect)

#obstacle truck
car3Image = pygame.image.load("graphics/truck.png")
car3Rect = pygame.Rect(750, 820, 80, 80)
car3speed = 3
#object
car3 = Figure(car3Image, car2speed, car3Rect)
#jump = pygame.mixer.Sound("sound/sound-frogger-hop.wav")

def drawLogin(Title, User, User_Input, user_input_rect, Password, Password_Input, Password_Inpuct_rect):
    screen.blit(Title, (350, 300))
    screen.blit(User, (350, 400))
    screen.blit(User_Input, user_input_rect)
    screen.blit(Password, (350, 500))
    screen.blit(Password_Input, Password_Inpuct_rect)

def drawButtons(loginText, loginText_rect, createAccountText, createAccountText_rect):
    screen.blit(loginText, loginText_rect)
    screen.blit(createAccountText, createAccountText_rect)

def drawButtonsCreateAccount(loadPicture, loginPicture_rect, setAccountButtonText, setAccountButtonText_rect, backButton, backButton_rect):
    screen.blit(loadPicture, loginPicture_rect)
    screen.blit(setAccountButtonText, setAccountButtonText_rect)
    screen.blit(backButton, backButton_rect)

def drawButtonsMenueGame(Title, startGameButton, startGameButton_rect, historyButton, historyButton_rect, logoutButtonButton, logoutButton_rect):
    screen.blit(Title, (350, 300))
    screen.blit(startGameButton, startGameButton_rect)
    screen.blit(historyButton, historyButton_rect)
    screen.blit(logoutButtonButton, logoutButton_rect)

def drawFrog(frog, frogPosition):
    screen.blit(frog, frogPosition)

def drawObstacles(car1, car1Position, car2, car2Position, car3, car3Position):
    screen.blit(car1, car1Position)
    screen.blit(car2, car2Position)
    screen.blit(car3, car3Position)

def drawMenueHistory(historyTitle, avatar, avatar_rect, name, name_rect, status, status_rect, date, date_rect):
    screen.blit(historyTitle, (350,300))
    screen.blit(avatar, avatar_rect)
    screen.blit(name, name_rect)
    screen.blit(status, status_rect)
    screen.blit(date, date_rect)

def movementCar1(car, speed):
    car.move_ip(-speed,0)
    if car.right < 0:
        car.left = 830

def movementCar2(car, speed):
    car.move_ip(-speed,0)
    if car.right < 0:
        car.left = 830

def movementCar3(car, speed):
    car.move_ip(-speed,0)
    if car.right < 0:
        car.left = 830

class View:

    def start():

        pygame.init()
        pygame.font.init()
        #bool variables for menue
        login = False
        createAccount = False
        game = True
        menueGame = False
        historyMenue = False

        #check color user input Box
        color_rect_user = color_passive
        color_rect_password = color_passive
        #check input box
        active_user = False
        active_password = False
        #Font
        headline = pygame.font.Font("font/font.ttf", 40)
        text = pygame.font.Font("font/font.ttf", 16)
        text_small = pygame.font.Font("font/font.ttf", 13)
        #Title "Frogger"
        Title = headline.render('Frogger', False, GREEN)
        #user
        User = text.render('Benutzername', False, YELLOW)
        user_input = ''
        user_rect = pygame.Rect(350,440,300,40)
        #Historie List
        historieTitle = headline.render('Historie', False, GREEN)
        avatarPlayer1 = pygame.image.load("avatar/spiderman.png")
        avatarPlayer1_rect = pygame.Rect(100, 400, 80, 80)
        namePlayer1 = text.render('Spidy', False, YELLOW)
        namePlayer1_rect = pygame.Rect(200, 440, 80, 80)
        statusPlayer1 = text.render('Gewonnen', False, YELLOW)
        statusPlayer1_rect = pygame.Rect(320, 440, 80, 80)
        datePlayer1 = text.render('25.12.2021', False, YELLOW)
        datePlayer1_rect = pygame.Rect(500, 440, 80, 80)
        player1 = HistoryList(avatarPlayer1, avatarPlayer1_rect, namePlayer1, namePlayer1_rect, statusPlayer1, statusPlayer1_rect, datePlayer1, datePlayer1_rect)
        #password
        Password = text.render('Passwort', False, YELLOW)
        password_input = ''
        password_rect = pygame.Rect(350,540,300,40)
        #buttons login
        loginText = text.render('Einloggen', False, YELLOW)
        loginButton_rect = pygame.Rect(350,640,300,40)
        createAccountText = text.render('Account erstellen', False, GREEN)
        createAccountButton_rect = pygame.Rect(350,740,300,40)
        #buttons create Account
        loadPictureText = text_small.render('Bild hochladen', False, YELLOW)
        loadPicture_rect = pygame.Rect(450,650,200,40)
        picture = pygame.Rect(350,620,90,90)
        setAccountText = text.render('Account anlegen', False, GREEN)
        setAccountButton_rect = pygame.Rect(350,740,300,40)
        backButton = text.render('Zurück', False, YELLOW)
        backButton_rect = pygame.Rect(100,150,120,40)
        #buttons menueGame
        startGameButton = text.render('Spiel starten', False, GREEN)
        startGameButton_rect = pygame.Rect(350,440,300,40)
        historyButton = text.render('Historie', False, YELLOW)
        historyButton_rect = pygame.Rect(350,540,300,40)
        logoutButton = text.render('Ausloggen', False, PURPLE)
        logoutButton_rect = pygame.Rect(350,640,300,40)

        wall_top = pygame.Rect(0,0, 1000, 200)
        wall_right = pygame.Rect(800, 1000, 100, 900)
        wall_bottom = pygame.Rect(0,900, 900, 100)
        wall_left = pygame.Rect(0,0,100 , 1000) 
  
        #message
        wrongUser = text.render('Name oder Passwort falsch!', False, PURPLE)
        rightUser = text.render('Login erfolgreich!!', False, PURPLE)
        message_rect = pygame.Rect(350,540,200,40)

        #play sound
        Sound.soundMenu()
        clock = pygame.time.Clock()

        gameStart = True
        while gameStart:
            
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    return
                #user, password
                if event.type == pygame.MOUSEBUTTONDOWN:
                    if user_rect.collidepoint(event.pos):
                        active_user = True
                        active_password = False
                    elif password_rect.collidepoint(event.pos):
                        active_password = True
                        active_user = False
                    elif createAccountButton_rect.collidepoint(event.pos):
                        user_input = ''
                        password_input = ''
                        createAccount = True
                        login = False
                        game = False
                        menueGame = False
                    elif backButton_rect.collidepoint(event.pos):
                        user_input = ''
                        password_input = ''
                        createAccount = False
                        login = True
                        game = False
                        menueGame = False
                    elif setAccountButton_rect.collidepoint(event.pos):
                        user_input = ''
                        password_input = ''
                        createAccount = False
                        login = False
                        game = False
                        menueGame = True
                    elif startGameButton_rect.collidepoint(event.pos):
                        createAccount = False
                        login = False
                        game = True
                        menueGame = False
                    else:
                        active_user = False
                        active_password = False

                if event.type == pygame.KEYDOWN:

                    #Login Controller
                    if active_user == True:
                        if event.key == pygame.K_BACKSPACE:
                            user_input = user_input[:-1]
                        else:
                            user_input += event.unicode
                    elif active_password == True:
                        if event.key == pygame.K_BACKSPACE:
                            password_input = password_input[:-1]
                        else:
                            password_input += event.unicode

                    #Gameplay Controller
                    if event.key == pygame.K_UP and not frog.rect.colliderect(wall_top):
                        #pygame.mixer.Sound.play(jump)
                        frog.rect.move_ip(0, -frog.speed)
                        frog.image = pygame.image.load("graphics/frog_u.png")
                    if event.key == pygame.K_DOWN and not frog.rect.colliderect(wall_bottom):
                        #pygame.mixer.Sound.play(jump)
                        frog.rect.move_ip(0, +frog.speed)
                        frog.image = pygame.image.load("graphics/frog_d.png")
                    if event.key == pygame.K_LEFT and not frog.rect.colliderect(wall_left):
                        #pygame.mixer.Sound.play(frog.speed)
                        frog.rect.move_ip(-frog.speed, 0)
                        frog.image = pygame.image.load("graphics/frog_l.png")
                    if event.key == pygame.K_RIGHT and not frog.rect.colliderect(wall_right):
                        #pygame.mixer.Sound.play(jump)
                        frog.rect.move_ip(frog.speed, 0)
                        frog.image = pygame.image.load("graphics/frog_r.png")
            if login:

                screen.blit(loginView.image, (0, 0))
                pygame.draw.rect(screen, color_rect_user, user_rect,2)
                pygame.draw.rect(screen, color_rect_password, password_rect, 2)
                pygame.draw.rect(screen, YELLOW, loginButton_rect,2)
                pygame.draw.rect(screen, GREEN, createAccountButton_rect,2)

                User_Type = text.render(user_input, True, YELLOW)
                Password_Type = text.render(password_input, True, YELLOW)

                drawLogin(Title, User, User_Type, (user_rect.x + 5, user_rect.y + 10), Password, Password_Type, (password_rect.x + 5, password_rect.y + 10))
                drawButtons(loginText, (loginButton_rect.x + 10, loginButton_rect.y + 10), createAccountText, (createAccountButton_rect.x + 10 , createAccountButton_rect.y + 10))
                
                user_rect.w = max(300,User_Type.get_width() + 10)
                password_rect.w = max(300,Password_Type.get_width() + 10)

            if active_user:
                color_rect_user = color_active
            else:
                color_rect_user = color_passive
            
            if active_password:
                color_rect_password = color_active
            else:
                color_rect_password = color_passive
# - - - - - - - - - - - - - - MENUE CREATE ACCOUNT - - - - - - - - - - - - - - - - - - - - - - - - - - - #                    
            if createAccount:

                screen.blit(loginView.image, (0,0))
                pygame.draw.rect(screen, color_rect_user, user_rect,2)
                pygame.draw.rect(screen, color_rect_password, password_rect, 2)
                pygame.draw.rect(screen, YELLOW, loadPicture_rect,2)
                pygame.draw.rect(screen, YELLOW, picture,2)
                pygame.draw.rect(screen, GREEN, setAccountButton_rect,2)
                pygame.draw.rect(screen, YELLOW, backButton_rect,2)            

                User_Type = text.render(user_input, True, YELLOW)
                Password_Type = text.render(password_input, True, YELLOW)

                drawLogin(Title, User, User_Type, (user_rect.x + 5, user_rect.y + 10), Password, Password_Type, (password_rect.x + 5, password_rect.y + 10))
                drawButtonsCreateAccount(loadPictureText, (loadPicture_rect.x + 5 , loadPicture_rect.y + 15), setAccountText, (setAccountButton_rect.x + 10, setAccountButton_rect.y + 10), backButton, (backButton_rect.x +10 , backButton_rect.y + 10))
                
                user_rect.w = max(300,User_Type.get_width() + 10)
                password_rect.w = max(300,Password_Type.get_width() + 10)
# - - - - - - - - - - - - - - MENUE GAME - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - # 
            if menueGame:

                screen.blit(loginView.image, (0,0))
                pygame.draw.rect(screen, GREEN, startGameButton_rect,2)
                pygame.draw.rect(screen, YELLOW, historyButton_rect,2)
                pygame.draw.rect(screen, PURPLE, logoutButton_rect,2)
                drawButtonsMenueGame(Title, startGameButton, (startGameButton_rect.x + 10, startGameButton_rect.y + 10), historyButton, (historyButton_rect.x + 10, historyButton_rect.y + 10), logoutButton, (logoutButton_rect.x + 10 , logoutButton_rect.y + 10))
# - - - - - - - - - - - - - - GAME - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - # 
            if game:
                                           
                screen.blit(gameView.image, (0, 0))
                drawFrog(frog.image, frog.rect)
                drawObstacles(car1.image, car1.rect, car2.image, car2.rect, car3.image, car3.rect)
                movementCar1(car1Rect, car1speed)
                movementCar2(car2Rect, car2speed)
                movementCar3(car3Rect, car3speed)
                pygame.draw.rect(screen, 0, wall_top,2)
                pygame.draw.rect(screen, 0, wall_bottom,2) 
                pygame.draw.rect(screen, 0, wall_left,2) 
                pygame.draw.rect(screen, 0, wall_right,2)
# - - - - - - - - - - - - - - HISTORIE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - # 
            if historyMenue:
                screen.blit(loginView.image, (0,0))
                drawMenueHistory(historieTitle, avatarPlayer1, avatarPlayer1_rect, namePlayer1, namePlayer1_rect, statusPlayer1, statusPlayer1_rect, datePlayer1, datePlayer1_rect)
                pygame.draw.rect(screen, YELLOW, avatarPlayer1_rect, 2)

            pygame.display.update()
            clock.tick(60)

class db:
    def connectDB():
        pass
    def closeDB():
        pass
Hier mal der ganze code.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst keine Bildschirmflaeche frei machen, du hast Code, der falsch auf Mausklicks reagiert. Was auf dem Bildschirm zu sehen ist, hat nichts mit der Reaktion auf Mausklicks zu tun in pygame.
cypher28
User
Beiträge: 24
Registriert: Mittwoch 8. Dezember 2021, 00:54

Ok, habs hinbekommen.
Mal aber eine generelle Frage. Macht es sinn solche Menü´s mit jeweiligen bool-Werten immer ein und auszublenden oder gibt es da eine bessere Lösung um Menüs zu realisieren?
Vielleicht sollte man die Menüs in eigene Funktionen verpacken.
Benutzeravatar
__blackjack__
User
Beiträge: 14005
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@cypher28: Dazu hatte ich doch schon was geschrieben.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
cypher28
User
Beiträge: 24
Registriert: Mittwoch 8. Dezember 2021, 00:54

__blackjack__ hat geschrieben: Freitag 14. Januar 2022, 00:45 @cypher28: Dazu hatte ich doch schon was geschrieben.
Stimmt, sorry. :)
Antworten