Сделать «выпущенный ключ» в Python без библиотеки? - PullRequest
0 голосов
/ 21 октября 2019

Я пытался использовать некоторые «освобожденные ключом» функции из таких библиотек, как pynput и т. Д., Но я столкнулся с проблемой, что если я попытаюсь использовать их вместе с библиотекой с именем pyglet, это библиотека для оконных приложений, она мне не даст, и программа зависнет.

Мне было интересно, есть ли какой-нибудь способ обнаружения выпусков ключей без библиотек.

PS: я пытался использовать функцию on_key_release из pyglet, но она была для меня глючной, и хотя я писал что-то для нее при отпускании ключа, он обычно этого не делал. Я проверял свой код тысячу раз, и это не проблема с моей стороны.

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

, и этот код заставляет моего игрока зависать после того, как я начинаю его перемещать, и он делает это, даже если я ничего не делаю ипросто выщелочить весь каталог on_key_release пустым. действительно странно.

1 Ответ

0 голосов
/ 23 октября 2019

Итак, ваша проблема, скорее всего, в том, что вы делаете Pressing = False, если любой ключ выпущен. Принудительное зависание объекта игрока из-за того, что Pressing означает False, как только вы отпустите любой из ваших ключей.

Чтобы обойти это, вы должны хранить состояния ваших ключей в переменной (I 'Я назову это self.keys), и непосредственно перед рендерингом обновите / проверьте ключи и соответственно обновите объект вашего игрока.

Вот рабочий пример движения на объекте игрока (в данном случае красный квадрат)):

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, потому что мне проще скопировать и вставить этот пример класса / наследования, поскольку он у меня лежал. Но вы можете применить эту логику так, как вы хотите. Просто убедитесь, что вы не определили твердое состояние нажатия или не нажатия, проверьте отдельные клавиши и обновите соответственно перед рендерингом.

...