Как сделать функцию мультиключей в Python? - PullRequest
0 голосов
/ 27 июня 2018

Я использую Python 3.5. Я хочу сделать функцию многократного нажатия. значит, я хочу сделать функцию, которая замечает оба Ctrl + S and Q. Но программа этого не делает.

Вот мой код:

import threading, pygame, sys
from pygame.locals import *
from time import sleep

pygame.init()
screen = pygame.display.set_mode((1160, 640), 0, 0)
screen.fill((255, 255, 255))
pygame.display.flip()

def background():
    while True:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if pygame.key.get_mods() & pygame.KMOD_CTRL and event.key == pygame.K_s:
                    print('GOOD')

def foreground():
    while True:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_q:
                    print('HELLO_WORLD')
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

b = threading.Thread(name='background', target=background)

b.start()
foreground()

Программа замечает Q, но не Ctrl + S.

Я хочу, чтобы эта программа заметила их обоих.

Как мне это сделать?

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Вы должны обрабатывать все ваши события pygame из одного потока / места, даже если вы можете использовать функциональность pygame из других потоков ... если вы все еще настаиваете на наличии нескольких потоков для чтения событий клавиатуры, вы делите состояние клавиши с чем-то вроде это:

import threading
import pygame
import sys
from pygame.locals import *
from time import sleep

pygame.init()
screen = pygame.display.set_mode((1160, 640), 0, 0)
screen.fill((255, 255, 255))
pygame.display.flip()
keys = {
    "mods": 0
}


def background():
    while True:
        mods = keys.get("mods", None)

        if keys["mods"] & pygame.KMOD_CTRL and keys.get(pygame.K_s, False):
            print("GOOD")


def foreground():
    pygame.display.update()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                keys[event.key] = True

                mods = pygame.key.get_mods()
                if mods:
                    keys["mods"] = mods
            elif event.type == pygame.KEYUP:
                keys[event.key] = False
                keys["mods"] = 0

            if event.type == QUIT:
                pygame.quit()
                sys.exit()


b = threading.Thread(name='background', target=background)
b.start()
foreground()

Но я бы рекомендовал вам избегать этого, обычно вы хотите обрабатывать все входные данные игры в одном потоке и использовать другие потоки для обработки различных частей игры (физика, аудио, логика, ...).

Тем не менее, мое эмпирическое правило при создании приложений реального времени - проектировать их как однопоточные приложения и просто использовать многопоточность, если это строго необходимо ... но знаете что? В 90% случаев (приложениях реального времени) вы увидите, что однопоточность будет более чем достаточно, поэтому ... KISS

0 голосов
/ 27 июня 2018

pygame.event.get() потребляет события, поэтому вам нужно только одно место, связанное с событиями, и проверьте оба ключа в этом единственном месте:

   for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_q:
                print('HELLO_WORLD')
            if pygame.key.get_mods() & pygame.KMOD_CTRL and event.key == pygame.K_s:
                print('GOOD')
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

Не используйте два цикла в потоках, в любом случае pygame управляется событиями, поэтому вы можете просто использовать один цикл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...