【问题标题】:Drawing One Image After Another in Pygame在 Pygame 中绘制一个又一个图像
【发布时间】:2017-12-24 20:59:20
【问题描述】:

我正在编写一个程序来在 pygame 窗口中绘制 100 个随机(大小和颜色)圆圈。我希望每个圆圈一次绘制一个。出于某种原因,圆圈仅在最后绘制。有没有人看到这样做的原因?

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

【问题讨论】:

  • 什么是`util.wait_for_quit()`?更好地使用标准 while 循环和 for event 循环。

标签: python pygame draw


【解决方案1】:

您可以在while 循环中使用pygame.time.get_ticks() 来控制何时绘制元素。这样你可以用不同的延迟绘制不同的元素,你仍然可以使用 key 来停止它。

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

如果您需要在相同的延迟中绘制所有内容,那么您可以使用clock.tick(2) 来控制帧之间的时间。但是密钥也将以相同的延迟进行检查。如果延迟太长可能会出现问题,因为密钥的延迟太长。

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

您还可以使用事件定期执行代码来绘制它。

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

【讨论】:

    【解决方案2】:

    您可以使用time.sleep() 来延迟绘图时间

    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)
    

    还有import module, moduleb不是很好,你可以改成

    import module
    import moduleb
    

    编辑:这是一些不需要任何“Util”的更新代码,并且更适合 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()
    

    【讨论】:

    • 好吧,如果您打算使用控件/事件,否则使用这样的代码就可以了。
    • 但它无法获取事件 QUITKEYDOWN - 特别是如果您必须绘制更长的延迟。如果您没有收到事件,某些系统可能会终止程序。
    • 其他方法见我的回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    • 2021-12-19
    • 2012-06-15
    • 1970-01-01
    相关资源
    最近更新 更多