如何在pygame中从一种颜色褪色到另一种颜色?

2024-06-01 11:33:52 发布

您现在位置:Python中文网/ 问答频道 /正文

在pygame中,我如何从一种颜色褪色到另一种颜色?我想慢慢地改变一个圆圈的颜色,从绿色到蓝色,再到紫色,再到粉色,再到红色,再到橙色,再到黄色再到绿色。我该怎么做?目前,我正在使用

def colour():
    switcher = {
        0: 0x2FD596,
        1: 0x2FC3D5,
        2: 0x2F6BD5,
        3: 0x432FD5,
        4: 0x702FD5,
        5: 0xBC2FD5,
        6: 0xD52F91,
        7: 0xD52F43,
        8: 0xD57F2F,
        9: 0xD5D52F,
        10: 0x64D52F,
        11: 0x2FD557,
    }
    return switcher.get(round((datetime.datetime.now() - starting_time).total_seconds()%11))

但这在颜色和外观之间有很大的区别。在


Tags: datetimereturn颜色defpygame橙色蓝色绿色
3条回答

如果你不需要计算任何颜色,你可以选择:

首先,你需要确定溶解需要多长时间。您还需要存储原始颜色和最终颜色。最后,计算混合物。我会为此创建一个类:

import pygame
import time

class color_blend:
    def __init__(self, start_color, end_color, duration=1000):
        self.start_color = pygame.Color(start_color.r, start_color.g, start_color.b)
        self.current_color = pygame.Color(start_color.r, start_color.g, start_color.b)
        self.end_color = end_color
        self.duration = float(duration)
        self.start_time = color_blend.millis()

    # Return current time in ms
    @staticmethod
    def millis():
        return (int)(round(time.time() * 1000))

    # Blend any 2 colors
    # 0 <= amount <= 1 (0 is all initial_color, 1 is all final_color)
    @staticmethod
    def blend_colors(initial_color, final_color, amount):
        # Calc how much to add or subtract from start color
        r_diff = (final_color.r - initial_color.r) * amount
        g_diff = (final_color.g - initial_color.g) * amount
        b_diff = (final_color.b - initial_color.b) * amount

        # Create and return new color
        return pygame.Color((int)(round(initial_color.r + r_diff)),
                            (int)(round(initial_color.g + g_diff)),
                            (int)(round(initial_color.b + b_diff)))

    def get_next_color(self):
        # Elapsed time in ms
        elapsed_ms = color_blend.millis() - self.start_time

        # Calculate percentage done (0 <= pcnt_done <= 1)
        pcnt_done = min(1.0, elapsed_ms / self.duration)

        # Store new color
        self.current_color = color_blend.blend_colors(self.start_color, self.end_color, pcnt_done)
        return self.current_color

    def is_finished(self):
        return self.current_color == self.end_color

# Blend red to green in .3 seconds
c = color_blend(pygame.Color(255, 0, 0), pygame.Color(0, 255, 0), 300)
while not c.is_finished():
    print(c.get_next_color())

你可以很容易地修改它来做非线性混合。例如,在blend_colorsamount = math.sin(amount * math.pi)

(我不是Pygame专家-可能已经有一个内置函数了。)

你可以转换成一个整数,增加数字,再把它转换回十六进制,这样就可以在一种颜色到另一种颜色的所有值之间切换。然后循环,直到达到下一个值,如下所示:

value1 = 0xff00ff
value2 = 0xffffff
increment = 1 # amount to decrease or increase the hex value by
while value1 != value2:
    if value1 > value2:
        if int(value1)-increment < int(value2): # failsafe if the increment is greater than 1 and it skips being the value
            value1 = value2
        else:
            value1 = hex(int(value1)-increment)
    else:
        if int(value1)+increment > int(value2):
            value1 = value2
        else:
            value1 = hex(int(value1)+increment)
    code_to_change_colour(value1)

请参阅editbyprune以获得更优雅的实现。请注意,code_to_change_colour(value1)应该更改为您在程序中更改颜色的方式。增量将允许您更改跳过的颜色数。显然,这段代码需要以一种易于使用的方式进行编辑:例如def fade(value1, value2)这样的函数。在


从@Prune编辑——因为代码在注释中不能很好地工作。在

请注意,您所写的大部分内容都是“仅仅”循环控制。您已经知道开始和停止值以及固定的增量。这意味着一个for循环,而不是while。考虑一下这个:

^{pr2}$

关键是简单地计算每一步要改变多少通道(a、r、g和b)。Pygame的Color类非常方便,因为它允许在每个通道上进行迭代,并且它的输入非常灵活,所以您只需在下面的示例中将'blue'更改为{},它仍将运行。在

下面是一个简单的运行示例:

import pygame
import itertools

pygame.init()

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

colors = itertools.cycle(['green', 'blue', 'purple', 'pink', 'red', 'orange'])

clock = pygame.time.Clock()

base_color = next(colors)
next_color = next(colors)
current_color = base_color

FPS = 60
change_every_x_seconds = 3.
number_of_steps = change_every_x_seconds * FPS
step = 1

font = pygame.font.SysFont('Arial', 50)

running = True
while running:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    text = font.render('fading {a} to {b}'.format(a=base_color, b=next_color), True, pygame.color.Color('black'))

    step += 1
    if step < number_of_steps:
        # (y-x)/number_of_steps calculates the amount of change per step required to 
        # fade one channel of the old color to the new color
        # We multiply it with the current step counter
        current_color = [x + (((y-x)/number_of_steps)*step) for x, y in zip(pygame.color.Color(base_color), pygame.color.Color(next_color))]
    else:
        step = 1
        base_color = next_color
        next_color = next(colors)

    screen.fill(pygame.color.Color('white'))
    pygame.draw.circle(screen, current_color, screen.get_rect().center, 100)
    screen.blit(text, (230, 100))
    pygame.display.update()
    clock.tick(FPS)

enter image description here


如果不想依赖于帧速率,而是使用基于时间的方法,可以将代码更改为:

^{pr2}$

相关问题 更多 >