Blinking rectangle white pygame with specific freq

2019-06-13 20:11发布

问题:

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

Thanks for your help community.

回答1:

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


回答2:

I made some edits to your code to fit your needs and tested it.

The Code

import pygame
import sys
import time
from pygame.locals import *

pygame.init()

fenetre = pygame.display.set_mode((500, 400), 0, 32)
black = (0, 0, 0)
white = (255, 255, 255)
clock = pygame.time.Clock()

frequency = 1


def main():

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

        pygame.draw.rect(fenetre, black, (200, 150, 100, 50))
        pygame.display.update()
        time.sleep(frequency)
        pygame.draw.rect(fenetre, white, (200, 150, 100, 50))
        pygame.display.update()
        time.sleep(frequency)
        clock.tick(30)


main()

The result should be the rect appearing each 1 sec