python - 如何在 pygame 中调色板交换 Sprite 而不使用后面的矩形

标签 python pygame pygame-surface

Player sprite without palette swap

Colored rectangle appears behind sprite

所以我正在制作一个自动生成的游戏,其中每个级别都有不同的调色板。现在,我想在我的玩家 Sprite 内切换一种颜色。我使用了这个视频: https://www.youtube.com/watch?v=MLrDR-Mks8I 创建一个函数,接受我想要交换的颜色和替换它的新颜色。但是,当我这样做时,它会替换 Sprite 中的颜色,但还会在其周围创建一个与新颜色颜色相同的矩形。这可能是因为我正在填充新表面并为旧表面创建一个颜色键,该颜色键填充了 Sprite 的整个命中框。

def palette_swap(self, surf, old_c, new_c):
    img_copy = pygame.Surface(surf.get_size())
    img_copy.fill(new_c)
    surf.set_colorkey(old_c)
    img_copy.blit(surf, (0, 0))
    return img_copy

def animate(self):

image = self.palette_swap(image, (255, 148, 66), (249, 4, 99))

我不想上传所有代码,因为它很多,但只知道动画函数会更新图像。当我将此函数应用于每个 Sprite 时,会发生以下情况:

Image

作为引用,每个 Sprite 周围不应该有矩形。 pygame 中是否有另一种不需要此方法的调色板交换方法?不,这与更改 Sprite 的色调不同,我正在更改调色板,这意味着我正在单独更改颜色。我认为这并不困难,因为我的调色板只有 4 种颜色,而且我希望为每个级别只更改其中 2 种颜色。

最佳答案

您必须使用pygame.mask完成您的任务。

  1. 根据颜色创建 mask

    color_mask = pygame.mask.from_threshold(image, old_c, threshold=(1, 1, 1, 255))
    
  2. Mask转换为具有新颜色的Surface

    color_change_surf = color_mask.to_surface(setcolor=new_c, unsetcolor=(0, 0, 0, 0))
    
  3. 复制图像并在其顶部绘制颜色 mask 表面

    img_copy = surf.copy()
    img_copy.blit(color_change_surf, (0, 0))
    
def palette_swap(self, surf, old_c, new_c):
    color_mask = pygame.mask.from_threshold(image, old_c, threshold=(1, 1, 1, 255))
    color_change_surf = color_mask.to_surface(setcolor=new_c, unsetcolor=(0, 0, 0, 0))
    img_copy = surf.copy()
    img_copy.blit(color_change_surf, (0, 0))
    return img_copy

最小示例

import pygame

pygame.init()
window = pygame.display.set_mode((350, 200))
clock = pygame.time.Clock()

def palette_swap(surf, old_c, new_c):
    color_mask = pygame.mask.from_threshold(image, old_c, threshold=(1, 1, 1, 255))
    color_change_surf = color_mask.to_surface(setcolor=new_c, unsetcolor=(0, 0, 0, 0))
    img_copy = surf.copy()
    img_copy.blit(color_change_surf, (0, 0))
    return img_copy

image = pygame.Surface((100, 100))
image.fill((0, 255, 0))
image.set_colorkey((0, 255, 0))
pygame.draw.circle(image, "black", (50, 50), 50)
pygame.draw.circle(image, (255, 148, 66), (50, 50), 40)
pygame.draw.circle(image, "black", (30, 35), 10)
pygame.draw.circle(image, "black", (70, 35), 10)

new_iamge = palette_swap(image, (255, 148, 66), (249, 4, 99))

run = True
while run:
    clock.tick(100)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False 
    
    window.fill("gray")
    window.blit(image, image.get_rect(center = (100, 100)))
    window.blit(new_iamge, new_iamge.get_rect(center = (250, 100)))
    pygame.display.flip()

pygame.quit()
exit()

关于python - 如何在 pygame 中调色板交换 Sprite 而不使用后面的矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77590955/

相关文章:

python - 当我在窗口中间画一个圆圈时出现错误

python - Django Admin 如何更改关系字段中的文本

Python 安装工具 : install pacakge dependencies from a local repository

python - pygame 未关闭并返回控制台(python)

numpy - 如何在 pygame 中制作 Surface 的灰度副本?

python - Pygame - 是否可以根据时间更改背景图像?

python - 如何使实体在pygame中因颜色碰撞而受到伤害?

python - win.blit()后台pygame时出现滞后

python - Python Multiprocessing.Process 模块中的术语 bootstrap 指的是什么?

Python套接字等待