Search code examples
pythonpython-3.xpygamepygame-surfacepygame2

Why is Pygame waiting for sprites to load before creating the window?


I've been trying to create a sprite creator, but I notice that the pygame window doesn't load until all of those sprites have been created, and I wanted to know 2 things:

  1. Why it only loads the screen when all of these sprites have been created
  2. How could I fix this without changing too much

code:

#!/usr/bin/env python3
import random
import pygame
import time

display_width = 1280
display_height = 720
rotation = random.randint(0, 359)
size = random.random()
pic = pygame.image.load('assets/meteor.png')
pygame.init()
clock = pygame.time.Clock()
running = True


class Meteor(pygame.sprite.Sprite):
    def __init__(self, x=0, y=0):
        pygame.sprite.Sprite.__init__(self)

        self.rotation = random.randint(0, 359)
        self.size = random.randint(1, 2)
        self.image = pic
        self.image = pygame.transform.rotozoom(self.image, self.rotation, self.size)

        self.rect = self.image.get_rect()
        self.rect.center = (x, y)


all_meteors = pygame.sprite.Group()

# completely random spawn
for i in range(5):
    new_x = random.randrange(0, display_width)
    new_y = random.randrange(0, display_height)
    all_meteors.add(Meteor(new_x, new_y))
    time.sleep(2) # this*5 = time for screen to show up

main:

import pygame
import meteors
pygame.init()
while True:
    meteors.all_meteors.update()
    meteors.all_meteors.draw(screen)
    pygame.display.update()

I do not have a clue on why it prioritizes creating the sprites before creating the pygame window, and it prevents me from creating endless amounts of meteor sprites.


Solution

  • Don't create the meteors before the application loop, create them with a time delay in the loop.

    Use pygame.time.get_ticks() to get the current time in milliseconds and set the start time, before the main loop. Define a time interval after which a new meteorite should appear. When a meteorite spawns, calculate the time when the next meteorite must spawn:

    next_meteor_time = 0
    meteor_interval = 2000 # 2000 milliseconds == 2 sceonds
    
    while ready:
        clock.tick(60)  # FPS, Everything happens per frame
        for event in pygame.event.get():
            # [...]
    
        # [...]
    
        current_time = pygame.time.get_ticks()
        if current_time >= next_meteor_time:
             next_meteor_time += meteor_interval
             new_x = random.randrange(0, display_width)
             new_y = random.randrange(0, display_height)
             all_meteors.add(Meteor(new_x, new_y))
    
        # [...]
    
    
        meteors.all_meteors.update()
        meteors.all_meteors.draw(screen)
        pygame.display.update()