Im trying to make a fade in and out

384 Views Asked by At

I am trying to create a function that will fade in and out for a game that I'm making. the problem is that the first part works fine but the second pard doesn't work.

WIDTH = screen width, HEIGHT = screen height, WINDOW = the name of the window, and I imported pygame as pg

def fade():
    fade = pg.Surface((WIDTH, HEIGHT))
    fade.fill((0,0,0))
    opacity = 0
    for r in range(0, 100):
        opacity += 1
        fade.set_alpha(opacity)
        WINDOW.blit(fade, (0,0))
        pg.display.update()
        pg.time.delay(10)
    for r in range(0, 100):
        opacity -= 1
        fade.set_alpha(opacity)
        WINDOW.blit(fade, (0,0))
        pg.display.update()
        pg.time.delay(10)

From looking at the code everything should work fine but it doesn't. I didn't paste the entire code because its 300 lines.

1

There are 1 best solutions below

1
Rabbid76 On BEST ANSWER

What they actually do is draw a transparent image over the background over and over again until the background is completely covered. You can't make the background visible again by blending the image with less transparency over it. You have to completely redraw the whole scene in every frame, blending an ever more agile transparent image over it.
I suggest to write a blitFadeIn and blitFadeOut function and call it in the application loop.

Minimal example:

import pygame

pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()

background = pygame.Surface(window.get_size())
ts, w, h, c1, c2 = 50, *background.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)]
[pygame.draw.rect(background, color, rect) for rect, color in tiles]

font = pygame.font.SysFont(None, 100)
text = font.render("image", True, (255, 255, 0))
image = pygame.Surface(window.get_size(), pygame.SRCALPHA)
pygame.draw.ellipse(image, "red", window.get_rect().inflate(-20, -20))
image.blit(text, text.get_rect(center = window.get_rect().center))

image.set_alpha(0)

def blitFadeIn(target, image, pos, step=2):
    alpha = image.get_alpha()
    alpha = min(255, alpha + step)
    image.set_alpha(alpha)
    target.blit(image, pos)
    return alpha == 255

def blitFadeOut(target, image, pos, step=2):
    alpha = image.get_alpha()
    alpha = max(0, alpha - step)
    image.set_alpha(alpha)
    target.blit(image, pos)
    return alpha == 0

fade_in = False
fade_out = False
run = True
while run:
    clock.tick(100)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False 
        if event.type == pygame.KEYDOWN or event.type == pygame.MOUSEBUTTONDOWN:
            if not fade_in and not fade_out:
                fade_in = True

    window.blit(background, (0, 0))
    if fade_in:
        done = blitFadeIn(window, image, (0, 0))
        if done:
            fade_in, fade_out = False, True
    if fade_out:
        done = blitFadeOut(window, image, (0, 0))
        if done:
            fade_out = False
    pygame.display.flip()

pygame.quit()
exit()

Also see: