ghulseman
ghulseman

Reputation: 165

Random-generated boolean values in pygame - understanding my code

I had some help making this star generator code that creates random x,y variables and appends the data to a list, then blits each star to the screen. Occasionally each star blinks, based on randomly generated boolean values. Though the code works perfectly, I'm just not understanding how the if not-statements that decide whether a star is on or off work.

I believe the first if-not statement (if not randint(0, 600) makes the stars invisible. The second if-not statement (if not randint(0, 25) makes the star visible again. But I'm not quite grasping this part of the code and why it makes the stars "blink".

Here's the code:

import time
import pygame
from random import randint
pygame.init()

display_width = 1200
display_height = 800

gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("My God, it's full of stars!")

med_star_img = pygame.image.load('images/medium_star.png')
tiny_star_img = pygame.image.load('images/tiny_star.png')

black = (0,0,0)
white = (255,255,255)
gray = (50,50,50)

tiny_stars_width = tiny_star_img.get_width()
tiny_stars_height = tiny_star_img.get_height()

med_stars_width = med_star_img.get_width()
med_stars_height = med_star_img.get_height()

tiny_stars_location = []
med_stars_location = []

clock = pygame.time.Clock()
running = True
gameDisplay.fill(gray)

# create random coordinates for stars
for i in range(30):
        tiny_stars_location.append([randint(1,1200),randint(1,800),tiny_stars_width,tiny_stars_height, True])

for i in range(15):
        med_stars_location.append([randint(1,1200),randint(1,800),med_stars_width,med_stars_height, True])


def make_med_star(x,y):
        gameDisplay.blit(med_star_img, (x,y))
        
def make_tiny_star(x,y):
        gameDisplay.blit(tiny_star_img, (x,y))
        
while running:
        for event in pygame.event.get():
                if event.type == pygame.QUIT:
                        running = False

        
        for star in med_stars_location:
                if star[2]:
                        make_med_star(star[0], star[1])
                if not randint(0, 600):
                        # makes star invisible ?
                        star[2] = False
                        # makes star visible ?
                if not randint(0, 25):
                        star[2] = True
                
##            if not randint(0, 300): # 300 / 60(fps) = 5  -> every 5 seconds on average
##                star[2] = not star[2] # inverse
                
        for star in tiny_stars_location:
                if star[2]:
                        make_tiny_star(star[0], star[1])
                # makes star invisible ?
                if not randint(0, 600):
                        star[2] = False
                # makes star visible ?
                if not randint(0, 5):
                        star[2] = True

                
        pygame.display.flip()
        #time.sleep(1) <- never do this in pygame
        clock.tick(60)
        gameDisplay.fill(gray) # reset display

pygame.quit()

Upvotes: 0

Views: 54

Answers (1)

Oli
Oli

Reputation: 2602

The information that you're missing (and it is admittedly pretty unintuitive) is that integers can be used as boolean values, and all numbers are considered the same as True except for 0, which is considered the same as False. Therefore, not randint(0, 600) can only return True if the random number was 0 - in other words the if not randint(0, 600) is a rather unintuitive way of waying "there is a 1 in 600 chance of the star turning invisible this frame".

Your game runs at 60 frames per second, so 60 times every second, each star makes a random choice whether it should be visible. It might turn off, then stay off for a bit, then turn on again, and so on. This is blinking.

Upvotes: 1

Related Questions