【问题标题】:Is it me or is pygame.key.get_pressed() not working?是我还是 pygame.key.get_pressed() 不起作用?
【发布时间】:2013-06-26 16:13:29
【问题描述】:

好的,所以我正在制作一个基本的宇宙飞船游戏。

我无法让旋转工作,因为它会扰乱位图,但这是另一个问题。我什至应该使用 gif 吗?还有其他文件类型建议吗?

回到这里的实际点,所以:

k = pygame.key.get_pressed()

是的,不言自明。这不起作用,因为它会返回按下的每个键。

所以,别处:

d = k[pygame.K_d]

还有一行:

print d

还有一个:

if d:

因此,k 在键盘上的每个键被按下时返回。

无论是否按下 d,d 都会无限期返回 0。

d 始终为 0。

因此,关于 d 的陈述永远不会正确。

为什么会这样?

【问题讨论】:

  • 从您的措辞很难看出:您是否希望 get_pressed() 函数在按下键后立即返回?
  • 你在循环print d

标签: python input pygame


【解决方案1】:

您可能会对get_pressed() 的实际操作感到困惑。来自文档:

返回一个 布尔值序列,表示每个键的状态 键盘。使用键常量值来索引数组。真值 表示该按钮被按下。

用这个函数获取按钮列表不是 处理来自用户的文本输入的正确方法。你没有办法知道 按键的顺序,快速按键可以完全 在两次调用 pygame.key.get_pressed() 之间没有被注意到。还有 无法将这些推送的键翻译成完全翻译的 字符值。查看事件队列上的 pygame.KEYDOWN 事件 这个功能。

换句话说,当您调用 get_pressed() 时,您将获得在调用 get_pressed() 时键盘状态的表示

例如,假设您在游戏开始前一秒调用了 get_pressed()。您将返回一个结构,其中列出了键盘上的所有键以及它们是否被按下(它们都是错误的)。

在游戏开始两秒后,您按下了一个键。如果您查看之前查看的相同结构,它仍然会说所有内容都未按下,因为您仍在查看一秒钟前的键盘状态。然而,如果你再次调用 get_pressed(),你会得到一个新的、更新的结构,这个新结构应该显示按键被按下。

解决此问题的一种方法是执行以下操作:

while True:
    # Update Stuff
    # Draw Stuff
    state = pygame.key.get_pressed()
    # Now check the keys

现在,您可以在键盘上获取最新信息。

需要注意的一点是,使用上述功能,您仍然可能会错过按键盘的操作。如果更新功能需要很长时间,则可能会在一个足够短的时间内按下某个键,然后在按下该键时不会调用 get_pressed()。

如果这可能是个问题,您可能希望改用事件循环。比如……

is_moving = False

while True:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN and event.key == pygame.K_d:
            is_moving = True
        elif event.type == pygame.KEYUP and event.key == pygame.K_d:
            is_moving = False

【讨论】:

  • 理论上,如果我在更新函数中定义 k 和 d (在播放器生命的每一帧上调用)它应该可以工作。到目前为止,我度过了糟糕的一天,我应该想到这一点,但是,我没有!谢谢马克。极快的回复速度和我可能应该拥有的洞察力。我习惯于使用稍微不同的库,其中通过类似的值引用函数在当时是有效且准确的。我的错!
  • 另外,关于按键的事情(与上一条评论分开)。 get_pressed 将为键盘上的每个键获取一个布尔值。 get_pressed 不是针对事件 pygame.KEYDOWN,而是针对键被按下的实际想法(允许轻松连续移动)。在经过一帧后(对于测试游戏来说,时间并不长,它只是一个原型,我可以修复响应性),应该返回准确的值。
  • 那么...我回答你的问题了吗?
  • 是的,对不起,我忘了说!
【解决方案2】:

对于混合 (1) 事件和 (2) 键状态输入,它看起来像

import pygame
from pygame.locals import *

done = False    

while not done:
    for event in pygame.event.get():
        # any other key event input
        if event.type == QUIT:
            done = True        
        elif event.type == KEYDOWN:
            if event.key == K_ESC:
                done = True
            elif event.key == K_F1:
                print "hi world mode"

    # get key current state
    keys = pygame.key.get_pressed()
    if keys[K_SPACE]:
        #repeating fire while held
        fire() 

我喜欢 KEYDOWN 和 KEYUP 也是如此,

您必须轮询事件。一种方法是

while not done:
    for event in pygame.event.get():
        # any other key event input
        if event.type == QUIT:
            done = True        
        elif event.type == KEYDOWN:
            if event.key == K_ESC:
                done = True

    player.handle_event(event)

然后在Player()

def handle_event(self, event):
    if event.type == KEYDOWN:
        if event.key == K_f: print 'Player.f pressed'

【讨论】:

  • 我真的很喜欢 pygame.key.get_pressed() 存在于 for 循环之外来处理事件的事实。我希望 KEYDOWN 和 KEYUP 也是如此,但我永远无法让它工作。为什么会这样,你知道吗?
  • 我添加了代码。您始终必须使用其中一种轮询函数,但是,您可以在类自己处理事件的“外部”传递事件副本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-05
相关资源
最近更新 更多