Вычисления Pygame неверны для манипулирования pygame.time.get_ticks() в таймер

#python #function #time #while-loop #pygame

Вопрос:

В настоящее время я использую pygame для АККУРАТНОГО моделирования самоуправляемого автомобиля. Приведенный ниже код находится в цикле while внутри run() функции. Каждый раз, когда заканчивается каждое поколение, цикл while также прерывается, но перезапускается снова. Каждое поколение заканчивается через 120 секунд, поэтому я сделал таймер ниже, чтобы посмотреть, сколько прошло времени, и он работает правильно для первого поколения, но для каждого поколения после этого вывод искажается. т. Е. поколение 2 начинается с 80, заканчивается 120, но секунды дольше, чем обычно, и т. Д…

Правка: Окно не замерзает, все работает, в том числе pygame.time.get_ticks() , но когда я пытаюсь использовать его для отображения времени и манипулирую им с помощью вычислений для сброса до 0 каждые 120 секунд, вычисления неверны, потому что время просто искажается. Кроме того, я проверил сообщение, на которое меня направили, когда мой предыдущий вопрос был закрыт, это не решило мою проблему.

Код:

 import pygame

generation = 0
screen_width = 1500
screen_height = 800
generations = [1, 2, 3]

def run():
    pygame.init()
    screen = pygame.display.set_mode((screen_width, screen_height))
    clock = pygame.time.Clock()
    tick = 60
    global generation
    generation  =1
    font = pygame.font.SysFont('Aharoni', 20)
    while 1:
        pygame.event.pump()

        for event in pygame.event.get():  # Loop to check if anything that can be pressed was pressed:
            if event.type == pygame.QUIT:  # If the quit button was pressed:
                sys.exit(0)  # Exit the program.

        if pygame.time.get_ticks() >= 120000 * generation:  # if the ticks that passed is greater than 120k (120.s)*gen:
            break  # Exit the while loop and end the generation.

           # Draw a transparent box for stats to be written on.
        stat_box = pygame.Surface((200, 200))  # Create a surface with (200, 200) resolution.
        stat_box.set_alpha(50)  # Make the surface '50' transparent.
        stat_box.fill((255, 255, 255))  # Set the color of the surface to (255, 255, 255) / black.
        screen.blit(stat_box, (screen_width / 150, screen_height / 1.355932))  # Render box to the screen.


        gen_time = pygame.time.get_ticks()  # Set the variable to be the same amount of ticks, divide it by 1k to get
        gen_time = gen_time / 1000          # seconds, and divide it by the generation amount to create a timer.
        gen_time = gen_time / generation
        gen_time = str(gen_time)  # Convert the variable to a string from being a number.

        text = font.render("Generation clock: "   gen_time[0:3]   "s", True, (0, 0, 0))  # Text to be drawn, and color.
        text_rect = text.get_rect()  # Grab the rectangle borders for the text.
        text_rect.center = (110, 620)  # Coordinates for text to be drawn at.
        screen.blit(text, text_rect)  # Render 'text' to the screen at the position of 'text_rect'.

        pygame.display.flip()  # Refresh the entire screen (graphically).
        clock.tick_busy_loop(tick)  # Tick the clock by 'ticks' amount.

for i in generations:
    run()
 

Комментарии:

1. Извините, я не вызываю pygame.event.pump(), я попытаюсь добавить еще немного кода, чтобы сделать его воспроизводимым, мне просто нужно несколько минут.

2. Извините, я прошу вас извинить, но я пытался позвонить по этому номеру и удалил его, потому что это не решило мою проблему(не повлияло на программу ни хорошо, ни плохо), я не совсем уверен, но я не думаю, что время имеет какое-либо отношение к событиям? Поправьте меня, если я ошибаюсь, но я обновил код, так что теперь моя проблема воспроизводима. Извините, если я был груб, и еще раз спасибо! (Я включил строку, которую вы сказали включить, чтобы показать, что это не исправляет проблему. редактировать: моя программа также никогда раньше не блокировалась, и я запускал ее в течение нескольких дней, поэтому я удалил строку, так как думаю, что в моем случае это может быть бесполезно)

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

Ответ №1:

Видеть pygame.time.get_ticks() :

[…] Возвращает количество миллисекунд с момента pygame.init() вызова

Видеть pygame.init() :

[…] Безопасно звонить по этому init() номеру несколько раз, так как повторные звонки не будут иметь никакого эффекта.

Поэтому вам нужно позвонить pygame.qiut() в конце поколения.

 def run():
    pygame.init()

    # [...]

    while 1:
        # [...]

    pygame.quit() # <---
 

Кроме того, вы можете получить время начала до цикла и рассчитать разницу во времени в цикле:

 def run():
    pygame.init()

    # [...]

    start_time = pygame.time.get_ticks()
    while 1:
        # [...]

        elapsed_time = pygame.time.get_ticks() - start_time
        if elapsed_time >= 120000 * generation:
            break 
 

Комментарии:

1. Спасибо! Это работает правильно (хотя я помещаю оператор quit в конце функции run), но он также закрывается в конце каждого поколения, что не идеально, поэтому мне было интересно, можно ли сбросить pygame.time.get_ticks (), если нет, то в любом случае спасибо, я наконец-то смогу избавиться от ошибок в своей программе!

2. @EshanT201 Нет, невозможно «сбросить» pygame.time.get_ticks() , как четко указано в документах. Однако вы можете найти альтернативное решение во втором абзаце моего ответа.

3. Большое вам спасибо, я предпочитаю второе, хорошего дня!