简体   繁体   中英

User keyboard input in pygame, how to get CAPS input

I'm in the process of making my first game and want prompt the user to enter information, eg their name. I've spent the last 3.5 hours writing the function below which I intend to use(slightly modified with a blinking underscore cursor to name one) in my games moving forward.

As my code is currently written I cannot get CAPS input from the user, even though I have allowed for such characters. How might I do this?

Any other suggestions also welcome.

Code:

import pygame
from pygame.locals import *
import sys

def enter_text(max_length, lower = False, upper = False, title = False):
    """
    returns user name input of max length "max length and with optional
    string operation performed
    """
    BLUE = (0,0,255)
    pressed = ""
    finished = False
    # create list of allowed characters by converting ascii values
    # numbers 1-9, letters a-z(lower/upper)
    allowed_chars = [chr(i) for i in range(97, 123)] +\
                    [chr(i) for i in range(48,58)] +\
                    [chr(i) for i in range(65,90)]


    while not finished:
        screen.fill((0,0,0))
        pygame.draw.rect(screen, BLUE, (125,175,150,50))
        print_text(font, 125, 150, "Enter Name:")

        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            # if input is in list of allowed characters, add to variable
            elif event.type == KEYUP and pygame.key.name(event.key) in \
               allowed_chars and len(pressed) < max_length:
                pressed += pygame.key.name(event.key)
            # otherwise, only the following are valid inputs
            elif event.type == KEYUP:
                if event.key == K_BACKSPACE:
                    pressed = pressed[:-1]
                elif event.key == K_SPACE:
                    pressed += " "
                elif event.key == K_RETURN:
                    finished = True


        print_text(font, 130, 180, pressed)
        pygame.display.update()

    # perform any selected string operations
    if lower: pressed = pressed.lower()
    if upper: pressed = pressed.upper()
    if title: pressed = pressed.title()
    return pressed


def print_text(font, x, y, text, color = (255,255,255)):
    """Draws a text image to display surface"""
    text_image = font.render(text, True, color)
    screen.blit(text_image, (x,y))

pygame.init()
screen = pygame.display.set_mode((400,400))
font = pygame.font.SysFont(None, 25)
fpsclock = pygame.time.Clock()
fps = 30

BLUE = (0,0,255)



# name entered?
name = False

while True:
    fpsclock.tick(fps)
    pressed = None
    for event in pygame.event.get():
        if event.type == KEYUP:
            print(pygame.key.name(event.key))
            print(ord(pygame.key.name(event.key)))
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    # key polling
    keys = pygame.key.get_pressed()

    screen.fill((0,0,0))

    if not name:
        name = enter_text(4, title = True)

    print_text(font, 130, 180, name)
    pygame.display.update()

Below is the re-worked code with upper case input catered for. I've also put in a blinking underscore. Unsure if it's the most efficient way to do so, but there it is. I had fun doing it.

import pygame
from pygame.locals import *
import sys
from itertools import cycle

def enter_text(max_length, lower = False, upper = False, title = False):
    """
    returns user name input of max length "max length and with optional
    string operation performed
    """
    BLUE = (0,0,255)
    pressed = ""
    finished = False
    # create list of allowed characters using ascii values
    # numbers 1-9, letters a-z
    allowed_values = [i for i in range(97, 123)] +\
                     [i for i in range(48,58)]

    # create blinking underscore
    BLINK_EVENT = pygame.USEREVENT + 0
    pygame.time.set_timer(BLINK_EVENT, 800)
    blinky = cycle(["_", " "])
    next_blink = next(blinky)

    while not finished:
        screen.fill((0,0,0))
        pygame.draw.rect(screen, BLUE, (125,175,150,50))
        print_text(font, 125, 150, "Enter Name:")

        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == BLINK_EVENT:
                next_blink = next(blinky)
            # if input is in list of allowed characters, add to variable
            elif event.type == KEYUP and event.key in allowed_values \
                 and len(pressed) < max_length:
                # caps entry?
                if pygame.key.get_mods() & KMOD_SHIFT or pygame.key.get_mods()\
                   & KMOD_CAPS:
                    pressed += chr(event.key).upper()
                # lowercase entry
                else:
                    pressed += chr(event.key)
            # otherwise, only the following are valid inputs
            elif event.type == KEYUP:
                if event.key == K_BACKSPACE:
                    pressed = pressed[:-1]
                elif event.key == K_SPACE:
                    pressed += " "
                elif event.key == K_RETURN:
                    finished = True
        # only draw underscore if input is not at max character length
        if len(pressed) < max_length:
            print_text(font, 130, 180, pressed + next_blink)
        else:
            print_text(font, 130, 180, pressed)
        pygame.display.update()

    # perform any selected string operations
    if lower: pressed = pressed.lower()
    if upper: pressed = pressed.upper()
    if title: pressed = pressed.title()

    return pressed


def print_text(font, x, y, text, color = (255,255,255)):
    """Draws a text image to display surface"""
    text_image = font.render(text, True, color)
    screen.blit(text_image, (x,y))

pygame.init()
screen = pygame.display.set_mode((400,400))
font = pygame.font.SysFont(None, 25)
fpsclock = pygame.time.Clock()
fps = 30
BLUE = (0,0,255)
# name entered?
name = False

while True:
    fpsclock.tick(fps)
    pressed = None
    for event in pygame.event.get():
        if event.type == KEYUP:
            print(pygame.key.name(event.key))
            print(ord(pygame.key.name(event.key)))
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    # key polling
    keys = pygame.key.get_pressed()
    screen.fill((0,0,0))

    if not name:
        name = enter_text(10)

    print_text(font, 130, 180, name)
    pygame.display.update()

Try this code:

while True:
for event in pygame.event.get():
    if event.type == QUIT:
        exit()
    if event.type == KEYDOWN:
        if event.key == K_BACKSPACE:
            word = word[:-1]
        elif event.unicode != " ":
            word += event.unicode

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM