【问题标题】:Optimizing Keyboard Input in Pygame在 Pygame 中优化键盘输入
【发布时间】:2016-12-14 12:29:43
【问题描述】:

我正在使用 pygame 库创建一个非常简单的游戏,其中玩家使用箭头键在屏幕上移动一个正方形。不幸的是,控件的响应被证明是一个问题。

在您切换方向之前,控件工作正常,例如左到右。当玩家切换方向时,玩家控制罐子的方格会停止。

我的游戏中的控件代码如下所示:

def move(self, event):
    speed = 6
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_LEFT:
            self.rect.x -= speed
        if event.key == pygame.K_RIGHT:
            self.rect.x += speed
        if event.key == pygame.K_DOWN:
            self.rect.y += speed
        if event.key == pygame.K_UP:
            self.rect.y -= speed

此方法位于一个名为 Block 的类中(我从 pygame 文档中窃取了 Block),它只是为玩家制作一个精灵并提供运动。

函数 move() 实际上是在 main.py 文件中这样调用的:

while going:
    clock.tick(60)

    # event handling
    for event in pygame.event.get():
        if event.type == QUIT:
            going = False

    # controller input
    player.move(event)

其中 player 是 Block 类的一个实例,而 event 只是我的游戏事件队列中的一个项目。

我尝试使用 pygame.key.get_pressed 函数(效果更好),但我宁愿使用 pygame.KEYDOWN 本地变量,因为它会将按键作为事件队列中的事件返回,而不是从列表返回布尔值。

如果您比一般的 joe 更具调查性,可以在此处查看“完整”游戏:https://github.com/catmes/Project_React

您将需要 pygame 1.9.2 和 python 2.7。请记住,游戏本身更像是一种学习练习,所以当你看到糟糕的代码时不要感到惊讶(当然,稍后会修复;))。

感谢您过来看看这个问题,非常感谢您抽出宝贵的时间。

【问题讨论】:

    标签: python-2.7 pygame


    【解决方案1】:

    我尝试了一种流畅的方式来围绕一个运行良好的玩家移动。它基本上跟踪列表中的按键并根据最后按下的键移动播放器。当您按下一个键时,它会在列表中的第一个位置添加一个 speed 变量,当您释放该键时,它将删除该变量。在 update 方法中,您将列表的第一个速度变量添加到相应的 x 和 y 值。

    import pygame
    pygame.init()
    
    screen = pygame.display.set_mode((720, 480))
    
    class Player(pygame.sprite.Sprite):
    
        def __init__(self):
            super(Player, self).__init__()
            self.rect = pygame.Rect((0, 0), (32, 32))
            self.image = pygame.Surface((32, 32))
            self.image.fill((255, 255, 255))
            self.velocity = [0, 0]  # It's current velocity.
            self.speed = 4  # The speed the player will move.
            self.dx = []  # Keeps track of the horizontal movement.
            self.dy = []  # Keeps track of the vertical movement.
    
        def update(self):
            try:
                self.rect.x += self.dx[0]  # Index error if the list is empty.
            except IndexError:
                self.rect.x += 0
            try:
                self.rect.y += self.dy[0]  # Index error if the list is empty.
            except IndexError:
                self.rect.y += 0
    
    player = Player()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                raise SystemExit
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_a:
                    player.dx.insert(0, -player.speed)
                elif event.key == pygame.K_d:
                    player.dx.insert(0, player.speed)
                elif event.key == pygame.K_w:
                    player.dy.insert(0, -player.speed)
                elif event.key == pygame.K_s:
                    player.dy.insert(0, player.speed)
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_a:
                    player.dx.remove(-player.speed)
                elif event.key == pygame.K_d:
                    player.dx.remove(player.speed)
                elif event.key == pygame.K_w:
                    player.dy.remove(-player.speed)
                elif event.key == pygame.K_s:
                    player.dy.remove(player.speed)
    
        player.update()
        screen.fill((0, 0, 0))
        screen.blit(player.image, player.rect)
        pygame.display.update()
    
        # print player.dx, player.dy  # Uncomment to see what's happening in action!
    

    【讨论】:

    • 效果很好!太感谢了。我尝试保持已释放键的状态,以查看这是否会优化控件,但没有达到您所做的程度。干杯!
    • 其实我很好奇您是如何在 Player 类中定义 init 函数的;当您之前在 Player 类中定义了 init 函数时,是否有特定原因使用 super() 来固有?
    • 我不太明白你的问题。我使用super(Player, self).__init__() 来初始化超类 pygame.sprite.Sprite。这样做不是必需的,但最好将所有可见类设为 Sprite 类的子类,这样您就可以将游戏对象添加到 pygame.sprite.Group 并利用一些有用的方法。 (pygame.org/docs/ref/sprite.html#pygame.sprite.Group)
    • 是的,这就是我想知道的。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 2022-01-22
    相关资源
    最近更新 更多