Как показать слово на экране в Pygame через ряд функций - PullRequest
0 голосов
/ 07 января 2019

Я думаю, что у меня есть 2 проблемы:

  1. В chooseTheme() ни оператор возврата, ни код нажатой клавиши не работают.

  2. Функция randWord() не останавливается, когда в то время как не сделано main, она продолжает рандомизировать список слов.

Сообщение печатается chooseTheme().

Я запустил строки 22-27 отдельно, и он выводит одно слово, которое я и хочу.

При попытке randWord("Nations") вместо randWord(chooseTheme()) появляется текст, но он перебирает все слова, а не просто выбирает одно.

import random
import pygame


pygame.init()

display_width = 1102
display_height = 625

moccasin = (255, 228, 181)
BLACK = (0, 0, 0)

screen = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption("Hangman")
clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 25)
background = pygame.image.load("world_map.jpg")


def randomWord(theme):
    if theme == "Nations":
        with open("countries_europe.txt") as f:
            word_list = ""
            for word in f:
                word_list = word_list + word
            f.close()
            x = random.choice(word_list.split())
            screen_word = font.render(x, True, BLACK)
            screen.blit(screen_word, [display_width/2, display_height/2])
    elif theme == "Capitals":
        with open("capitals_europe.txt") as f:
            word_list = ""
            for word in f:
                word_list = word_list + word
            f.close()
            x = random.choice(word_list.split())
            screen_word = font.render(x, True, BLACK)
            screen.blit(screen_word, [display_width/2, display_height/2])


def chooseTheme():
    category_text = font.render("Choose a theme:  NATIONS [N] CAPITALS [C]", True, BLACK)
    screen.blit(category_text, (200, display_height/2))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_n:
                return "Nations"
            elif event.key == pygame.K_c:
                return "Capitals"


done = False

while not done:
    screen.blit(background, (0, 0))
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

    randomWord(chooseTheme())

    pygame.display.flip()
    clock.tick(60)

pygame.quit()

При нажатии клавиш N или C вопрос «Выбор темы» должен исчезнуть, и случайное слово должно появиться на экране из одного из файлов .txt.

1 Ответ

0 голосов
/ 07 января 2019

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

Кроме того, после нажатия клавиши вы отображаете случайное слово в функции randomWord, но оно сразу же переписывается в следующем кадре. Вы должны следить за состоянием своей игры (например, в приведенном ниже коде подумайте, что ваша игра находится в состоянии ChooseTheme или в состоянии Word).

Вот как вы можете это сделать, используя спрайты (вам не нужно, но они полезны). Обратите внимание на комментарии в коде.

import random
import pygame
import pygame.freetype

pygame.init()

MOCASSIN = (255, 228, 181)
BLACK = (0, 0, 0)

screen = pygame.display.set_mode((1102, 625))
pygame.display.set_caption("Hangman")
clock = pygame.time.Clock()

# let's use freetype instead of font 
# because freetype is just better in every way
FONT = pygame.freetype.SysFont(None, 25)

# let's use a solid Surface instead of a picture
# so we can run the code without the image
# background = pygame.image.load("world_map.jpg")
background = pygame.Surface(screen.get_rect().size)
background.fill((30, 30, 30))

# we define a dict of the dicts we want to use
# this allows us to easily add new dicts
# also we seperated data from code
THEMES = {
    'Nations': 'countries_europe.txt',
    'Capitals': 'capitals_europe.txt'
}

# let's cache the words so we don't have to read the files over and over again
cached_themes = {}
def get_theme(theme):
    if not theme in cached_themes:
        with open(THEMES[theme]) as f:
            cached_themes[theme] = [data.strip() for data in f.readlines()]
    return cached_themes[theme]


# we use a Sprite so pygame handles the drawing automatically for us
# this sprite handles the theme choosing
class ChooseTheme(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        # we create the message dynamically, so new themes are automatically avaiable
        theme_str = ' '.join(t.upper() + ' [' + t[0].upper() + ']' for t in THEMES)
        self.image =  pygame.Surface(screen.get_rect().size)
        FONT.render_to(self.image, (50, 50), 'Choose a theme: ' + theme_str, MOCASSIN)
        self.rect = self.image.get_rect()

    def update(self, events):
        for event in events:
            if event.type == pygame.QUIT:
                done = True
            elif event.type == pygame.KEYDOWN:
                for theme in THEMES:
                    if theme[0].upper() == event.unicode.upper():
                        # create a new  Word-sprite
                        # self.groups()[0] is the sprites-group created below
                        self.groups()[0].add(Word(theme))
                        # remove this sprite from the game
                        self.kill()

# this sprite handles the displaying of a random word
class Word(pygame.sprite.Sprite):
    def __init__(self, theme):
        super().__init__()
        self.word = random.choice(get_theme(theme))
        self.image = pygame.Surface(screen.get_rect().size)
        FONT.render_to(self.image, (50, 50), self.word, MOCASSIN)
        self.rect = self.image.get_rect()


def main():
    # we use a sprite group to handle updating and drawing
    # since we put all the game logic into the sprites,
    # we probably don't have to touch the main loop again
    sprites = pygame.sprite.Group(ChooseTheme())
    while True:
        # handle events
        events = pygame.event.get()
        for event in events:
            if event.type == pygame.QUIT:
                return

        # update gamestate
        sprites.update(events)

        # draw everything
        screen.blit(background, (0, 0))
        sprites.draw(screen)
        pygame.display.flip()
        clock.tick(60)

if __name__ == '__main__':
    main()
    pygame.quit()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...