【问题标题】:PyGame separate thread for keyboard input handling [duplicate]PyGame 用于键盘输入处理的单独线程[重复]
【发布时间】:2020-05-03 11:25:56
【问题描述】:

我正在制作一个蛇形运动的游戏。我认为,获得良好结果的最佳方法是制作单独的线程来处理用户的键盘输入。这是我想在单独的线程中运行的函数:

    def _handle_keyboard_input(self):
        while self.is_running:
            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT:
                        self._set_velocity(-1, 0)
                    elif event.key == pygame.K_RIGHT:
                        self._set_velocity(1, 0)
                    elif event.key == pygame.K_UP:
                        self._set_velocity(0, -1)
                    elif event.key == pygame.K_DOWN:
                        self._set_velocity(0, 1)

    def _set_velocity(self, x, y):
        self._velocity_x = x
        self._velocity_y = y

尽管我担心,是否不断循环通过该 while 是否会过多地加载 CPU。我考虑过添加pygame.time.delay() 延迟,但我不确定我是否会“击中”KEYDOWN 事件的正确时机(我在下面这个网站上找到的图形)。

我不想使用pygame.key.get_pressed(),因为我不想优先考虑任何键(例如,如果同时按下左箭头和上箭头,我将不得不选择其中一个)。

最好的方法是什么?

【问题讨论】:

  • 请注意队列中的pygame.event.get()。如果您有多个事件循环(即使在不同的线程中),那么您将错过事件!我看不出有什么好的理由在不同的线程中处理事件。将耗时的计算转移到不同的线程,而不是事件处理。更新和计时也需要事件处理。
  • 在主线程中我有pygame.time.delay(500),因为我不想让蛇以那个频率移动,所以这个延迟会阻塞一段时间并且键盘无法处理
  • 我认为,获得良好结果的最佳方法是为处理用户的键盘输入创建单独的线程是什么让你这么认为?
  • @sloth 事实上,用户输入将不断被处理,没有任何中断。但我没有意识到 pygame 事件存储在队列中,现在它没有意义了

标签: python multithreading pygame keyboard-events


【解决方案1】:

注意pygame.event.get() 从队列中删除事件。如果您有多个事件循环(即使在不同的线程中),那么您将错过事件。没有必要在显示更新之后更频繁地处理事件,因为状态更改仅在显示更新后才“可见”。由于事件存储在队列中,因此无需在“正确”时刻获取事件,pygame.event.get() 获取并从队列中删除所有未决事件。

如果你想每 500 毫秒移动一次蛇,那么我建议使用pygame.time.Clocktick 方法返回自上次调用以来经过的毫秒数。
求和超过 500 的毫秒数,移动蛇:

clock = pygame.time.Clock()
count_ms = 0

FPS = 100
run = True
while run:
    passed_ms = clock.tick(FPS)

    # event loop
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        # [...]

    count_ms += passed_ms
    if count_ms >= 500:
        count_ms = count_ms % 500

        # move and draw snake
        # [...]

        pygame.display.flip()

【讨论】:

  • 另外,pygame.event.get() 只能在主线程上正常工作。
  • 哦,我没有注意到事件存储在队列中,这解决了我的问题,非常感谢
猜你喜欢
  • 2012-01-02
  • 1970-01-01
  • 2015-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
  • 2011-02-09
  • 2012-11-19
相关资源
最近更新 更多