Pygame:key.get_pressed() 与事件队列不一致 [英] Pygame: key.get_pressed() does not coincide with the event queue

查看:31
本文介绍了Pygame:key.get_pressed() 与事件队列不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Python 中的 pygame 为应用程序制定简单的控件.我已经掌握了基础知识,但遇到了奇怪的问题:我正在使用箭头键来控制我的角色.如果我按住一个箭头键,然后按住另一个箭头键(对角移动),角色会按预期移动.但是,如果我松开我按下的 second 键(同时按住 first 键),角色会停止移动,即使我仍然按住第一个键.这是我的简单移动代码:

I'm attempting to work out simple controls for an application using pygame in Python. I have got the basics working, but I'm hitting a weird wall: I am using the arrow keys to control my character. If I hold down one arrow key, then hold down another arrow key (to move diagonally), the character moves as expected. However, if I release the second key that I pressed (while still holding down the first key), the character stops moving, even though I am still holding down that first key. Here is my simple movement code:

for event in pygame.event.get():
    if event.type == QUIT:
        pygame.quit()
        sys.exit()
    elif event.type == KEYDOWN:
        if pygame.key.get_pressed()[K_LEFT]:
            player.pos = (player.pos[0] - 2, player.pos[1])
        if pygame.key.get_pressed()[K_RIGHT]:
            player.pos = (player.pos[0] + 2, player.pos[1])
        if pygame.key.get_pressed()[K_UP]:
            player.pos = (player.pos[0], player.pos[1] - 2)
        if pygame.key.get_pressed()[K_DOWN]:
            player.pos = (player.pos[0], player.pos[1] + 2)

现在,我自然对此感到非常困惑.所以我尝试打印一些行进行调试.在主控制循环的顶部,我写道:

Now, I was naturally very confused by this. So I tried to print some lines to debug. In the top of the main control loop, I wrote:

print (pygame.key.get_pressed()[K_DOWN], pygame.key.get_pressed()[K_RIGHT])
print pygame.event.get()

...输出一个显示向下和向右箭头键状态的元组,然后显示pygame事件队列.我的结果更让我困惑.如果我对角向下和向右移动字符,先按向下键,然后按右键,然后松开右键使其简单向下移动,字符会像以前一样停止移动......但是这将打印到外壳:

...to output a tuple displaying the state of the down and right arrow keys, and then display the pygame event queue. My results baffled me even more. If I move the character diagonally down and right, pressing the down key first and then the right key, then release the right key to make it move simply downward, the character stops moving as before... but this is printed to the shell:

(1, 0)
[]

也就是说,当我松开右箭头键并仍然按住向下箭头键时,pygame.key.get_pressed() 知道向下箭头键仍然被按住,但是有事件队列中什么都没有.

That is, when I release the right arrow key and still hold down the down arrow key, pygame.key.get_pressed() understands that the down arrow key is still being held down, but there is nothing in the event queue.

此外,在代码的前面(在控制循环之前)我正在调用

Also, earlier in the code (before the control loop) I am invoking

pygame.key.set_repeat(1, 2)

使角色在按住键的同时继续移动.

to make the character continue to move while the key is held down.

任何帮助将不胜感激!谢谢:)

Any help will be appreciated! Thanks :)

推荐答案

对于诸如移动之类的事情,您不应该检查事件(例如 KEYDOWNKEYUP),但是如果您的移动键被按下(使用 get_pressed).

For things like movement, you should not check for events (like KEYDOWN or KEYUP), but check every iteration of your mainloop if your movement keys are pressed (using get_pressed).

在您的代码中,只有当还有 KEYDOWN 事件时,您才检查按下的键.

In your code, you check the pressed keys only if there's also a KEYDOWN event.

还有一些其他的事情需要考虑:

There are also some other things to consider:

  • 您应该将键映射和播放器的速度分开,以便以后更改其中任何一个都更容易.

  • You should seperate the key-mapping and the speed of your player, so it will be easier later on to change either of this.

你应该先确定一个移动向量并对其进行归一化,否则,如果你的垂直和水平移动速度是10,你的对角线移动速度将是~14代码>.

You should determine a movement vector and normalize it first, since otherwise, if your vertical and horizontal movement speed is 10, your diagonal movement speed would be ~14.

工作示例:

import pygame

pygame.init()

screen = pygame.display.set_mode((200, 200))
run = True
pos = pygame.Vector2(100, 100)
clock = pygame.time.Clock()

# speed of your player
speed = 2

# key bindings
move_map = {pygame.K_LEFT: pygame.Vector2(-1, 0),
            pygame.K_RIGHT: pygame.Vector2(1, 0),
            pygame.K_UP: pygame.Vector2(0, -1),
            pygame.K_DOWN: pygame.Vector2(0, 1)}

while run:
  for e in pygame.event.get():
    if e.type == pygame.QUIT: run = False

  screen.fill((30, 30, 30))
  # draw player, but convert position to integers first
  pygame.draw.circle(screen, pygame.Color('dodgerblue'), [int(x) for x in pos], 10)
  pygame.display.flip()

  # determine movement vector
  pressed = pygame.key.get_pressed()
  move_vector = pygame.Vector2(0, 0)
  for m in (move_map[key] for key in move_map if pressed[key]):
    move_vector += m

  # normalize movement vector if necessary
  if move_vector.length() > 0:
    move_vector.normalize_ip()

  # apply speed to movement vector
  move_vector *= speed

  # update position of player
  pos += move_vector

  clock.tick(60)

这篇关于Pygame:key.get_pressed() 与事件队列不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆