Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to change sprite colours in Pygame?

Tags:

I'm making a game in Python using Pygame that includes a small avatar maker before the game starts, but instead of creating a big sprite sheet with 88 different combinations of hairstyles and colours, is there a way that I can just use a generic .png image of each hairstyle and apply colour to it in-game?

The hairstyles are saved as .png images with alpha and anti-aliasing, so they are not just one shade of colour. I've got 8 different hairstyles and 11 different colours. It wouldn't be a problem to load them in as a sprite sheet and clip them in-game, but if there was a way to apply colour (or hue) in the game then not only would it be easier on the memory, but would open it up to more possibilities.

hairstyles

like image 483
Jayce Avatar asked May 19 '19 16:05

Jayce


1 Answers

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:

like image 69
Rabbid76 Avatar answered Oct 27 '22 00:10

Rabbid76