Search code examples
pythonpygamerectangles

Blinking rectangle white pygame with specific frequency


I'm student at university and I have a specific question.

Presently I display a white rectangle in center of a window with pygame above a black background. But presently I would like to blinking my white rectangle at a specific frequency, and it's why a I need help.

Presently I implement that:

import pygame, sys
from pygame.locals import *

def main():
    pygame.init()

    fenetre = pygame.display.set_mode((500,400),0,32)

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

    fenetre.fill(black)

    pygame.draw.rect(fenetre, white,(200,150,100,50))


    while True:
        for event in pygame.event.get():
            if event.type==QUIT:
                pygame.quit()
                sys.exit()
        pygame.display.update()

main()

enter image description here

Thanks for your help community.


Solution

  • Very popular method to control elements is using time.

    You set time of next change state and then you compare this with current time. This way you control object and you don't stop while True loop so it cando other things.

    import pygame
    import sys
    
    # --- constants ---
    
    BLACK = (  0,   0,   0)
    WHITE = (255, 255, 255)
    
    # --- main ---
    
    def main():
        pygame.init()
    
        fenetre = pygame.display.set_mode((500, 400), 0, 32)
    
        # time in millisecond from start program 
        current_time = pygame.time.get_ticks()
    
        # how long to show or hide
        delay = 500 # 500ms = 0.5s
    
        # time of next change 
        change_time = current_time + delay
        show = True
    
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
    
            # --- updates ---
    
            current_time = pygame.time.get_ticks()
    
            # is time to change ?
            if current_time >= change_time:
                # time of next change 
                change_time = current_time + delay
                show = not show
    
            # --- draws ---
    
            fenetre.fill(BLACK)
    
            if show:
                pygame.draw.rect(fenetre, WHITE,(200,150,100,50))
    
            pygame.display.update()
    
    main()
    

    EDIT: the same with more elements

    import pygame
    import sys
    
    # --- constants ---
    
    BLACK = (  0,   0,   0)
    WHITE = (255, 255, 255)
    RED   = (255,   0,   0)
    GREEN = (  0, 255,   0)
    
    # --- main ---
    
    def main():
        pygame.init()
    
        fenetre = pygame.display.set_mode((500, 400), 0, 32)
    
        current_time = pygame.time.get_ticks()
    
        # time of show or hide
        delay = 500 # 500ms = 0.5s
    
        # time of next change (WHITE)
        change_time = current_time + delay
        show = True
    
        # time of next change (RED)
        red_change_time = current_time + delay + 150
        red_show = False
    
        # time of next change (GREEN)
        green_change_time = current_time + delay + 300
        green_show = False
    
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
    
            # --- updates ---
    
            current_time = pygame.time.get_ticks()
    
            # is time to change ? (WHITE)
            if current_time >= change_time:
                change_time = current_time + delay
                show = not show
    
            # is time to change ? (RED)
            if current_time >= red_change_time:
                red_change_time = current_time + delay
                red_show = not red_show
    
            # is time to change ? (GREEN)
            if current_time >= green_change_time:
                green_change_time = current_time + delay
                green_show = not red_show
    
            # --- draws ---
    
            fenetre.fill(BLACK)
    
            if show: # (WHITE)
                pygame.draw.rect(fenetre, WHITE, (200,150,100,50))
    
            if red_show: # (RED)
                pygame.draw.rect(fenetre, RED, (100,150,100,50))
    
            if green_show: # (GREEN)
                pygame.draw.rect(fenetre, GREEN, (300,150,100,50))
    
            pygame.display.update()
    
    main()
    

    EDIT: version using class. But this time with different frequencies

    import pygame
    import sys
    
    # --- constants ---
    
    BLACK = (  0,   0,   0)
    WHITE = (255, 255, 255)
    RED   = (255,   0,   0)
    GREEN = (  0, 255,   0)
    
    # --- classes ---
    
    class Rectangle():
    
        def __init__(self, color, rect, time, delay):
            self.color = color
            self.rect = rect
            self.time = time
            self.delay = delay
            self.show = False
    
        def draw(self, screen):
            if self.show:
                pygame.draw.rect(screen, self.color, self.rect)
    
        def update(self, current_time):
            if current_time >= self.time:
                 self.time = current_time + self.delay
                 self.show = not self.show
    
    # --- main ---
    
    def main():
        pygame.init()
    
        fenetre = pygame.display.set_mode((500, 400), 0, 32)
    
        current_time = pygame.time.get_ticks()
    
        # time of show or hide
        delay = 500 # 5000ms = 0.5s
    
        # objects    
        rect_white = Rectangle(WHITE, (200,150,100,50), current_time, 500)
        rect_red = Rectangle(RED, (100,150,100,50), current_time + 150, 100)
        rect_green = Rectangle(GREEN, (0, 0, 500, 400), current_time + 300, 2000)
    
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
    
            # --- updates ---
    
            current_time = pygame.time.get_ticks()
    
            rect_white.update(current_time)
            rect_red.update(current_time)
            rect_green.update(current_time)
    
            # --- draws ---
    
            fenetre.fill(BLACK)
    
            rect_green.draw(fenetre)
            rect_white.draw(fenetre)
            rect_red.draw(fenetre)
    
            pygame.display.update()
    
    main()