【问题标题】:constant movement in pygamepygame中的不断运动
【发布时间】:2015-04-22 22:58:04
【问题描述】:

这是我的第一个 pygame 代码不多,非常简单。当我想移动我的球员时,它可以工作,但我希望移动稳定。就像当我按下左键时,我希望它向左移动。目前我每次都必须按下左键,以便玩家向左移动。你有什么建议吗?

import pygame, sys

pygame.init()

window_size = ( 400, 400 )

white = ( 255, 255, 255 )

class Player():
  image = pygame.image.load( 'foo.png')
  rect = image.get_rect()

player = Player()

screen = pygame.display.set_mode( window_size )

done = False

while not done:
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      sys.exit()

    if event.type == pygame.KEYDOWN:
      if event.key == pygame.K_LEFT:
        move = (-10, 0 )
        player.rect = player.rect.move(move)
      if event.key == pygame.K_RIGHT:
        move = ( 10, 0 )
        player.rect = player.rect.move(move)
      if event.key == pygame.K_UP:
        move = ( 0,-10 )
        player.rect = player.rect.move(move)
      if event.key == pygame.K_DOWN:
        move = ( 0, 10 )
        player.rect = player.rect.move(move)

  screen.fill( white )
  screen.blit( player.image, player.rect )

  pygame.display.flip()

编辑我对亚伦的回答:

while not done:

  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      sys.exit()

  pressed = pygame.key.get_pressed()
  if pressed[pygame.K_LEFT]:
    move = ( 2, 0 )
    player.rect = player.rect.move(move)
  if pressed[pygame.K_RIGHT]:
    move = ( 2, 0 )
    player.rect = player.rect.move(move)
  if pressed[pygame.K_UP]:
    move = ( 0,-2 )
    player.rect = player.rect.move(move)
  if pressed[pygame.K_DOWN]:
    move = ( 0, 2 )
    player.rect = player.rect.move(move)

【问题讨论】:

    标签: python pygame


    【解决方案1】:

    您可以同时跟踪 KEYUPKEYDOWN 事件,然后为您正在跟踪的每个键存储按下状态。

    现在不是在用户按下键时移动播放器,而是测试键的状态以查看它是否被按下,如果是,则将移动应用于播放器。

    作为一个简化的例子:

    pressed_keys = {
        'left': false,
        ...define other keys...
    }
    
    while not done:
    
        # Check for key events
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    pressed_keys['left'] = True
                ...check other keys...
    
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT:
                    pressed_keys['left'] = False
                ...check other keys...
    
       # Move the player
       if pressed_keys['left']:
           ...move player left...
    

    【讨论】:

    • 您的回答也非常棒,因为有人知道这是如何工作的,但我将 Aarons 的回答标记为已接受,因为它更 'pygamic' :P跨度>
    • 最好只使用“get_pressed”来获取按下键的状态,而不是创建自己的字典来存储状态。使用您的代码,您必须为您感兴趣的每个键在游戏中添加 4 行不必要的代码。
    【解决方案2】:

    在类似问题上查看Sloth's answer。您似乎有两种可能的方法,使用 set_repeat 或 get_pressed。

    set_repeat

    启用键盘重复时,按住的键会产生多个 pygame.KEYDOWN 事件。延迟是发送第一个重复的 pygame.KEYDOWN 之前的毫秒数。之后,另一个 pygame.KEYDOWN 将每间隔毫秒发送一次。如果没有传递参数,则禁用键重复。 Source

    这样的事情就可以了:

    # set_repeat(delay, interval)
    pygame.key.set_repeat(1, 10) 
    # A delay of 0 disables the repeat.
    # The lower the interval, the faster the movement would be.
    

    get_pressed

    返回一个布尔值序列,表示键盘上每个键的状态。使用键常量值来索引数组。 True 值表示该按钮被按下。 使用此函数获取按钮列表不是处理用户文本输入的正确方法。您无法知道按键的顺序,并且在两次调用 pygame.key.get_pressed() 之间可能完全不会注意到快速按键。也没有办法将这些推送的键翻译成完全翻译的字符值。有关此功能,请参阅事件队列上的 pygame.KEYDOWN 事件。 Source

    这样的东西应该很适合你的代码:

    pressed = pygame.key.get_pressed()
    if pygame.K_LEFT in pressed:
       # move left
    if pygame.K_RIGHT in pressed:
       # move right
    

    在@ZedsWhatSheSaid 的代码中实现的解决方案,还添加了 PEP-8 格式:

    import pygame
    import sys
    
    pygame.init()
    
    window_size = (400, 400)
    
    white = (255, 255, 255)
    
    
    class Player():
        image = pygame.image.load('foo.png')
        rect = image.get_rect()
    
    player = Player()
    
    screen = pygame.display.set_mode(window_size)
    
    done = False
    
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
    
        pressed = pygame.key.get_pressed()
        if pygame.K_LEFT in pressed:
            move = (-10, 0)
        player.rect = player.rect.move(move)
        if pygame.K_RIGHT in pressed:
            move = (10, 0)
        player.rect = player.rect.move(move)
        if pygame.K_UP in pressed:
            move = (0, -10)
        player.rect = player.rect.move(move)
        if pygame.K_DOWN in pressed:
            move = (0, 10)
    

    【讨论】:

    • 我认为这里的第二个建议比我的回答更正确,我的回答基本上做同样的事情,但需要你用 Python 编写状态管理,而不是使用现有的 PyGame 接口。
    • 太棒了,我确实实现了它,所以无论如何我都会在我的答案中分享我的代码,不幸的是我目前无法测试,所以如果有错误,请随时编辑/删除我的补充。不过我很高兴你让它工作了,享受你的 Python 之旅吧!
    • @AaronCritchley 非常感谢 :)
    • 请永远不要使用set_repeatIt sucks.
    • 在较新版本的 pygame 中是if key[K_LEFT]:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-25
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多