Is it possible to change sprite colours in Pygame?
If the image is a "mask" image, with a transparent background and a white (255, 255, 255) mask, then you can "tint" the image with ease.
Load the image:
image = pygame.image.load(imageName)
Generate a uniform colored image with an alpha channel and the same size:
colorImage = pygame.Surface(image.get_size()).convert_alpha()
colorImage.fill(color)
Blend the image
with maskImage
, by using the filter BLEND_RGBA_MULT
:
image.blit(colorImage, (0,0), special_flags = pygame.BLEND_RGBA_MULT)
A sprite class may look like this:
class MySprite(pygame.sprite.Sprite):
def __init__(self, imageName, color):
super().__init__()
self.image = pygame.image.load(imageName)
self.rect = self.image.get_rect()
colorImage = pygame.Surface(self.image.get_size()).convert_alpha()
colorImage.fill(color)
self.image.blit(colorImage, (0,0), special_flags = pygame.BLEND_RGBA_MULT)
Minimal example: repl.it/@Rabbid76/PyGame-ChangeColorOfSurfaceArea-4
import pygame
def changColor(image, color):
colouredImage = pygame.Surface(image.get_size())
colouredImage.fill(color)
finalImage = image.copy()
finalImage.blit(colouredImage, (0, 0), special_flags = pygame.BLEND_MULT)
return finalImage
pygame.init()
window = pygame.display.set_mode((300, 160))
image = pygame.image.load('CarWhiteDragon256.png').convert_alpha()
hue = 0
clock = pygame.time.Clock()
nextColorTime = 0
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
color = pygame.Color(0)
color.hsla = (hue, 100, 50, 100)
hue = hue + 1 if hue < 360 else 0
color_image = changColor(image, color)
window.fill((96, 96, 64))
window.blit(color_image, color_image.get_rect(center = window.get_rect().center))
pygame.display.flip()
pygame.quit()
exit()
Sprite:
Trying to make sections of sprite change colour, but whole sprite changes instead
self.image
is the loaded image, where you want to change specific regions by a certain color and self.mask
is a mask which defines the regions.
And you create an image masked
, which contains the regions which are specified in mask
tinted in a specific color.
So all you've to do is to .blit
the tinted mask (masked
) on the image
without any special_flags
set:
self.image.blit(self.masked, (0, 0))
See the example, where the red rectangle is changed to a blue rectangle:
repl.it/@Rabbid76/PyGame-ChangeColorOfSurfaceArea
Minimal example: repl.it/@Rabbid76/PyGame-ChangeColorOfSurfaceArea-3
Sprite:
Mask:
import pygame
def changColor(image, maskImage, newColor):
colouredImage = pygame.Surface(image.get_size())
colouredImage.fill(newColor)
masked = maskImage.copy()
masked.set_colorkey((0, 0, 0))
masked.blit(colouredImage, (0, 0), None, pygame.BLEND_RGBA_MULT)
finalImage = image.copy()
finalImage.blit(masked, (0, 0), None)
return finalImage
pygame.init()
window = pygame.display.set_mode((404, 84))
image = pygame.image.load('avatar64.png').convert_alpha()
maskImage = pygame.image.load('avatar64mask.png').convert_alpha()
colors = []
for hue in range (0, 360, 60):
colors.append(pygame.Color(0))
colors[-1].hsla = (hue, 100, 50, 100)
images = [changColor(image, maskImage, c) for c in colors]
clock = pygame.time.Clock()
nextColorTime = 0
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill((255, 255, 255))
for i, image in enumerate(images):
window.blit(image, (10 + i * 64, 10))
pygame.display.flip()
pygame.quit()
exit()
How can I change an image's color in Pygame?
If you want to fill the entire image with a single color but preserve the transparency, you can utilize two nested for
loops and the pygame.Surface.set_at
method to change every pixel of the surface.
import pygame as pg
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
BG_COLOR = pg.Color('gray12')
img = pg.Surface((150, 150), pg.SRCALPHA)
pg.draw.polygon(img, (0, 100, 200), ((75, 0), (150, 75), (75, 150), (0, 75)))
def set_color(img, color):
for x in range(img.get_width()):
for y in range(img.get_height()):
color.a = img.get_at((x, y)).a # Preserve the alpha value.
img.set_at((x, y), color) # Set the color of the pixel.
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_j:
set_color(img, pg.Color(255, 0, 0))
elif event.key == pg.K_h:
set_color(img, pg.Color(0, 100, 200))
screen.fill(BG_COLOR)
screen.blit(img, (200, 200))
pg.display.flip()
clock.tick(60)
If you want to tint a surface, take a look at this post: https://stackoverflow.com/a/49017847/6220679
Change color of Pygame Surface
Your problem is that you keep creating new sprites every frame, so when you change the color of one Rectangle
to green, it will be covered by a white one.
You do this by calling the fill
function (which creates new Rectangle
instances) inside the drawGrid
function.
Pygame Ellipse change color to collide
Your .draw()
function is only drawing the ball with a different colour while it's outside of the bounds of the display, which is never. What you instead want, is within your .check_collisions()
, if a collision is detected, set a property on self
determining which colour to use.
Then, in .draw()
, instead of draw.ellipse(self.display, self.color_default, self.rect)
, you'd have draw.ellipse(self.display, self.current_colour, self.rect)
, or something similar.
Related Topics
Python Requests.Get() Returns Improperly Decoded Text Instead of Utf-8
Modular Multiplicative Inverse Function in Python
How to Check If a String Only Contains Letters
Pandas Select Rows and Columns Based on Boolean Condition
How to Remove the Space Between Subplots in Matplotlib.Pyplot
Python 'If X Is Not None' or 'If Not X Is None'
How to Plot a Confusion Matrix
Why Doesn't List Have Safe "Get" Method Like Dictionary
Sort a Pandas Dataframe Series by Month Name
Subsampling Every Nth Entry in a Numpy Array
How to Find Duplicate Elements in Array Using for Loop in Python
Why Might Python's 'From' Form of an Import Statement Bind a Module Name
Truncate to Three Decimals in Python
How to Convert 24 Hour Time to 12 Hour Time
How to Use Python to Get the System Hostname