У меня есть функция, которая позволяет пользователю щелкнуть значок и установить логическое значение, чтобы основной цикл знал, какое действие выполнить. Код предназначен для работы как значок аэрографа щелчка -> установите для airbrushMode значение true -> верните airbrushMode, чтобы paintScreen() мог его обнаружить -> выполнить действие, установленное airbrushMode в цикл while. Я добавил операторы печати, чтобы найти проблему. Переменная изменяется, но переменная не возвращается, и функция аэрографии не работает. Это действительно работает, когда я устанавливаю для airbrushMode значение true внутри paintScreen(), но установка значения false в функции и вне функции не работает.

Основная функция

def paintScreen():
    airbrushMode = False
    paint = True
    gameDisplay.fill(cyan)
    message_to_screen('Welcome to PyPaint', black, -300, 'large')
    cur = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    pygame.draw.rect(gameDisplay, white, (50, 120, displayWidth - 100, displayHeight - 240))
    while paint:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        button('X', 20, 20, 50, 50, red, lightRed, action = 'quit')
        icon(airbrushIcon, white, 50, displayHeight - 101, 51, 51, white, grey, 'airbrush')
        icon(pencilIcon, white, 140, displayHeight - 101, 51, 51, white, grey, 'pencil')
        icon(calligraphyIcon, white, 230, displayHeight - 101, 51, 51, white, grey, 'calligraphy')
        pygame.display.update()
        if cur[0] >= 50 <= displayWidth - 50 and cur[1] >= 120 <= displayHeight - 120:
            if airbrushMode == True:
                airbrush()

Функция, которая создает значки и обнаруживает действие, а затем возвращает его

def icon(icon, colour, x, y, width, height, inactiveColour, activeColour, action = None):
    cur = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    if x + width > cur[0] > x and y + height > cur[1] > y:#if the cursor is over the button
        pygame.draw.rect(gameDisplay, activeColour, (x, y, width, height))
        gameDisplay.blit(icon, (x, y))
        if click[0] == 1 and action != None: #if clicked
            print('click')
            if action == 'quit':
                pygame.quit()
                quit()
            elif action == 'airbrush':
                airbrushMode = True
                print('airbrush set')
                return airbrushMode
                print('airbrush active')
0
Normy Haddad 21 Фев 2019 в 02:39

2 ответа

Лучший ответ

Ваша проблема в том, что icon не пытается изменить какие-либо глобальные переменные; он имеет дело строго со своими входными параметрами и локальными переменными. Если вы хотите, чтобы он изменил переменную за пределами своей области видимости, вам нужно добавить

global airbrushMode

В верхней части вашей функции.

Кроме того, если вы ожидаете, что paintScreen распознает глобальную переменную, у вас должно быть либо глобальное присутствие (использование верхнего уровня) этой переменной, либо paintScreen также требуется объявление global.

Для получения полной информации, посмотрите глобальные переменные в Python.

2
Prune 20 Фев 2019 в 23:45

Вместо проверки событий в icon(), возможно, код будет работать более плавно, если он публикует событие при нажатии кнопки.

def icon(icon, colour, x, y, width, height, inactiveColour, activeColour, action = None):
    cur = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    if x + width > cur[0] > x and y + height > cur[1] > y:#if the cursor is over the button
        pygame.draw.rect(gameDisplay, activeColour, (x, y, width, height))
        gameDisplay.blit(icon, (x, y))
        if click[0] == 1 and action != None: #if clicked
            print('click')
            pygame.event.post( pygame.USEREVENT + 1, {} )

Затем обработайте это в вашем основном цикле:

while paint:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
        elif event.type == pygame.USEREVENT + 1
            airbrushMode = True

Если бы это был я, я бы сделал набор своих собственных типов событий:

import enum

...

class MyEvents( enum.Enum ):
    AIRBRUSH = pygame.USEREVENT + 1
    PEN      = pygame.USEREVENT + 2
    PENCIL   = pygame.USEREVENT + 3

Который позволяет:

pygame.event.post( MyEvents.AIRBRUSH, {} )

...

elif ( event.type == MyEvents.AIRBRUSH ):
    airbrushMode = True
1
Kingsley 20 Фев 2019 в 23:59