Лучший способ показать несколько изображений в быстрой последовательности - PullRequest
1 голос
/ 14 июля 2020

Я пытаюсь использовать pygame для быстрой смены sh нескольких изображений, но в приведенном ниже коде в течение некоторого времени отображается белый экран, а затем отображается одно изображение на долю секунды, а затем закрывается.

Где я ошибаюсь?

import glob
import pygame
import os
import pathlib
import time

max_idx = 276
imgs_dir = 'path/to/imgs/...'

pygame.init()
w = 480
h = 480
size=(w,h)
screen = pygame.display.set_mode(size) 
c = pygame.time.Clock()

idx = 0
while idx < max_idx:
    idx+=1
    print(idx)

    screen.fill((255,255,255))

    img_path = f'{imgs_dir}/{idx}.png'
    img = pygame.image.load(img_path)
    img_rect = img.get_rect()
    
    screen.blit(img, img_rect)
    pygame.display.update()
    
    c.tick(1000)

В моем случае имена файлов - это индексы, и они существуют. (например, 'path/to/imgs/0.png', ..., 'path/to/imgs/275.png')

Обновленная попытка

С отзывами я обновил его до этого, но он не был t решил проблему:

pygame.init()
w = 300
h = 300
size=(w,h)
screen = pygame.display.set_mode(size) 
c = pygame.time.Clock()

images = []
for idx in range(0, max_idx):
    img_path = f'{new_folder_path}/{idx}.png'
    img = pygame.image.load(img_path)
    img = pygame.transform.scale(img, size)
    images.append(img)

for img in images:  # I want it to close as soon as all images have been shown
    img_rect = img.get_rect()
    screen.blit(img, img_rect)
    pygame.display.update()
    c.tick(0.5)

pygame.quit()

1 Ответ

1 голос
/ 14 июля 2020

Попробуйте загрузить изображения за пределами main_loop, так как загрузка занимает некоторое время. Также программа выйдет, когда idx станет True, и это в вашем случае после 276 итераций, теперь ваша частота кадров установлена ​​на 1000, уменьшите количество кадров. Если вы хотите предотвратить выход программы, удалите idx из условия while и поместите другую переменную, которая станет True, когда вы закроете окно (и при необходимости добавите некоторые другие триггеры), например:

run = True
...
for event in pygame.event.get():
    if event.type == pygame.QUIT:
        run = False

Также поставьте pygame.quit() в конце.

РЕДАКТИРОВАТЬ: Код решения

import pygame as pg
import os 

WIN_W = 500
WIN_H = 500
FPS = 2

clock = pg.time.Clock()

window = pg.display.set_mode((WIN_W, WIN_H))

images_list = []

def load_images(images_list):
    curr_dir = os.path.dirname(__file__)
    dir_images = os.path.join(curr_dir, "images")

    for i in range(2, 11, 2):   
        images_list.append(pg.image.load(os.path.join(dir_images, f"{i}c.png")))


load_images(images_list)


def redraw(i):

    window.blit(images_list[i], (0,0))

    pg.display.update()


run = True
while run:

    clock.tick(1)

    for event in pg.event.get():
        if event.type == pg.QUIT:
            run = False

    for i in range(len(images_list)):
        pg.time.wait(100)
        redraw(i)

pg.quit()

Я получил желаемый результат с pygame.time.wait(). Я не уверен на 100%, но я думаю, что проблема с нашими предыдущими попытками заключалась в том, что независимо от FPS, весь код в for loop запускается сразу, поэтому мы видим только последнее изображение. При использовании этого подхода за каждый проход происходит только ОДИН блиттинг. Я знаю, что вы хотите, чтобы ваша программа завершилась после завершения отображения, но это легче проверить.

ПРИМЕЧАНИЕ: не забудьте изменить пути к изображениям и имена переменных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...