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

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日

悬赏问题

  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 linux驱动,linux应用,多线程