Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
213 views
in Technique[技术] by (71.8m points)

python - Trying to make sections of sprite change colour, but whole sprite changes instead

I have a few sprites in my game that need specific parts to be able to change colour.

My process I am trying to to have a pure white sprite image that is transparent everywhere the colour does not need to be. I am blitting a coloured square on top of that, and then that on top of the main sprite, however the main sprite then changes colour everywhere, but while respecting the main sprite transparency. The part that confuses me most is that the masked colour image does look correct when I put it on the main screen.

# Load main sprite and mask sprite
        self.image = pygame.image.load("Enemy.png").convert_alpha()
        self.mask = pygame.image.load("EnemyMask.png").convert_alpha()

# Create coloured image the size of the entire sprite
        self.coloured_image = pygame.Surface([self.width, self.height])
        self.coloured_image.fill(self.colour)

# Mask off the coloured image with the transparency of the masked image, this part works
        self.masked = self.mask.copy()
        self.masked.blit(self.coloured_image, (0, 0), None, pygame.BLEND_RGBA_MULT)

# Put the masked image on top of the main sprite
        self.image.blit(self.masked, (0, 0), None, pygame.BLEND_MULT)

Enemy.png enemy.png

EnemyMask.png (It's white so can't be seen) EnemyMask.png

Masked colour Masked Colour

Final Failed Sprite Failed Sprite

Can't post images, not enough reputation

I get no error, but only the white part of the shield is supposed to be green

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...