PyGame 或 Moviepy - 显示透明视频

问题描述

我遇到了一个非常奇怪的情况,但我会尽力解释一切。所以我使用 PyGame 编写游戏。我使用moviepy在表面上显示视频。现在我正在做一个战斗画面,我想为攻击设置动画。我会显示一个快速屏幕截图

Heres the screen of the combat

当点击“火球”时,我想显示一个火球。视频本身具有透明度,但它用白色填充。

我之前用来显示过场动画的代码如下:

video = VideoFileClip('assets/Attacks/Frantz/fireball.webm')
video.preview()

当它播放视频时,它看起来像这样:

Here

我的初始文件一个 gif,我将其转换为 mp4。我发现 mp4 不支持 alpha/transparency 我尝试通过将 video = VideoFileClip('assets/Attacks/Frantz/fireball.mp4') 替换为 video = VideoFileClip('assets/Attacks/Frantz/fireball.gif') 来使用 gif 但同样的事情发生在白色背景上(是的,gif 具有 100% 透明度) 我有点不知道该怎么办。我是否应该尝试其他文件格式,如果是,我如何删除透明度,但我认为我需要更改代码中的某些内容,以便我可以实际使用 gif 或其他内容

顺便说一下 gif 的文件

我知道我的问题很奇怪,但它用于学校项目,我将不胜感激

解决方法

电影不是您想要的。你想要的是一个动画精灵。动画精灵由显示在连续帧中的许多不同精灵组成。这些精灵的来源可以是精灵表、动画 GIF 或位图列表。

关于这个话题有各种各样的问题和答案。例如:


由于您的 GIF 不透明,您必须使用 set_colorkey() 设置透明颜色的颜色键:

pygameImage.set_colorkey((0,0))

示例:

import pygame
from PIL import Image,ImageSequence

def pilImageToSurface(pilImage):
    return pygame.image.fromstring(
        pilImage.tobytes(),pilImage.size,pilImage.mode).convert()

def pilImageToSurface(pilImage):
    return pygame.image.fromstring(
        pilImage.tobytes(),pilImage.mode).convert()

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('RGB'))
            pygameImage.set_colorkey((0,0))
            frames.append(pygameImage)
    else:
        frames.append(pilImageToSurface(pilImage))
    return frames
 
pygame.init()
window = pygame.display.set_mode((500,500))
clock = pygame.time.Clock()

background = pygame.Surface(window.get_size())
ts,w,h,c1,c2 = 50,*window.get_size(),(128,128,128),(64,64,64)
tiles = [((x*ts,y*ts,ts,ts),c1 if (x+y) % 2 == 0 else c2) for x in range((w+ts-1)//ts) for y in range((h+ts-1)//ts)]
for rect,color in tiles:#
    pygame.draw.rect(background,color,rect)

gifFrameList = loadGIF('fire.gif')
currentFrame = 0

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

    window.blit(background,(0,0))

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

pygame.quit()
exit()

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...