Кнопки на разных экранах в Pygame - PullRequest
0 голосов
/ 04 февраля 2020

Я делаю программу с меню «Пуск» и «Справка», а также с другими функциями. Кнопки в «главном меню» работают отлично, но после входа в меню «Справка» кнопки, которые я запрограммировал для навигации по экрану, не работают должным образом. Пожалуйста, не стесняйтесь смотреть на код ниже. Я получаю сообщение об ошибке «BackHelpRect не определено». BackHelpRect - это прямоугольник, который я нарисовал вокруг кнопок изображений (как и для всех остальных кнопок), чтобы определить, когда мышь касается их. Это работает для кнопок главного меню, но как только я go в меню справки, прямоугольники для этих кнопок "исчезают". Если у вас есть решение, пожалуйста, ответьте, оно будет с благодарностью. :)

Извините, я прикрепил весь свой код, но все вызывается в других функциях, и все это работает синхронно c друг с другом. Извините, если это очень долго.

import pygame
import time
import smtplib
import webbrowser
pygame.init() # Starts pygame.
white = (255, 255, 255)
blue = (0, 100, 175)
black = (0, 0, 0)# Initialising Python with colours and a window size.
Event = []
AllTasks = []
MenuStatus = ""
def OpenMainMenu(): # To open Main Menu.
    MenuStatus = "Main Menu" # In case the code needs to know what menu is currently projected.
    pygame.display.set_caption("Main Menu") # Naming the New Window.
    CurrentMenu = pygame.image.load(r'D:\Holiday Planner Screen Resources\Main Menu.jpg') # Opening a custom made Screen.
    Screen.blit(CurrentMenu, (0, 0))
    CreateEventB()
    OpenEventB()
    HelpB()
    pygame.display.update()# Loads the Main Menu Screen.
    ButtonInteract()
def CreateEventB(): # To Open the "Create Menu Button".
    CreateButton = pygame.image.load(r'D:\Holiday Planner Screen Resources\Create Event.jpg') # Open the custom button design.
    CreateButton = pygame.transform.scale(CreateButton, (174, 85))
    global CreateRect
    CreateRect = Screen.blit(CreateButton, (425, 325))
    pygame.display.update(CreateRect)
def OpenEventB(): # To Open the "Create Menu Button".
    OpenButton = pygame.image.load(r'D:\Holiday Planner Screen Resources\Open Event.jpg') # Open the custom button design.
    OpenButton = pygame.transform.scale(OpenButton, (179, 85))
    global OpenRect
    OpenRect = Screen.blit(OpenButton, (225, 325))
    pygame.display.update(OpenRect)
def HelpB():
    HelpButton = pygame.image.load(r'D:\Holiday Planner Screen Resources\Help Button.jpg') # Open the custom button design.
    HelpButton = pygame.transform.scale(HelpButton, (151, 51))
    global HelpRect
    HelpRect = Screen.blit(HelpButton, (335, 415))
   pygame.display.update(HelpRect)
def BackHelp():
    BackHelpB = pygame.image.load(r'D:\Holiday Planner Screen Resources\BackHelp.jpg') # Open the custom button design.
    BackHelpB = pygame.transform.scale(BackHelpB, (235, 84))
    global BackHelpRect
    BackHelpRect = Screen.blit(BackHelpB, (45, 490))
    pygame.display.update(BackHelpRect)
def NextHelp():
    NextHelpB = pygame.image.load(r'D:\Holiday Planner Screen Resources\NextHelp.jpg') # Open the custom button design.
    NextHelpB = pygame.transform.scale(NextHelpB, (233, 85))
    global NextHelpRect
    NextHelpRect = Screen.blit(NextHelpB, (545, 490))
    pygame.display.update(NextHelpRect)
def FinishHelp():
    FinishHelpB = pygame.image.load(r'D:\Holiday Planner Screen Resources\FinishHelp.jpg') # Open the custom button design.
    FinishHelpB = pygame.transform.scale(NextHelpB, (230, 85))
    global FinishHelpRect
    FinishHelpRect = Screen.blit(FinishHelpRect, (545, 490))
    pygame.display.update(FinishHelpRect)  
def ButtonInteract(): # A function that helps to connect button interactions to their respective functions.
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                if CreateRect.collidepoint(event.pos):
                    CreateEvent()
            if event.type == pygame.MOUSEBUTTONDOWN:
                if OpenRect.collidepoint(event.pos):
                    Event, AllTasks = OpenEvent("BerlinTestTrip")
                    print(Event, AllTasks)
            if event.type == pygame.MOUSEBUTTONDOWN:
                if HelpRect.collidepoint(event.pos):
                     MenuStatus = "Help menu 1"
                     Help()
def ButtonsForHelp(): # A seperate button interaction pathway for help buttons as they are housed on a different screen.
    global BackHelpRect
    global NextHelpRect
    global FinishHelpRect
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                if BackHelpRect.collidepoint(event.pos): # Button navigaton.
                    if MenuStatus == "Help menu 1":
                        OpenMainMenu()
                    if MenuStatus == "Help menu 2":
                        MenuStatus = "Help menu 1"
                        Help()
                    if MenuStatus == "Help menu 3":
                        MenuStatus = "Help menu 2"
                        Help()
            if event.type == pygame.MOUSEBUTTONDOWN:
                if NextHelpRect.collidepoint(event.pos): # Button navigaton.
                    if MenuStatus == "Help menu 1":
                        MenuStatus = "Help menu 2"
                        Help()
                    if MenuStatus == "Help menu 2":
                        MenuStatus = "Help menu 3"
                        Help()
            if event.type == pygame.MOUSEBUTTONDOWN:
                if FinishHelpRect.collidepoint(event.pos): # Button navigaton.
                    if MenuStatus == "Help menu 3":
                        OpenMainMenu()

def CreateEvent():
    print ("Created")

def OpenEvent(EventSaveName):
    print ("Opened")
def Help():
    pygame.display.set_caption("Help Menu") # Naming the New Window.
    CurrentMenu = pygame.image.load(r'D:\Holiday Planner Screen Resources\Help Menu 1.jpg') # Opening a custom made Screen.
    Screen.blit(CurrentMenu, (0, 0))
    pygame.display.update()
    if MenuStatus == "Help menu 1":
        CurrentMenu = pygame.image.load(r'D:\Holiday Planner Screen Resources\Help Menu 1.jpg') # Opening a custom made Screen.
        Screen.blit(CurrentMenu, (0, 0))
        pygame.display.update()# Loads the menu Screen.
        BackHelp()
        NextHelp()
    if MenuStatus == "Help menu 2":
        CurrentMenu = pygame.image.load(r'D:\Holiday Planner Screen Resources\Help Menu 2.jpg') # Opening a custom made Screen.
        Screen.blit(CurrentMenu, (0, 0))
        pygame.display.update()# Loads the menu Screen.
        BackHelp()
        NextHelp()
    if MenuStatus == "Help menu 3":
        CurrentMenu = pygame.image.load(r'D:\Holiday Planner Screen Resources\Help Menu 3.jpg') # Opening a custom made Screen.
        Screen.blit(CurrentMenu, (0, 0))
        pygame.display.update()# Loads the menu Screen.
        BackHelp()
        FinishHelp()
    ButtonsForHelp()

# MAIN BODY

Screen = pygame.display.set_mode((824, 620))

OpenMainMenu()
pygame.display.update()

Спасибо.

1 Ответ

0 голосов
/ 05 февраля 2020

Проблема в том, что основной l oop ссылается на BackHelpRect до того, как он будет определен. Это легко повторить, просто выберите пункт меню «назад» на первом экране. Для отладки я добавил print( "BackHelp Defined HERE" ) к функции BackHelp(). Он не всегда вызывается заранее.

Чтобы исправить это, возможно, ваш код может определить все эти Изображения и Rects сразу, прежде чем начнется обработка меню. Что-то вроде:

def preloadButtons():
    global HelpButton, HelpButtonRect
    global BackHelpButton, BackHelpRect
    # etc. etc.

    HelpButton     = pygame.image.load('button.jpg') # Open the custom button design.
    HelpButton     = pygame.transform.scale(HelpButton, (151, 51))
    HelpButtonRect = HelpButton.get_rect()
    HelpButtonRect.topleft = (335, 415)

    BackHelpButton     = pygame.image.load('button.jpg') # Open the custom button design.
    BackHelpButton     = pygame.transform.scale(BackHelpButton, (235, 84))
    BackHelpButtonRect = BackHelpButton.get_rect()
    BackHelpButtonRect.topleft = (45, 490)

Хранение всех этих кнопок в виде отдельных глобалов не очень хороший дизайн, и он уже вызывает сложность в рисовании и тестировании событий в остальной части программы. Было бы лучше упаковать все атрибуты (изображение, размер, положение, прямоугольник) кнопки в структуру данных. Это не обязательно должен быть Python class, просто поместить свойства каждой кнопки в list было бы шагом вперед, а затем, возможно, все эти списки в один список all_buttons.

Например, здесь мы определяем список свойств кнопки, а затем перебираем их, чтобы создать более простой список имени кнопки / изображения / прямоугольника.

help_button      = [ 'help', 'help_button.jpg', (151, 51), (335, 415) ]
back_help_button = [ 'back', 'back_button.jpg', (235, 84), ( 45, 490) ]
# ... TODO: rest of buttons
all_buttons_properties = [ help_button, back_help_button ]

# Initialise buttons
all_buttons = []
for butt in all_button_properties:
    button_image = pygame.image.load( butt[1] )                     # load
    button_image = pygame.transform.scale( button_image, butt[2] )  # resize
    button_rect  = button_image.get_rect()
    button_rect.topleft = butt[3]                                   # move
    all_buttons.append( butt[0], button_image, button_rect )

Это дает простой список all_buttons списков [имя кнопки, изображение с измененным размером кнопки, прямоугольник с предварительно установленной кнопкой].

И, вероятно, вы хотите if ... elif ... для этих тестов кнопок, а не if ... if ...:

        if event.type == pygame.MOUSEBUTTONDOWN:
            if NextHelpRect.collidepoint(event.pos): # Button navigaton.
                if MenuStatus == "Help menu 1":
                    MenuStatus = "Help menu 2"
                    Help()
                if MenuStatus == "Help menu 2":
                    MenuStatus = "Help menu 3"
                    Help()

Что происходит, когда MenuStatus равно «Меню справки 1» -> оно становится «Меню справки 2», но затем следующее if меняет снова на «Меню справки 3»

...