我的背景在 pygame 中淡化后如何保持相同的背景颜色?

How do i keep the same background color after my background fades in pygame?

我是初学者,我正在制作一个需要背景淡出的游戏。我写的程序使背景变淡,但它不会保持它刚刚淡化成的颜色,因为它会在一段时间后跳回原来的颜色。我希望它还保持它在特定时间淡出的颜色,例如我希望程序在进入游戏的时间为 20,000 毫秒时淡入淡出,而不是按下 MOUSEBUTTONDOWN 键,这就是为什么我写了 'print(pygame.time.get_ticks()) 但是我用起来有问题,如果有其他方法,请评论给我看看。谢谢!

import pygame
import time
pygame.init()

DISPLAY_HEIGHT = 700
DISPLAY_WIDTH = 900

screen = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))

clock = pygame.time.Clock()
FPS = 60

#colors
WHITE = (255,255,255)
BLACK = (0,0,0)
SKY_BLUE = (102,178,255)


def fade(width, height):
    fade = pygame.Surface((width, height))
    fade.fill((31,97,141))
    for alpha in range(0, 300):
        fade.set_alpha(alpha)
        screen.blit(fade, (0,0))
        pygame.display.update()
        print(pygame.time.get_ticks())
        screen.fill((31,97,141))

running = True
while running:
    screen.fill(SKY_BLUE)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.MOUSEBUTTONDOWN:
            fade(DISPLAY_WIDTH, DISPLAY_HEIGHT)

    clock.tick(FPS)
    pygame.display.update()


    
    

要使背景淡出并保持它,您需要创建一个可供淡入淡出功能和主循环访问的共享表面。主要检查计数器和 运行 淡入淡出过程。这将暂停淡入淡出的主循环。 fade完成后查看fade surface变量,如果设置了就blit。

这是更新后的代码:

fade = None  # before fade process

def dofade(width, height):
    global fade  # share variable with main loop
    fade = pygame.Surface((DISPLAY_WIDTH, DISPLAY_HEIGHT))
    fade.fill((31,97,141))
    for alpha in range(0, 300):
        fade.set_alpha(alpha)
        screen.blit(fade, (0,0))
        pygame.display.update()
        #print(pygame.time.get_ticks())
        clock.tick(FPS)
        #screen.fill((31,97,141))

running = True
while running:
    screen.fill(SKY_BLUE)  # initial color
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.MOUSEBUTTONDOWN:  # can start fade early
            dofade(DISPLAY_WIDTH, DISPLAY_HEIGHT)
            
    tks = pygame.time.get_ticks()
    if (tks >= 20000 and not fade): # if hit counter and fade not processed yet
        dofade(DISPLAY_WIDTH, DISPLAY_HEIGHT)  # loop paused for fade process
    if fade: # if fade process done
        screen.blit(fade, (0,0)) # always show fade surface

    clock.tick(FPS)
    pygame.display.update()

只需将新颜色分配给变量SKY_BLUE,它将一直使用它

def fade(width, height):
    global SKY_BLUE
    
    # ... your code ...

    print('after fade')

    SKY_BLUE = (31,97,141)

我的版本有其他改动

import pygame

# --- constants ---

DISPLAY_HEIGHT = 700
DISPLAY_WIDTH = 900

WHITE = (255,255,255)
BLACK = (0,0,0)
SKY_BLUE = (102,178,255)

FPS = 60

# --- functions ---

def fade(width, height):
    global SKY_BLUE
    
    fade = pygame.Surface((width, height))
    fade.fill((31,97,141))

    for alpha in range(0, 256):
        fade.set_alpha(alpha)

        screen.blit(fade, (0,0))

        clock.tick(FPS)

        pygame.display.update()

    print('after fade')

    SKY_BLUE = (31,97,141)
    
# --- main ---

pygame.init()
screen = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))

clock = pygame.time.Clock()
    
running = True
while running:
    screen.fill(SKY_BLUE)
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.MOUSEBUTTONDOWN:
            fade(DISPLAY_WIDTH, DISPLAY_HEIGHT)

    clock.tick(FPS)
    pygame.display.update()

# - end -

pygame.quit()

同样的方法你也可以使用surface。

首先使用带颜色的表面SKY_BLUE

background = pygame.Surface((DISPLAY_WIDTH, DISPLAY_HEIGHT))
background.fill(SKY_BLUE)

running = True
while running:

    screen.blit(background, (0,0))

褪色后替换它

def fade(width, height):
    global background
    
    # ... code ... 

    print('after fade')

    background = fade

顺便说一句: 在这个地方最好为表面 fade 和函数 fade() 使用不同的名称,因为这会误导我。


import pygame

# --- constants ---

DISPLAY_HEIGHT = 700
DISPLAY_WIDTH = 900

WHITE = (255,255,255)
BLACK = (0,0,0)
SKY_BLUE = (102,178,255)

FPS = 60

# --- functions ---

def fade(width, height):
    global background
    
    surface = pygame.Surface((width, height))
    surface.fill((31,97,141))

    for alpha in range(0, 256):
        surface.set_alpha(alpha)

        screen.blit(surface, (0,0))

        clock.tick(FPS)

        pygame.display.update()

    print('after fade')

    background = surface
    
# --- main ---

pygame.init()
screen = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))

clock = pygame.time.Clock()
    
background = pygame.Surface((DISPLAY_WIDTH, DISPLAY_HEIGHT))
background.fill(SKY_BLUE)

running = True
while running:

    screen.blit(background, (0,0))
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.MOUSEBUTTONDOWN:
            fade(DISPLAY_WIDTH, DISPLAY_HEIGHT)

    clock.tick(FPS)
    pygame.display.update()

# - end -

pygame.quit()

至于 20 000 毫秒后的褪色,您可以使用 pygame.time.get_ticks() 获取当前时间并计算何时开始褪色(start_fading),稍后在循环中再次获取当前时间并与 start_fading 开始褪色。

可能需要布尔变量 (True/False) 才能在第一次褪色后不再执行此操作。

current_time = pygame.time.get_ticks()
start_fading = current_time + 20000
faded = False

running = True
while running:

    screen.blit(background, (0,0))
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        #elif event.type == pygame.MOUSEBUTTONDOWN:
        #    fade(DISPLAY_WIDTH, DISPLAY_HEIGHT)

    current_time = pygame.time.get_ticks()
    
    if not faded and current_time >= start_fading:
        fade(DISPLAY_WIDTH, DISPLAY_HEIGHT)
        faded = True
        
    clock.tick(FPS)
    pygame.display.update()

如果你想重复淡入淡出那么不要使用faded但在淡入淡出后使用start_fading

    if current_time >= start_fading:
        fade(DISPLAY_WIDTH, DISPLAY_HEIGHT)
        start_fading = current_time + 20000

如果你想要更多的元素延迟运行,那么你可以将它们保留在列表中并使用 for-loop 并且在 运行 一些函数之后你可以将它们从这个列表中删除。但是我这里不会用到。

import pygame

# --- constants ---

DISPLAY_HEIGHT = 700
DISPLAY_WIDTH = 900

WHITE = (255,255,255)
BLACK = (0,0,0)
SKY_BLUE = (102,178,255)

FPS = 60

# --- functions ---

def fade(width, height):
    global background
    
    surface = pygame.Surface((width, height))
    surface.fill((31,97,141))

    for alpha in range(0, 256):
        surface.set_alpha(alpha)

        screen.blit(surface, (0,0))

        clock.tick(FPS)

        pygame.display.update()

    print('after fade')

    background = surface
    
# --- main ---

pygame.init()
screen = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))

clock = pygame.time.Clock()
    
background = pygame.Surface((DISPLAY_WIDTH, DISPLAY_HEIGHT))
background.fill(SKY_BLUE)

current_time = pygame.time.get_ticks()
start_fading = current_time + 20000
faded = False

running = True
while running:

    screen.blit(background, (0,0))
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        #elif event.type == pygame.MOUSEBUTTONDOWN:
        #    fade(DISPLAY_WIDTH, DISPLAY_HEIGHT)

    current_time = pygame.time.get_ticks()
    
    if not faded and current_time >= start_fading:
        fade(DISPLAY_WIDTH, DISPLAY_HEIGHT)
        faded = True
        
    clock.tick(FPS)
    pygame.display.update()

# - end -

pygame.quit()

还有其他方法 - 您可以使用 pygame.time.set_timer()pygame.USEREVENT 来生成带有一些延迟的自定义事件

FADE_EVENT = pygame.USEREVENT

pygame.time.set_timer(FADE_EVENT, 2000)

然后你可以使用for event in pygame.event.get():捕获它并执行fade()

        if event.type == FADE_EVENT:
            pygame.time.set_timer(FADE_EVENT, 0) # turn off after one use 
            fade(DISPLAY_WIDTH, DISPLAY_HEIGHT)

import pygame

# --- constants ---

DISPLAY_HEIGHT = 700
DISPLAY_WIDTH = 900

WHITE = (255,255,255)
BLACK = (0,0,0)
SKY_BLUE = (102,178,255)

FPS = 60

# --- functions ---

def fade(width, height):
    global background
    
    surface = pygame.Surface((width, height))
    surface.fill((31,97,141))

    for alpha in range(0, 256):
        surface.set_alpha(alpha)

        screen.blit(surface, (0,0))

        clock.tick(FPS)

        pygame.display.update()

    print('after fade')

    background = surface
    
# --- main ---

pygame.init()
screen = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))

clock = pygame.time.Clock()
    
background = pygame.Surface((DISPLAY_WIDTH, DISPLAY_HEIGHT))
background.fill(SKY_BLUE)

#FADE_EVENT = pygame.event.custom_type()  # PyGame 2.0
FADE_EVENT = pygame.USEREVENT             # PyGame 1.9

#pygame.time.set_timer(FADE_EVENT, 2000, True) # PyGame 2.0 # `once=True` - turn off after one use
pygame.time.set_timer(FADE_EVENT, 2000)        # PyGame 1.9 # doesn't have `once`, it will need `set_timer(..., 0)`

running = True
while running:

    screen.blit(background, (0,0))
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if event.type == FADE_EVENT:
            pygame.time.set_timer(FADE_EVENT, 0) # PyGame 1.9 # turn off after one use 
            fade(DISPLAY_WIDTH, DISPLAY_HEIGHT)
            
    clock.tick(FPS)
    pygame.display.update()

# - end -

pygame.quit()