尽管我引用了变量事件,但在赋值之前引用了它

时间:2020-07-14 17:39:42

标签: python pygame

我试图将所有游戏关卡放在一个程序中。在此之前,所有代码都运行良好。但是,当我将所有程序放入其功能中并尝试运行第一级时,出现错误:

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

我在线搜索了此错误,并做了应该解决的问题;我将这些代码行用于事件循环,但这使游戏无法进行。我只需要按一下键就可以了(按住不起作用)。然后,我尝试更改是否为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 个答案:

答案 0 :(得分:1)

如@pjk和其他人所述,您确实需要用于检查键的代码,使其位于事件循环中。

您说过,当您修复游戏变得无法玩时,因为您必须反复按下键,因为按住键不会执行任何操作。按下按键是一个事件,仅在按下按键时才会发生。释放键时也会收到一个事件,但按住该键时不会生成任何事件。但是,有一些解决方法。

以下是一些解决方法:

我喜欢重复的密钥方法,这就是为什么我将首先介绍它。

您可以告诉pygame您希望它重复一次,如果按住该键,则为您提供按键事件。这类似于许多系统在按住键时所做的事情。您可以通过告诉pygame您希望它在按住键的同时定期给您提供KEYDOWN事件来获取它。您使用命令pygame.key.set_repeat(delay, interval)(文档here)。基本上,当按住某个键时,pygame会为您伪造KEYDOWN事件。 delay是发送第一个重复按键事件之前需要按住一个键的时间,而interval是您希望在初始延迟后重复事件的频率。

您也可以采用其他方式。您无需跟踪按下键时的反应,而是可以跟踪要让游戏做出反应的键的状态。当您收到其中一个键的KEYDOWN事件时,将设置一个状态变量,指示该键已被按下。当您为该键获得相应的KEYUP事件时,便会清除该变量。然后,在事件循环之外,只要按住键并设置状态,就可以对那些键状态变量做出反应以使事情发生。

还有另一种方法,您可以通过pygame.key.get_pressed()询问pygame当前按下了哪些键。然后,您从返回中解析当前按下的键。参见文档here

如果您使用get_pressed(),则仍需要一个事件循环来处理事件,否则pygame将不处理事件,并且游戏将无法响应。您还可以使用pygame.event.pump()来防止这种停顿。

答案 1 :(得分:0)

event对于第一个for循环而言是本地的。循环结束后event将超出范围。 if event.type == pygame.KEYDOWN and event.key == pygame.K_UP and igralec.y > 10: igralec.y -= 5在for循环之外,这是导致此错误的原因。