不同功能的不同页面

Different page from different functions

我正在尝试让 pygame 根据随机确定的调用函数显示不同的页面。理想情况下,当按下正确的按钮时,它会自动移动到下一页。当 运行 这个时候, pygame window 就停止响应了。任何见解将不胜感激。

运行 Python 3x 和 pygame 1.9.5

import pygame
from pygame.locals import *
import random
import keyboard

pygame.init()

display_width = 500
display_height = 500

black = (0,0,0)
white = (255,255,255)

gd = pygame.display.set_mode((display_width,display_height))

myfont = pygame.font.SysFont("Arial", 30)

def rw():
    gd.fill(white)
    letter = myfont.render("Press r and w",0,(black))
    gd.blit(letter,(100,100))
    pygame.display.flip()
    while True:
        try: 
            if keyboard.is_pressed('r+w'): 
                break
            else:
                pass
        except:
            break

def yk():
    gd.fill(white)
    letter = myfont.render("Press y and k",0,(black))
    gd.blit(letter,(100,100))
    pygame.display.flip()
    while True:
        try: 
            if keyboard.is_pressed('y+k'): 
                break
            else:
                pass
        except:
            break

def ctsh():
    gd.fill(white)
    letter = myfont.render("Press CTRL and Shift",0,(black))
    gd.blit(letter,(100,100))
    pygame.display.flip()
    while True:
        try: 
            if keyboard.is_pressed('ctrl+shift'): 
                break
            else:
                pass
        except:
            break

my_sample = random.sample(range(3), 3)

for i in my_sample:
    if my_sample[i] == 0:
        rw()

    if my_sample[i] == 1:
        yk()

    if my_sample[i] == 2:
        ctsh()

while True:
for event in pygame.event.get():
    if event.type == QUIT:
        pygame.quit()
        quit()

pygame.display.update()

正如我在评论中提到的,问题的主要部分是您尝试将称为 keyboard 模块的东西与 pygame 一起使用,这通常需要您使用它自己的事件处理模型获取用户的输入。

通常情况下这不会是什么大问题,但在这种情况下,由于三件事而变得有点困难:

  1. 在您当前的程序中,每个页面函数都有自己的键盘处理。
  2. 页面功能重复代码过多
  3. 您要检测的某些键实际上对应于标准键盘上的两个不同物理键,即 ShiftCtrl 键.

以下显示了解决这些问题的一些方法。它通过所谓的 OOP (object oriented programming) 减少了代码重复——在本例中是通过定义一个通用的 Page class 来表示您想要显示的每个页面包含处理它们所需的通用代码的方法。

它通过将双键映射与常规键分开来处理双键映射,以便可以检测到它们对应的两个物理键。 (如果您限制自己指定确切的键,例如左 Shift 键 (K_LSHIFT) 或右 Ctrl 键 (K_RCTRL),而不是 KMOD_SHIFTKMOD_CTRL,后者可用于指定任何一对——显示所有键名称常量的列表 here in the pygame documentation.) 换句话说,代码可以指定 KMOD_CTRL 来表示 其中一个 ,而传递 K_LCTRLK_RCTRL 会意思是需要同时按下两个

为了支持当前显示的事件处理 Page,主事件处理循环通过调用当前页面的 keys_pressed() 方法来检查是否按下了所需的键,以确定是否需要的键都被同时按下。

import pygame
from pygame.locals import *
import random

DISPLAY_WIDTH, DISPLAY_HEIGHT = 500, 500
BLACK = 0, 0, 0
WHITE = 255, 255, 255
# Modifier keys which which correspomd to two different keys on keyboards.
DUAL_MODIFIERS = {KMOD_SHIFT, KMOD_CTRL, KMOD_ALT, KMOD_META}

class Page:
    def __init__(self, title, background, message, text_color, *keys):
        """ Save everything needed to show page and detect its keys. """
        self.title = title
        self.background = background
        self.message = message
        self.text_color = text_color

        # Create two lists and put each key into one or the other
        # depending on whether it's a "dual modifier".
        lists = (self.keys, self.dual_mods) = [], []
        for key in keys:
            lists[key in DUAL_MODIFIERS].append(key)

    def keys_pressed(self):
        """ Check whether all keys are all being pressed simultaneously. """
        pressed, mods = pygame.key.get_pressed(), pygame.key.get_mods()
        return (all(pressed[key] for key in self.keys) and
                all((mods & dual_mod) for dual_mod in self.dual_mods))

    def show(self, surface, font):
        pygame.display.set_caption(self.title)
        surface.fill(self.background)
        img = font.render(self.message, True, self.text_color)
        surface.blit(img, (100, 100))
        pygame.display.flip()


def main():
    pygame.init()

    screen = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
    msg_font = pygame.font.SysFont("Arial", 30)

    # Create a list of Page instances.
    pages = [Page("RW Page", WHITE, "Press r and w", BLACK, K_r, K_w),
             Page("YK Page", WHITE, "Press y and k", BLACK, K_y, K_k),
             Page("CTSH Page", WHITE, "Press Ctrl and Shift", BLACK, KMOD_CTRL,
                  KMOD_SHIFT)]
    current_page = random.choice(pages)  # Start with random initial page.
    current_page.show(screen, msg_font)

    while True:  # Process events until terminated.
        event = pygame.event.poll()
        if event.type == QUIT:
            break
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:  # Keypress to quit?
                break
            elif current_page.keys_pressed():
                # Select a different page to display.
                new_page = current_page
                while new_page == current_page:
                    new_page = random.choice(pages)
                current_page = new_page
                current_page.show(screen, msg_font)

    pygame.quit()

# Run application.
main()

结束评论:

我不确切知道您的应用程序的用途,但认为您应该认真地重新考虑其人机界面的设计——需要同时按下多个键有点尴尬,并且为每个页面分配不同的键组合使得由于缺乏一致性,它们很难被记住(而且这是不必要的,尤其是因为它总是做同样的事情,只是切换到不同的随机页面)。