afrcmg 2022-07-12 00:53 采纳率: 87.5%
浏览 116
已结题

pygame的键盘检测的问题

我希望实现的功能是不管按w还是按s,光标的位置始终都能在两个点之前切换

开始键盘keys的获取方式是这样的:

elif event.type in (pygame.KEYDOWN, pygame.KEYUP):
    self.keys = pygame.key.get_pressed()

然后处理keys分了好几种出错情况:
①下面的代码使用后,按一下键,有时是等于就按1下键,但也很多时候等于按2,3下键

        if keys[pygame.K_w] or keys[pygame.K_s]:
            if self.cursor_state == 'start':
                self.cursor_state = 'load'
                self.cursor_rect.y = 438
            else:
                self.cursor_state = 'start'
                self.cursor_rect.y = 398
        elif self.cursor_state == 'start' and keys[pygame.K_v]:
            self.finished = True

②情况①下方的代码不变,但把上面获取键盘代码改成
elif event.type == pygame.KEYDOWN:
self.keys = pygame.key.get_pressed()
按一下键就会无限循环重复按键(就像是按着不放一样)。反之把KEYDOWN改成KEYUP,就会没反应(就像没按一样)
③获取按键的方式仍然改为初始的
elif event.type in (pygame.KEYDOWN, pygame.KEYUP):
self.keys = pygame.key.get_pressed()
下面代码改成

        if keys[pygame.K_w]:
            self.cursor_state = 'start'
            self.cursor_rect.y = 398
        elif keys[pygame.K_s]:
            self.cursor_state = 'load'
            self.cursor_rect.y = 438
        elif keys[pygame.K_v]:
            if self.cursor_state == 'start':
                self.finished = True

这样按键一点问题都没有,点一下就是一下,不多不少。但是,没实现我的功能,我希望实现的功能是不管按w还是按s,光标的位置始终都能在两个点之前切换,而这样只能w上,s下
④为了实现功能,我在③的基础上,改了下面代码,如下:

        if keys[pygame.K_w]:
            if self.cursor_state == 'start':
                self.cursor_state = 'load'
                self.cursor_rect.y = 438
            else:
                self.cursor_state == 'start'
                self.cursor_rect.y = 398
        elif keys[pygame.K_s]:
            if self.cursor_state == 'start':
                self.cursor_state = 'load'
                self.cursor_rect.y = 438
            else:
                self.cursor_state == 'start'
                self.cursor_rect.y = 398
        elif keys[pygame.K_v]:
            if self.cursor_state == 'start':
                self.finished = True
                print(111111)

按理说,③都成功了,④应该也能成功才对。然而现实是,④没有反应,光标不移动,我试过单步调试,明明确定坐标已经改变了,也blit新的坐标了。然而画面没动静。
另外,更神奇的是,如果我一进去,在默认的'start'的状态下,按下v键,就会打印11111(即上面代码的最后几行)。除此之外,只要我按过w或s键,不管按几下,都不能再打印11111了

感觉就好像是,如果if keys[ ]:后面,只要多了一层if,就不能正常运行一样,不知道是什么原因

希望有高人能解答一下,有必要的话,我也可以加微信发源码。如果实再不行,我也只能放弃最初的功能

  • 写回答

2条回答 默认 最新

  • 关注

    因为你是判断键盘keys执行动作的代码放在 elif event.type in (pygame.KEYDOWN, pygame.KEYUP): 事件if块之外的,这样代码是快速重复执行多次的
    当你按住s键时,多次循环执行判断keys[pygame.K_s]都是true, 这样你第1个代码中

            if self.cursor_state == 'start':
                self.cursor_state = 'load'
                self.cursor_rect.y = 438
            else:
                self.cursor_state = 'start'
                self.cursor_rect.y = 398
    

    不是按一次键只执行一次,而是会执行多次,这样两个点就会反复切换状态,只有松开s键时才不再执行
    这种设置适合按住一个键时,对象多次连续执行移动操作的情况

    要按一次键只执行一次,需要把判断键盘keys执行动作的代码放在 elif event.type == pygame.KEYDOWN: 事件if块内

    elif event.type == pygame.KEYDOWN:
        keys = pygame.key.get_pressed()
        # 下边判断键盘keys执行动作的代码放在 elif event.type == pygame.KEYDOWN: 事件if块内,这样才是按一次键只执行一次 
        if keys[pygame.K_w] or keys[pygame.K_s]:
            if self.cursor_state == 'start':
                self.cursor_state = 'load'
                self.cursor_rect.y = 438
            else:
                self.cursor_state = 'start'
                self.cursor_rect.y = 398
        elif self.cursor_state == 'start' and keys[pygame.K_v]:
            self.finished = True
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 7月20日
  • 已采纳回答 7月12日
  • 创建了问题 7月12日

悬赏问题

  • ¥250 雷电模拟器内存穿透、寻基址和特征码的教学
  • ¥200 比特币ord程序wallet_constructor.rs文件支持一次性铸造1000个代币,并将它们分配到40个UTXO上(每个UTXO上分配25个代币),并设置找零地址
  • ¥15 关于Java的学习问题
  • ¥15 如何使用chatgpt完成文本分类任务?
  • ¥15 已知速度v关于位置s的等式,怎么转化为已知位置求速度v的等式
  • ¥15 我有个餐饮系统,用wampserver把环境配置好了,但是后端的网页却进去,是为什么,能不能帮远程一下?
  • ¥15 R运行没有名称为"species"的插槽对于此对象类"SDMmodelCV"
  • ¥20 基于决策树的数字信号处理,2ask 2psk 2fsk的代码,检查下报错的原因
  • ¥15 wincc已组态的变量过多
  • ¥60 如图:直线与椭圆X轴平行,求直线与椭圆任意一点的相切坐标计算公式