EshanT201
EshanT201

Reputation: 39

Pygame calculations not correct for manipulating pygame.time.get_ticks() into a timer

I am currently using pygame for a NEAT self-driving car simulation. The code below is in a while loop, inside a run() function. Every time each generation ends, the while loop also is broken but restarted again. Each generation ends at 120 seconds, so I made the timer below to view how much time passed, and it works correctly for the first generation, but for each generation, after that, the output is messed up. i.e. gen 2 starts at 80, ends at 120, but the seconds are longer than usual, etc...

Edit: The window isn't freezing, everything works, including pygame.time.get_ticks(), but when I try to use it to display the time and manipulate it using calculations to reset to 0 every 120 seconds, the calculations aren't correct because the time just gets distorted. Also, I checked out the post I was directed to when my previous question was closed, that didn't fix my problem.

Code:

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()

Upvotes: 1

Views: 173

Answers (1)

Rabbid76
Rabbid76

Reputation: 210998

See pygame.time.get_ticks():

[...] Return the number of milliseconds since pygame.init() was called

See pygame.init():

[...] It is safe to call this init() more than once as repeated calls will have no effect.

Therefore you need to call pygame.qiut() at the end of a generation.

def run():
    pygame.init()

    # [...]

    while 1:
        # [...]

    pygame.quit() # <---

Alternatively, you can get the start time before the loop and calculate the time difference in the loop:

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 

Upvotes: 1

Related Questions