0

I have a pretty weird situation but i will try hard to explain everything the best i can. So im coding a game using PyGame. I used moviepy to show a video on the surface. Now im doing a combatscreen and i want to animate the attacks. Ill show a quick screenshot

Heres the screen of the combat

When clicked on "Fireball" i want to show a fireball. The video itself has transparency but it fills it up with white.

The code i used previously to show cutscenes for example is following:

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

When it plays the video it looks like this:

Here

My initial file was a gif that i converted to an mp4. i found out that mp4 doesn't support alpha/transparency i tried using the gif by replacing video = VideoFileClip('assets/Attacks/Frantz/fireball.mp4') with video = VideoFileClip('assets/Attacks/Frantz/fireball.gif') but the same thing happend with the white background (And yes the gif has 100% transparency) I kinda don't know what to do. Should i try other file formats, if yes how do i remove the transparency but i think i need to change something in the code so i might be able to actually use a gif or something.

Heres the file of the gif btw

I know my issue if very weird but its for a school project and i would greatly appreciate some help

Rabbid76
  • 202,892
  • 27
  • 131
  • 174

1 Answers1

0

A movie is not what you want. What you want is an animated sprite. An animated sprite is made up of many different sprites that are displayed in consecutive frames. The source of these sprites can be a sprite sheet, an animated GIF, or a list of bitmaps.

There are various questions and answers on this topic. For example:


Since your GIF is not transparent, you have to set the color key for the transparent color with set_colorkey():

pygameImage.set_colorkey((0, 0, 0))

Example:

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.size, 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, 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()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174