I hesitated to post an answer because I came up with almost the same answer as Sloth's, but I'd just like to mention linear interpolation (short lerp
, also called mix
in OpenGL/GLSL). It's usually used to blend between two colors, but unfortunately pygame's Color
class doesn't have a lerp method, so you have to define your own lerp
function and use a list comprehension to interpolate the RGBA values.
Here's the lerp
function from Wikipedia ported to Python (t
is the weight and has to be between 0 and 1):
def lerp(v0, v1, t):
return (1 - t) * v0 + t * v1
Now you can lerp the RGBA values of two colors with a list comprehension.
color = [lerp(v0, v1, t) for v0, v1 in zip(color1, color2)]
E.g.:
>>> [lerp(v0, v1, .5) for v0, v1 in zip((0, 0, 0), (255, 255, 255))]
[127.5, 127.5, 127.5]
>>> [lerp(v0, v1, .25) for v0, v1 in zip((0, 0, 0), (255, 255, 255))]
[63.75, 63.75, 63.75]
If you don't need the alpha channel, you can also use pygame's Vector3 class which has a lerp
method for your colors, then you'd just have to write: color = color1.lerp(color2, t)
.
import itertools
import pygame as pg
from pygame.math import Vector3
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
color_cycle = itertools.cycle([
Vector3(255, 0, 0),
Vector3(0, 255, 0),
Vector3(255, 255, 0),
Vector3(0, 0, 255),
])
color1 = next(color_cycle)
color2 = next(color_cycle)
color = color1
start_time = pg.time.get_ticks()
time_interval = 2000 # milliseconds
t = 0
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
now = pg.time.get_ticks()
t = (now - start_time) / time_interval
if t > 1:
t = 0
start_time = now
color1, color2 = color2, next(color_cycle)
color = color1.lerp(color2, t) # Lerp the two colors.
screen.fill(color)
pg.display.flip()
clock.tick(60)