Ryan Heuss
Ryan Heuss

Reputation: 1

Drawing One Image After Another in Pygame

I am writing a program to draw 100 random (in size and color) circles in a pygame window. I want each circle to be drawn one at a time. For some reason, the circles are only drawn at the very end. Does anyone see a reason for this?

import pygame, random, util

pygame.init()

side = 600
win = pygame.display.set_mode((side, side))
win.fill(util.white)
pygame.display.update()

for i in range(100):
    radius = random.randrange(2, 15)
    r = random.randrange(256)
    g = random.randrange(256)
    b = random.randrange(256)
    x = random.randrange(0 + radius, side - radius)
    y = random.randrange(0 + radius, side - radius)

    pygame.draw.circle(win, (r, g, b), (x, y), radius)
    pygame.display.update()
    print(i)


util.wait_for_quit()

Upvotes: 0

Views: 514

Answers (2)

furas
furas

Reputation: 142641

You can use pygame.time.get_ticks() inside while loop to control when to draw element. This way you can draw different elements with different delays and you can still use key to stop it.

import pygame
import random

# --- constants --- (UPPER_CASE_NAMES)

WHITE = (255, 255, 255)
SIDE = 600

# --- main ---

# - init -

pygame.init()

win = pygame.display.set_mode((SIDE, SIDE))

win.fill(WHITE)
pygame.display.update()

# - objects -

circles_number = 100

next_circle = pygame.time.get_ticks() + 500 # 500ms = 0.5s

# - mainloop -

clock = pygame.time.Clock()

running = True

while running:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            running = False

    if circles_number > 0:
        # get current time
        current = pygame.time.get_ticks()

        # check if it is time to draw next circle
        if current >= next_circle:    

            radius = random.randrange(2, 15)
            r = random.randrange(256)
            g = random.randrange(256)
            b = random.randrange(256)
            x = random.randrange(0 + radius, SIDE - radius)
            y = random.randrange(0 + radius, SIDE - radius)

            pygame.draw.circle(win, (r, g, b), (x, y), radius)
            pygame.display.update()

            # time for next circle
            next_circle = pygame.time.get_ticks() + 500 # 500ms = 0.5s

            # counting down circles
            circles_number -= 1                    

    clock.tick(25)

pygame.quit()

If you need to draw all in the same delay then you can use clock.tick(2) to control time between frames. But key also will be checked with the same delay. It can be problem if delay will be too long because key will work with too long delay.

import pygame
import random

# --- constants --- (UPPER_CASE_NAMES)

WHITE = (255, 255, 255)
SIDE = 600

# --- main ---

# - init -

pygame.init()

win = pygame.display.set_mode((SIDE, SIDE))

win.fill(WHITE)
pygame.display.update()

# - objects -

circles_number = 100

# - mainloop -

clock = pygame.time.Clock()

running = True

while running:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            running = False

    if circles_number > 0:

        radius = random.randrange(2, 15)
        r = random.randrange(256)
        g = random.randrange(256)
        b = random.randrange(256)
        x = random.randrange(0 + radius, SIDE - radius)
        y = random.randrange(0 + radius, SIDE - radius)

        pygame.draw.circle(win, (r, g, b), (x, y), radius)
        pygame.display.update()

        # counting down circles
        circles_number -= 1                    

    # 2 frames per seconds = 2 circles per second
    clock.tick(2)

pygame.quit()

You can also use event to execute periodically code which will draw it.

import pygame
import random

# --- constants --- (UPPER_CASE_NAMES)

WHITE = (255, 255, 255)
SIDE = 600

DRAW_CIRCLE_EVENT = pygame.USEREVENT

# --- main ---

# - init -

pygame.init()

win = pygame.display.set_mode((SIDE, SIDE))

win.fill(WHITE)
pygame.display.update()

# - objects -

circles_number = 10

# run event periodically
pygame.time.set_timer(DRAW_CIRCLE_EVENT, 500) # 500ms = 0.5s

# - mainloop -

clock = pygame.time.Clock()

running = True

while running:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            running = False
        if event.type == DRAW_CIRCLE_EVENT:

            if circles_number > 0:

                radius = random.randrange(2, 15)
                r = random.randrange(256)
                g = random.randrange(256)
                b = random.randrange(256)
                x = random.randrange(0 + radius, SIDE - radius)
                y = random.randrange(0 + radius, SIDE - radius)

                pygame.draw.circle(win, (r, g, b), (x, y), radius)
                pygame.display.update()

                # counting down circles
                circles_number -= 1
            else:
                # disable events
                pygame.time.set_timer(DRAW_CIRCLE_EVENT, 0)

    clock.tick(25)

pygame.quit()

Upvotes: 1

Mercury Platinum
Mercury Platinum

Reputation: 1569

You could possibly use time.sleep() to delay the drawing for a bit

for i in range(100):
    radius = random.randrange(2, 15)
    r = random.randrange(256)
    g = random.randrange(256)
    b = random.randrange(256)
    x = random.randrange(0 + radius, side - radius)
    y = random.randrange(0 + radius, side - radius)

    pygame.draw.circle(win, (r, g, b), (x, y), radius)
    pygame.display.update()
    print(i)
    time.sleep(0.001)

Also import module, moduleb is not very nice, you could change it to

import module
import moduleb

EDIT: Here is some updated code that does not need whatever "Util" is, and fits more with pygame

import pygame
import random
import time

pygame.init()

side = 600
win = pygame.display.set_mode((side, side))
win.fill((255, 255, 255))
loop = True
on_start = True
while loop:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            loop = False
    if on_start:
        for i in range(100):
            radius = random.randrange(2, 15)
            r = random.randrange(256)
            g = random.randrange(256)
            b = random.randrange(256)
            x = random.randrange(0 + radius, side - radius)
            y = random.randrange(0 + radius, side - radius)

            pygame.draw.circle(win, (r, g, b), (x, y), radius)
            pygame.display.update()
            time.sleep(0.01)
            print(i)
        on_start = False

pygame.quit()

Upvotes: 0

Related Questions