在Python中生成一个没有库的“Key Released”?

2024-05-15 23:57:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在尝试使用一些库中的“键释放”函数,比如pynput等等,但是我遇到了一个问题,如果我尝试将它们与一个名为pyglet的库一起使用,这是一个基于窗口的应用程序库,它不会让我这样做,程序就会崩溃

我想知道是否有任何方法可以在没有库的情况下检测密钥释放

注:我试过使用pyglet的on_key_release函数,但对我来说是个bug,即使我为它写了一些东西,在密钥发布时,它通常也不会这样做。我已经检查了我的代码一千次,这对我来说不是一个问题

Pressing = False # var to indicate when the user is doing a long press and when he is not
@window.event
def on_key_release(symbol, modifiers):
    global Pressing
    if((symbol == key.A) | (symbol == key.S) | (symbol == key.W) | (symbol == key.D)):
        Pressing = False
    pass

这段代码会导致我的玩家在我开始移动他之后冻结,即使我什么都不做,只会把整个键释放空。真奇怪


Tags: key函数代码程序falsereleaseison
1条回答
网友
1楼 · 发布于 2024-05-15 23:57:25

因此,您的问题很可能是您正在执行Pressing = False,如果任何键被释放。当您释放任何键时,由于Pressing正在False而强制您的播放器对象冻结

为了解决这个问题,您应该将键的状态存储在一个变量中(我称之为self.keys),并且在您渲染东西之前,更新/检查键并相应地更新您的player对象

下面是一个在播放器对象上移动的工作示例(本例中为红色方块):

from pyglet import *
from pyglet.gl import *

key = pyglet.window.key

class main(pyglet.window.Window):
    def __init__ (self, width=800, height=600, fps=False, *args, **kwargs):
        super(main, self).__init__(width, height, *args, **kwargs)
        self.x, self.y = 0, 0

        self.keys = {}

        self.mouse_x = 0
        self.mouse_y = 0

        square = pyglet.image.SolidColorImagePattern((255, 0, 0, 255)).create_image(40, 40)
        self.player_object = pyglet.sprite.Sprite(square, x=self.width/2, y=self.height/2)

        self.alive = 1

    def on_draw(self):
        self.render()

    def on_close(self):
        self.alive = 0

    def on_mouse_motion(self, x, y, dx, dy):
        self.mouse_x = x

    def on_key_release(self, symbol, modifiers):
        try:
            del self.keys[symbol]
        except:
            pass

    def on_key_press(self, symbol, modifiers):
        if symbol == key.ESCAPE: # [ESC]
            self.alive = 0

        self.keys[symbol] = True

    def render(self):
        self.clear()

        ## Movement logic,
        #  check if key.W is in self.keys (updated via key_press and key_release)
        if key.W in self.keys:
            self.player_object.y += 1
        if key.S in self.keys:
            self.player_object.y -= 1
        if key.A in self.keys:
            self.player_object.x -= 1
        if key.D in self.keys:
            self.player_object.x += 1

        self.player_object.draw()

        self.flip()

    def run(self):
        while self.alive == 1:
            self.render()

            #      -> This is key <     
            # This is what replaces pyglet.app.run()
            # but is required for the GUI to not freeze
            #
            event = self.dispatch_events()

if __name__ == '__main__':
    x = main()
    x.run()

我已经离开了@window.event,因为复制粘贴这个类/继承的例子对我来说比较容易,因为我已经把它放在这里了。但你可以用任何你想用的逻辑。只要确保你没有定义一个固态的按下或不按下,检查个别关键点,并相应地更新之前,你渲染

相关问题 更多 >