【问题标题】:How do I get my object in pygame to move by holding the button?如何通过按住按钮让我的 pygame 中的对象移动?
【发布时间】:2017-07-29 16:03:04
【问题描述】:

我尝试使用类似的东西,但它不起作用。

while running:
keys = pygame.key.get_pressed()  #checking pressed keys
if keys[pygame.K_UP]:
    y1 -= 1
if keys[pygame.K_DOWN]:
    y1 += 1

这是我目前拥有的代码。我尝试使用不同的方法,因为上述方法对我不起作用。它一次移动一个按钮。

import pygame
spaceX = 100
spaceY = 100
pygame.init
black = (0,0,0)
size = (800, 800)
screen = pygame.display.set_mode(size)

def game(spaceX, spaceY):
    spaceship_file = 'spaceship.png'
    spaceship_image = pygame.image.load(spaceship_file)
    spaceship = pygame.transform.scale(spaceship_image, (30, 30))
    screen.fill(black)
    screen.blit(spaceship, (spaceX, spaceY))
    pygame.display.flip()

    while True:
        for event2 in pygame.event.get():
            if event2.type == pygame.KEYDOWN and event2.key == pygame.K_LEFT:
                spaceX2 = spaceX - 5
                game(spaceX2, spaceY)

            elif event2.type == pygame.KEYDOWN and event2.key == pygame.K_RIGHT:
                spaceX2 = spaceX + 5
                game(spaceX2, spaceY)

game(spaceX, spaceY)

编辑:

我现在有这个代码。我的对象仍然只有在我反复点击按钮而不是按住按钮时才会移动。

def game(spaceX, spaceY):

    while True:
        screen.fill(black)
        screen.blit(spaceship, (spaceX, spaceY))
        pygame.display.flip()
        keys = pygame.key.get_pressed()

        for event in pygame.event.get():
            if keys[pygame.K_LEFT]:
                spaceX = spaceX - 5
                game(spaceX, spaceY)

            elif keys[pygame.K_RIGHT]:
                spaceX = spaceX + 5
                game(spaceX, spaceY)

【问题讨论】:

  • 不要在游戏循环中使用递归调用。 Python 在引发错误之前已将递归调用限制为 1000 次。您可以更改此限制,但更好的方法是将screen.fill(black)screen.blit(spaceship, (spaceX, spaceY))pygame.display.flip() 放入while True 循环中。这样您也不会在每次移动飞船时加载图像并对其进行缩放。
  • 你说“它没有用”是什么意思?因为它应该工作得很好。我以前多次使用完全相同的代码。
  • 我的意思是我之前尝试过使用 pygame.key.get_pressed() 而不是 pygame.KEYDOWN 但它不起作用。
  • 我的意思是你有没有得到一个错误,当你按下按钮时它没有注册,它是否有效但不是你想要完成的,等等?因为如果所有逻辑都是正确的,它应该可以工作,并且它是做你想做的事情的最简单的方法之一。或者你可以引入一个速度变量,在每个循环中添加到位置。
  • 我用一些编辑过的代码编辑了我的帖子。我确实让 pygame.key.get_pressed() 工作,但它仍然一次只能移动 1 个按键。似乎没有弹出错误。

标签: python python-2.7 pygame


【解决方案1】:

有两种方法可以检查键输入,一种是在事件队列中,另一种是检查它们的当前状态。

事件队列

按键在被按下或重新释放时被放入事件队列中,因此您无法直接判断按键是否被按住。有两种解决方法:

  1. 在进入主循环之前调用pygame.key.set_repeat(True)。这将重复地将 KEYDOWN 事件放入事件队列中,只要它被持有。

  2. 引入一个速度变量。当用户按下键时将速度设置为某个速度,当用户抬起键时将速度设置为0。

例如:

for event in pygame.event.get():
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_LEFT:
            velocity_x = -5
        elif event.key == pygame.K_RIGHT:
            velocity_x = 5
    elif event.type == pygame.KEYUP:
        if event.key == pygame.K_LEFT:
            velocity_x = 0
        elif event.key == pygame.K_RIGHT:
            velocity_x = 0

position_x += velocity_x

状态检查

您可以通过调用pygame.key.get_pressed() 获取键的当前状态。您必须调用pygame.event 中的函数之一,以便pygame 执行一些必需的内部操作,因此如果您不想使用事件队列,请使用pygame.event.pump()。如果您不这样做,您的操作系统会认为 pygame 已崩溃,从而导致游戏无响应。虽然,您通常希望处理 pygame.QUIT 事件,以便用户可以退出。

pygame.event.pump()
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
    position_x -= 5
elif keys[pygame.K_RIGHT]:
    position_x += 5

【讨论】:

    【解决方案2】:

    解决这个问题的一个方法是使用set_repeat 函数

    pygame.key.set_repeat(True)
    

    这将生成多个KEYDOWN 事件。

    【讨论】:

      【解决方案3】:

      尝试将密钥添加到您的 pygame for 循环中。所以它应该看起来像这样......

      while running:
      for event in pygame.event.get():
          keys = pygame.key.get_pressed()  #checking pressed keys
              if keys[pygame.K_UP]:
              y1 -= 1
      
              if keys[pygame.K_DOWN]:
              y1 += 1
      

      【讨论】:

      • pygame.key.get_pressed() 每个循环只能调用一次。不是针对 pygame.event.get() 中的每个事件。
      猜你喜欢
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多