如何在pygame中将子画面制作为gif?

问题描述

因此,对于在控制直升机的同时躲避投射物的游戏,我有这个想法。我想知道您是否可以让精灵显示为gif或其他类似图像,每两秒切换一次。我知道如何使子画面显示为一张图像:

self.surf = pygame.image.load("example.png").convert()

但是我想知道这是否有效:

self.surf = pygame.image.load("example.gif").convert()

不幸的是,它仅显示gif中的第一张图像。 这是gif:

Helicopter.gif

编辑:好的,所以我查看了答案并尝试在我的代码中实现它们,但是这太令人困惑了,我试图做一些更简单的事情。这是我想出的:

    if play == 1:
        self.surf = pygame.image.load("Image2.png").convert()
        pygame.display.update()
        play = 2
        time.sleep(.2)
    if play == 2:
        self.surf = pygame.image.load("Image1.png").convert()
        pygame.display.update()
        play = 1
        time.sleep(.2)

但是,所有要做的只是将播放器精灵显示为图像1。我可以添加些什么来使这项工作有效?

解决方法

PyGame模块和pygame.image模块只能处理非动画的GIFs
但是在PyGame主页上引入了GIFImage库:

该库将GIF动画回放添加到pygame。


另一种选择是使用Pillow库(pip install Pillow)。

编写一个函数,该函数可以将PIL图像转换为pygame.Surface
(另请参见PIL and pygame.image

def pilImageToSurface(pilImage):
    mode,size,data = pilImage.mode,pilImage.size,pilImage.tobytes()
    return pygame.image.fromstring(data,mode).convert_alpha()

使用PIL库逐帧加载GIF:
(另请参见Extracting The Frames Of An Animated GIF Using Pillow

def loadGIF(filename):
    pilImage = Image.open(filename)
    frames = []
    if pilImage.format == 'GIF' and pilImage.is_animated:
        for frame in ImageSequence.Iterator(pilImage):
            pygameImage = pilImageToSurface(frame.convert('RGBA'))
            frames.append(pygameImage)
    else:
        frames.append(pilImageToSurface(pilImage))
    return frames

请参见简单的gif动画查看器示例:

import pygame
from PIL import Image

def pilImageToSurface(pilImage):
    mode,mode).convert_alpha()

def loadGIF(filename):
    pilImage = Image.open(filename)
    frames = []
    if pilImage.format == 'GIF' and pilImage.is_animated:
        for frame in ImageSequence.Iterator(pilImage):
            pygameImage = pilImageToSurface(frame.convert('RGBA'))
            frames.append(pygameImage)
    else:
        frames.append(pilImageToSurface(pilImage))
    return frames
 
pygame.init()
window = pygame.display.set_mode((500,500))
clock = pygame.time.Clock()

gifFrameList = loadGIF("my_gif.gif")
currentFrame = 0

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

    window.fill(0)

    rect = gifFrameList[currentFrame].get_rect(center = (250,250))
    window.blit(gifFrameList[currentFrame],rect)
    currentFrame = (currentFrame + 1) % len(gifFrameList)
    
    pygame.display.flip()

您可以使用pygame.Surface对象的列表来生成Spritesheet

,

Pygame无法做gif图像,但如果您确实愿意,可以一次一帧一帧地对其进行动画处理。