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

2024-10-04 11:25:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着把我所有的游戏关卡都放在一个程序里。在此之前,所有代码都工作得很好。但是,当我将所有程序放入其函数中并尝试运行第一级时,我遇到了一个错误:

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

我在网上搜索了这个错误并做了修复程序;我将这些代码放在for event循环下,但这使游戏无法运行;我只需按一下键就可以移动一步(按住键不动)。然后我试着把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

Tags: andkey程序eventifratetypepygame
2条回答

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

正如@pjk和其他人所说,您确实需要代码来检查事件循环中的键

您在修复时说过,游戏变得无法玩,因为您必须反复按按键,因为按住按键没有任何作用。被按下的键是一个事件,只有在按下该键时才会发生。当释放一个键时,您也会得到一个事件,但在按住键时不会生成任何事件。然而,有办法解决这个问题

以下是一些解决方法:

我喜欢重复关键点的方法,这就是为什么我将首先介绍它

您可以告诉pygame,如果按下了键,您希望它重复给您下键事件。这类似于许多系统在按下键时所做的操作。您可以通过告诉pygame您希望它在按住键的同时定期给您提供KEYDOWN事件来获得它。您可以使用命令pygame.key.set_repeat(delay, interval)(docshere)。基本上,当你按下一把钥匙时,pygame会为你模拟按键事件。delay是在发送第一个重复键事件之前需要按住键多长时间,interval是希望在初始延迟后重复事件的频率

你也可以用另一种方法。当按键被按下时,你不是对按键做出反应,而是跟踪你想让游戏做出反应的按键的状态。当您获得其中一个键的KEYDOWN事件时,您设置了一个状态变量,指示该键已被按下。当您获得该键对应的KEYUP事件时,可以清除该变量。然后,在事件循环之外,您可以对这些键状态变量做出反应,只要保持键并设置状态,事情就会发生

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

如果您使用get_pressed(),您仍然需要一个事件循环来处理事件,否则pygame将不会处理事件,您的游戏将失去响应。您还可以使用pygame.event.pump()来防止此暂停

相关问题 更多 >