Drawing random stars in background, pygame

Question:

I am working on a platformer game in which I want to add random stars in the background. I have written some code in the function drawBackDrop() which will make some stars at random positions on the screen.

It works fine, but for drawing the stars I have to update it every frame, so the function is called everytime and it makes random stars differently every time.

I want it to appear only once and then not update, so the stars remain at constant positions.

My drawBackDrop() function:

def drawBackdrop():
    if globals.theme == "dark":
        a = random.randint(3, 12)
        x = random.randint(5, globals.screen_width - 12)
        y = random.randint(5, globals.screen_height - 12)
        numberOfStars = random.randint(35, 55)
        starRect = pygame.Rect(x, y, a, a)
        for i in range(numberOfStars):
            pygame.draw.rect(globals.screen, "White", starRect)

    if globals.theme == "light":
        pass #Sun and Clouds

This is the code of scene in which I call the function:

def draw(self, sceneManager, screen):
        if globals.theme == "light":
            screen.fill(globals.light_blue)
        elif globals.theme == "dark":
            screen.fill(globals.black)
        draw.drawBackdrop()
        self.cameraSystem.update(screen)

What I get:

As you can see, the stars are being formed every frame. I want it to form only once and then draw the same stars in screen until I win/lose/leave.

How do I only call the function once? Or is there any other way to draw random stars?

Asked By: Dr.Strange Codes

||

Answers:

There’s two ways you can go here.

  • Paint the stars to a background layer, and blit that every frame
  • Generate the list of random stars once, and store them. Repainting the same Rects every frame. (As @matszwecja suggested in a comment)

But first note that there’s a minor bug in your code. It’s not generating the stars correctly – IFF I understand your intentions correctly. It looks like you wanted to generate a random set of stars, but it was painting the same star over and over.

def drawBackdrop():
    if globals.theme == "dark":
        numberOfStars = random.randint(35, 55)    # <<-- MOVED outside loop
        for i in range(numberOfStars):            # <<-- MOVED Loop
            a = random.randint(3, 12)
            x = random.randint(5, globals.screen_width - 12)
            y = random.randint(5, globals.screen_height - 12)         
            starRect = pygame.Rect(x, y, a, a) 
            pygame.draw.rect(globals.screen, "White", starRect)

Background Surface

def makeBackgroundStars(): 
    """ Generate a transparent background overlay with stars """ 
    background = pygame.Surface( ( globals.screen_width, globals.screen_height ), pygame.SRCALPHA )
    numberOfStars = random.randint(35, 55)
    for i in range(numberOfStars):
        a = random.randint(3, 12)
        x = random.randint(5, globals.screen_width - 12)
        y = random.randint(5, globals.screen_height - 12)
        starRect = pygame.Rect(x, y, a, a)
        pygame.draw.rect( background, "White", starRect )
    return background

The you just need to make the initial image, and then blit it every frame. Probably you’d include all background graphics into this image too.

star_field = makeBackgroundStars()

# in main loop
# ...
globals.screen.blit( star_field, ( 0, 0 ) )

List of Star Rectangles

star_positions = []   # global to hold rects

def genererateStars():
    """ generate a random amount of stars for the background """
    global star_positions
    numberOfStars = random.randint(35, 55)    # <<-- MOVED outside loop
    for i in range(numberOfStars):            # <<-- MOVED Loop
        a = random.randint(3, 12)
        x = random.randint(5, globals.screen_width - 12)
        y = random.randint(5, globals.screen_height - 12)
        star_positions.append( pygame.Rect(x, y, a, a) )   # save it for later

def paintStars( screen ):
    """ Draw the stars to the background """
    global star_positions
    for starRect in star_positions:
        pygame.draw.rect( screen, "White", starRect )
Answered By: Kingsley
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.