0

Hii I need help about pygame I'm under python 3.7.2 64 bits So I'm bassically working about a smooth way to exit a window I thought to create a fade out animation by using pygame.SRCALPHA on a surface Let me introduce the problem : it's isn't work at all :(

            for e in pygame.event.get():
                if e.type == QUIT:
                    window = 'left'
                    run = False
                    loop = False
                    c = 0
                    for i in range(50):
                        fade('out')
                        time.sleep(0.05)
                        pygame.display.update()
                    pygame.display.quit()
                    sys.exit()

to understand well all of this I give you critical others lines

alpha = pygame.Surface((1920, 1080), pygame.SRCALPHA)

this one is the creation of the surface

def fade(f_type): # must set c at 255 or 1
    global c, alpha
    c += 1 if f_type == 'out' else -1
    alpha.fill((0,0,0,c))
    screen.blit(alpha, (0,0))

And this is the fade() function to progress fading

Oh, and this is my traceback, I mean, a error message that I didn't know appear, maybe could help you :D

libpng warning: Interlace handling should be turned on when using png_read_image
libpng warning: iCCP: known incorrect sRGB profile   <- this line
[Finished in 35.5s]

Someone know were the problem come from ? @here

  • and what did you get ? we can't run it so we can't see how it looks like. If you will blit black surface on black surface then you can't see alpha. You would have to blit something before you blit `alpha` – furas Jul 13 '19 at 12:23

2 Answers2

0

I don't know what wrong with your fading because you did explain it and we can't run your code to see proble.

It fades image after pressing ESC (works on Linux Mint 19, Python 3.7, PyGame 1.9.6)

import pygame

pygame.init()
screen = pygame.display.set_mode((800,600))

img = pygame.image.load('image.jpg').convert()
img_rect = img.get_rect()

alpha = pygame.Surface((800, 600), pygame.SRCALPHA)
alpha_rect = alpha.get_rect()

alpha_val = 0
alpha_step = 10

clock = pygame.time.Clock()
running = True
fading = False


while running:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                fading = True

    if fading:
        alpha.fill((0,0,0,alpha_val))
        if alpha_val < 256-alpha_step:
            alpha_val += alpha_step
        else:
            running = False

    screen.blit(img, img_rect)
    screen.blit(alpha, alpha_rect)

    pygame.display.flip()
    clock.tick(30)

pygame.quit()    

The same with set_alpha() but without pygame.SRCALPHA.

This method can be use also to fade from one image to another.

import pygame

pygame.init()
screen = pygame.display.set_mode((800,600))

#img = pygame.image.load('image.jpg').convert()
img = pygame.Surface((800, 600))
img.fill((255, 0 , 0))
img_rect = img.get_rect()

alpha = pygame.Surface((800, 600)) # without pygame.SRCALPHA
alpha.set_alpha(0)
alpha_rect = alpha.get_rect()

alpha_val = 0
alpha_step = 10

clock = pygame.time.Clock()
running = True
fading = False

while running:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                fading = True

    if fading:
        alpha.set_alpha(alpha_val)
        if alpha_val < 256-alpha_step:
            alpha_val += alpha_step
        else:
            running = False

    screen.blit(img, img_rect)
    screen.blit(alpha, alpha_rect)

    pygame.display.flip()
    clock.tick(30)

pygame.quit()    
furas
  • 134,197
  • 12
  • 106
  • 148
0

In general the algorithm works, but it is not necessary to increment the variable c. Note, that the display should be "darkened" linearly, so it is sufficient to subtract a constant value from the colors of the entire surface. If you subtract 1, 255 times form the surface, then the entire surface is black.

This can be achieved by .fill and setting the special_flags parameter pygame.BLEND_SUB:

def fadeout():
    screen.fill((1, 1, 1, 1), special_flags = pygame.BLEND_SUB)
for i in range(255):
    fadeout()
    # [...]

For a fade in you have to copy the entire surface. .blit() the screen in a loop and apply a "reverse" fade:

def fadein(finalscreen, c):
    screen.blit(finalscreen, (0, 0))
    screen.fill((c, c, c, c), special_flags = pygame.BLEND_SUB)
finalscreen = screen.copy()
for i in range(255):
    fadein(finalscreen, 255-i)
    # [...]

Use pygame.time.delay() rather than time.sleep(), to control the fade time. The time has to be set in milliseconds. 1 second are 1000 milliseconds. The loop runs 255 times, so time to be delayed in the loop is ~ fade_time * 1000 // 255).
As in the main loop, the events have to be handled in the fade loop, too. Do this by pygame.event.poll():

fade_time = 3 # 3 seconds
for i in range(255):
   fadeout()
    pygame.time.delay(fade_time * 1000 // 255) # milliseconds / 255 
    pygame.display.update()
    pygame.event.poll()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174