当前位置: 首页 > 知识库问答 >
问题:

Pygame:如何在不丢失连续移动的情况下将键盘控制置于单独的模块中

羊越
2023-03-14

概述我正在制作一个可以向四个方向移动的宇宙飞船游戏。在游戏中,我的飞船可以通过键盘控制,如下所示。为了简单起见,我只展示了代码的一部分,以及我将太空船移到右侧的部分。

方法如前所述,我使用一个for循环和pyplay模块来接收键盘输入。我正在使用标志方法来实现连续移动。我首先将所有标志设置为False。然后根据键盘按下的不同,它会向不同的方向移动,并在按键上升时再次设置为False。它的所有工作正常...注:变量surf_centerx是我飞船的中心,screen.blit(冲浪,surf_rect),pygame.display.flip()在最后只是在屏幕上显示飞船,并分别更新飞船位置的最新变化。

import pygame
# pygame initializing
pygame.init()

#create the screen surface
screen =  pygame.display.set_mode((400, 400))

#..snip...

speedfactor = 0.1
move_right = False
#..snip...
while True:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                move_right = True
#..snip...
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                move_right = False
#..snip...

    if move_right:
        surf_centerx += speedfactor

#..snip...

    screen.blit(surf, surf_rect)
    pygame.display.flip()

代码重构——我想,但因为我的while循环不断增长,我想做一些代码重构,我想:o)所以我会把我的键盘材料放在一个单独的模块中,然后在while循环中调用一个函数。我将k_c.check_key_events()中的值保存在变量'returned'中,并在该变量下通过行'move_right=returned'解包该值。我的while循环现在看起来像这样(短得多):

import keyboard_control as k_c
while True:
    returned = k_c.check_key_events()
    move_right = returned
    if move_right:
        surf_centerx += speedfactor
#..snip...

    screen.blit(surf, surf_rect)
    pygame.display.flip()

控制键盘的侧模块(键盘控制)为:

import pygame

#necessary pygame initializing
pygame.init()

def check_key_events():
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                move_right = True
#..snip...
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                move_right = False
#..snip...
    return move_right

我现在调用主模块中“while循环”中的键盘控制模块,键盘控制模块现在应该返回“move\u right”变量的值。将for循环等放在自己的模块中可以有效地简化主模块。

问题,但现在运行我的程序会出现错误:*返回move\u right UnboundLocalError:赋值前引用的局部变量'move\u right'*

问题是函数不知道变量“move_right”,因为它没有在函数“check_key_events()”中定义。如果我在函数的开头定义它,比如:

#..snip...
def check_key_events():
    move_right = False
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                move_right = True
#..snip...

然后我的问题是我失去了连续移动,因为在while循环的每个周期中,行“returned=k_c.check_key_events()”调用函数“check_key_events()”,该函数将变量move_right设置为False,即使我没有释放“move right”键。所以我的问题是我如何巧妙地解决这个问题??我就是搞不懂。

共有1个答案

毋胜涝
2023-03-14

有(至少)两种方法来解决这个问题,快速的和正确的。

快速“n”脏:将您的move_right声明为全局变量,并将global move_right放在函数开头。这将起作用,但它相当丑陋,因为全局变量是邪恶的。

正确的方法是为你的宇宙飞船设置一个类,并在那里设置一个属性,告诉你你正在向哪个方向移动。这是一段很长的路,但肯定是你想要的,因为也许以后你会想在宇宙飞船物体上展开。

 类似资料:
  • 我使用下面的代码(来自这个答案)来配置要记录在WebClient请求上的头: 这很管用,但感觉有点奇怪。问题是:我是否需要像这样包含Jackson/objectMapper配置,或者是否有更简单的方法来避免Spring objectMapper配置被覆盖?

  • 我正在尝试构建一个自动化脚本来安装chrome扩展。 在我的本地系统(windows 10)上,当使用java的Robot类时,所有这些都可以正常工作,因为我有一个物理键盘连接到我的计算机。 问题是——当我试图在虚拟机(亚马逊EC2,视窗服务器)上运行这种自动化时,机器人类不起作用,因为它无法检测键盘的物理连接。 有没有其他方法可以在不连接键盘的情况下模拟键盘行程? 仅供参考,我必须使用键盘,因为

  • 问题内容: 我有一个带有一些视图的布局,其中一个是EditText。布局很容易放在一页上,但当软键盘退出时,布局不会滚动。这是我的布局的回顾: 在清单中,我声明了该属性: 有谁知道为什么它不起作用以及如何确保它起作用? 提前致谢! 问题答案: 好的,显然不应该将ScrollView 设置为。我将其设置为并将其设置为页面底部的按钮。 不要问我为什么,但这可以解决问题。

  • 我正在尝试使用selenium创建自动化,以安装chrome扩展。当我尝试在amazon虚拟机上运行这个jar时,我遇到了一个问题,因为当我尝试用robot类按enter键时,它不起作用,因为我没有连接物理键盘。我不能在selenium中使用sendkeys,因为来自google的pop不在同一页面,selenium无法识别它。有什么解决办法吗?

  • 问题内容: 我想更改数据库表的列位置而不丢失数据。 例如: 当前表: 到 问题答案: 试试这个:

  • 我想在不丢失数据的情况下更改数据库表的列位置。 例如: 当前表格: 到