pygame time.sleep имеет приоритет над остальной частью функции - PullRequest
0 голосов
/ 12 ноября 2018

Я пытаюсь создать приложение для викторины, в котором вы нажимаете одну из двух кнопок. Это пример MVC. Основная проблема связана с «правильной» функцией. Я намеревался задать для него значение false (что не решило проблему), заполнить игровой дисплей, затем распечатать сообщение на экране и обновить дисплей, чтобы он подождал 3 секунды, прежде чем делать что-либо еще. Но вместо этого он ждет 3 секунды, мигает намеченный экран для одного тика, а затем мгновенно возвращается к функции вопроса. Разве Python не должен читать функцию построчно сверху вниз? Потому что сейчас он отдает приоритет time.sleep над остальными инструкциями в функции

import time
clock = pygame.time.Clock()
display_width = 800
display_height = 600
gameDisplay = pygame.display.set_mode((display_width, display_height))

def question():
    global question
    question = True
    while question:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        gameDisplay.fill(cyan)
        button('text', 150, 500, 100, 50, darkYellow, yellow, action = 'correct')
        pygame.display.update()
        clock.tick(100)


def button(text, x, y, width, height, inactive_color, active_color, action = None):
    cur = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    if x + width > cur[0] > x and y + height > cur[1] > y:
        pygame.draw.rect(gameDisplay, active_color, (x, y, width, height))
        pygame.display.update()
        if click[0] == 1 and action != None:
            if action == 'correct':
                question = False
                correct()
    pygame.draw.rect(gameDisplay, inactive_color, (x, y, width, height))
    pygame.display.update()

def correct():
    question = False
    gameDisplay.fill(cyan)
    message_to_screen('Both of these licenses allow for distribution of software', black)
    pygame.display.update()
    time.sleep(3)

question()

1 Ответ

0 голосов
/ 12 ноября 2018

Потому что сейчас он отдает приоритет времени. Спит над остальными инструкциями в функции

Я не знаю точно, что вы ожидаете от того, что делает time.sleep. Это просто остановит вашу игру, и за это время в основном ничего не происходит. «Ничего не происходит» включает рисование и обработку событий. Ничто не является «приоритетным».

Запомните эти простые правила:

  • Всякий раз, когда вы используете time.sleep в игре, это, вероятно, неправильно
  • Всякий раз, когда вы звоните pygame.display.update несколько раз, это, вероятно, неправильно

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

Вот простой, работоспособный и общий пример:

import time
import pygame
import pygame.freetype
pygame.init()
clock = pygame.time.Clock()
display_width = 800
display_height = 600
gameDisplay = pygame.display.set_mode((display_width, display_height))
font = pygame.freetype.SysFont(None, 20)

def question():
    global question
    question = True
    state = None
    while question:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        gameDisplay.fill(pygame.Color('cyan'))
        result = button('text', 150, 500, 100, 50, pygame.Color('grey'), pygame.Color('yellow'), action = correct)
        if result: state = result
        if state: question = state()
        pygame.display.update()
        clock.tick(100)


def button(text, x, y, width, height, inactive_color, active_color, action = None):
    cur = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    if x + width > cur[0] > x and y + height > cur[1] > y:
        pygame.draw.rect(gameDisplay, active_color, (x, y, width, height))
        if click[0] == 1 and action != None:
            return action()
        return None
    pygame.draw.rect(gameDisplay, inactive_color, (x, y, width, height))

def message_to_screen(text, color):
    font.render_to(gameDisplay, (100, 100), text, color)

def correct():
    start = pygame.time.get_ticks()
    def func():
        cur = pygame.time.get_ticks()
        message_to_screen('Both of these licenses allow for distribution of software', pygame.Color('black'))
        return cur - start < 3000

    return func

question()

Мы передаем функции button другую функцию (в данном случае correct), которая будет вызываться, если игрок нажимает кнопку.

Результат этого, который, в свою очередь, также является функцией, затем сохраняется в переменной state и должен возвращать True для продолжения игры или False для завершения игры. Это делается путем установки question на результат вызова этой функции.

Конечно, есть бесконечные пути к чему-то подобному, но этот подход с двойной функцией имеет преимущество, заключающееся в том, что функция button имеет общий характер и инкапсулирует состояние («как долго мы будем отображать сообщение») в correct функция. Вы поймете идею.

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