переменное событие, указанное перед назначением, хотя я ссылался на него - PullRequest
0 голосов
/ 14 июля 2020

Я пытался поместить все свои игровые уровни в одну программу. До этого все коды работали отлично. Однако когда я поместил все программы в их функции и попытался запустить первый уровень, я получил сообщение об ошибке:

 if event.type == pygame.KEYDOWN and event.key == pygame.K_UP and igralec.y > 10:
UnboundLocalError: local variable 'event' referenced before assignment

Я поискал эту ошибку в Интернете и сделал то, что должно быть исправлено; Я поместил эти строки кода под событие l oop, но это сделало игру неиграбельной; Пришлось нажать клавишу всего на один ход (удерживать не получалось). Затем я попытался изменить if на while, что тоже не сработало. Вот код:

 while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT or event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
            run = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE and igralec.ziv > 0:
                print(igralec.fire_rate)
                igralec.fire_rate += 1
                if igralec.fire_rate == 4:
                    igralec.fire_rate = 1 
                if igralec.fire_rate % 2 == 1 or igralec.fire_rate == 1:
                    strel.play()   
                    if igralec.levo:
                        smer = -1
                    else:
                        smer = 1
                    if len(metki) < 5:
                        metki.append(torpedo(igralec.x, igralec.y + 40, smer))
    for metek in metki:
        if metek.x < 1024 and metek.x > 0:
            metek.x +=  metek.v
            if metek.x > podmornca.okvir[0] and metek.x < podmornca.okvir[0] + podmornca.okvir[2]:
                if metek.y > podmornca.okvir[1] and metek.y < podmornca.okvir[1] + podmornca.okvir[3]:
                    zadetek.play()
        else:
            metki.pop(metki.index(metek))
    if event.type == pygame.KEYDOWN and event.key == pygame.K_UP and igralec.y > 10:
        igralec.y -= 5
    if event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN and igralec.y < 600:
        igralec.y += 5
    if event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
        igralec.levo = True
        igralec.desno = False
        eksploziv.x += igralec.v
        kamenx += igralec.v
        podmornca.zac += igralec.v
        podmornca.konc += igralec.v
        podmornca.x += igralec.v
    if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
        igralec.levo = False
        igralec.desno = True
        eksploziv.x -= igralec.v
        kamenx -= igralec.v
        podmornca.zac -= igralec.v
        podmornca.konc -= igralec.v
        podmornca.x -= igralec.v
    if event.type == pygame.KEYDOWN and event.key == pygame.K_RSHIFT :
        if igralec.ziv < 0: 
            restart = True

Ответы [ 2 ]

1 голос
/ 14 июля 2020

Как указано @pjk и другими, вам нужен код для проверки наличия ключей в событии l oop.

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

Вот несколько способов исправить это:

Мне нравится подход с повторяющимися клавишами, поэтому я сначала расскажу о нем.

Вы можете указать pygame, что вы хотите, чтобы он повторялся, давая вам события нажатия клавиши, если клавиша удерживается. Это похоже на то, что делают многие системы, когда клавиша удерживается. Вы можете получить его, указав pygame, что вы хотите, чтобы он периодически выдавал вам события KEYDOWN, пока клавиша удерживается. Вы используете команду pygame.key.set_repeat(delay, interval) (документы здесь ). Обычно pygame подделывает для вас события KEYDOWN, когда клавиша удерживается. delay - это сколько времени необходимо удерживать клавишу перед отправкой первого повторного ключевого события, а interval - это то, как часто вы хотите, чтобы событие повторялось после начальной задержки.

Вы также можете сделай это по-другому. Вместо того, чтобы реагировать на клавиши при их нажатии, вы отслеживаете состояние клавиш, на которые должна реагировать игра. Когда вы получаете событие KEYDOWN для одной из этих клавиш, вы устанавливаете переменную состояния, указывающую, что клавиша была нажата. Вы очищаете эту переменную, когда получаете соответствующее событие KEYUP для этого ключа. Затем за пределами события l oop вы можете реагировать на эту ключевую переменную состояния, чтобы все происходило, пока ключи удерживаются и состояние установлено.

Есть еще один способ, когда вы спрашиваете pygame, что клавиши в настоящее время нажимаются с использованием pygame.key.get_pressed(). Затем вы анализируете нажатые в данный момент клавиши из возврата. См. Документы здесь .

Если вы используете get_pressed(), вам все равно нужно событие l oop для обработки событий, иначе pygame не будет обрабатывать события, и ваша игра go не будет отвечать. Вы также можете использовать pygame.event.pump(), чтобы предотвратить задержку.

0 голосов
/ 14 июля 2020

event является локальным для первого для l oop. и после того, как l oop закончится, event выйдет за рамки. if event.type == pygame.KEYDOWN and event.key == pygame.K_UP and igralec.y > 10: igralec.y -= 5 находится за пределами l oop, что является причиной этой ошибки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...