Pygame 中更复杂的颜色渐变

More Complex Color Gradients in Pygame

在 Python 3.8 中使用 Pygame 模块:

我正在尝试为我正在制作的彩色游戏制作颜色渐变。我知道如何制作一维渐变,像这样:

但我希望能够在渐变中创建具有两种以上颜色的图像。来自互联网的一个例子是这样的:(忽略花哨的文字)

如何创建一个函数来在表面上生成多种颜色的渐变?重要的是我可以选择角落的颜色,或者至少能够以我能理解的方式影响它们。

网上找的一个思路是这样的:

for i in range(900):
   for j in range(900):
      surface.set_at((i,j),(i/4,j/4,i/4))

我的问题是很难选择它生成的颜色。我不知道如何让颜色相互融合,尤其是多种颜色。

没有魔法。 Pygame 没有 API 渐变,虽然你没有 post 你的一段代码,你可能把插值做得很好。

所以,对于“二维方形渐变”,你必须继续打破你的 小部分的问题,直到你得到你想要的 - 为此,它可能是:在您感兴趣的区域顶部运行一个渐变 y == 0,另一个渐变在您的区域底部运行,在 y = 高度,并且对于每一列,您插入一个新的渐变, 从 顶部渐变的颜色和 运行 底部渐变的颜色。

唯一的坏消息是这在 pygame 中会非常慢 - 但您可以绘制一次并保存生成的图像,然后在游戏时加载它。

还有其他适合绘制线性渐变的库和框架, 并且速度快,就像 Cairo、gegl 和 opengl 本身一样——但是其中 none 有一种现成的方法可以将一个完整的渐变过渡到另一个。

[继续...]

So, for a "2 dimensional square gradient", you have to continue to break your problem in smaller parts, until you get what you want - For this, it could be: have a gradient that runs on the top of your interest area at y = 0, another gradient that runs at the bottom of your area, at y = height, and for each column, you interpolate a new gradient, starting at the color on the top gradient and running to the color at the bottom gradient.

效果很好!我能够想出三个函数,它们一起创建了很棒的 4 色矩形渐变,每种颜色位于不同的角。如果您想使用它,这是我的代码:

windowSurface = pygame.display.set_mode((1500,900))
s = pygame.Surface(size, pygame.SRCALPHA)
gradientStorage = pygame.Surface((1500,1500))
colorGridStorage = pygame. Surface((1500,1500))


def colorMix(color1, color2, paletteSize):    # creates a list of colors that gradually fade from color1 to color2, inclusive. paletteSize is the amount of values that will be generated.
               # The smallest useful paletteSize is 3, as it will return [color1, color1MixedWithColor2, color2]
        palette = [color1]
        colorDifference = [ color1[0] - color2[0], color1[1] - color2[1], color1[2] - color2[2] ]

        Rstep = (color1[0] - color2[0]) / (paletteSize -1)
        Gstep = (color1[1] - color2[1]) / (paletteSize -1)
        Bstep = (color1[2] - color2[2]) / (paletteSize -1)

        for i in range(1,paletteSize):
            palette.append((color1[0] - Rstep*i, color1[1] - Gstep*i, color1[2] - Bstep*i))

        palette.append(color2)

        return palette

def createColorGrid(resolution, color1, color2, color3, color4):        # build a new colorGrid using a different process than above. colors are RGB format. For a 1D color fade set pairs of colors
                                      # like (255,0,0) (255,0,0) (0,255,255) (0,255,255). Colors are ordered from top left corner and follow corners clockwise.
        colorArray = [resolution]   # the first value in colorGrid is always a tuple stating the resolution.
        leftColumn = colorMix(color1,color4,resolution[1])
        rightColumn = colorMix(color2,color3,resolution[1])

        for i in range(0,resolution[1]):                                                                  # color processing goes from top left to top right, then down a row and repeat
                colorArray.append(colorMix(leftColumn[i],rightColumn[i],resolution[0]))
        return colorArray


def drawColorGrid(colorGrid, rect):    # input a colorGrid array. This will draw the set of color tiles decided by the colorGrid you pass into it
    colorGridStorage.fill((255,255,255))
    iCounter = 0
    for i in colorGrid:

        jCounter = 0
        if isinstance(i[0], int):   # the first value in colorGrid is the [x,y] resolution. we need to ignore it and move on to the rest
            continue

        for j in i:
            rectX = (rect[0] + round( jCounter * (rect[2]/colorGrid[0][0])))
            rectY = rect[1] + round(iCounter * rect[3]/colorGrid[0][1])
            rectWidth = round(rect[2]/colorGrid[0][0])
            rectHeight = round(rect[3]/colorGrid[0][1])
            pygame.draw.rect(colorGridStorage, j, (rectX,  rectY, rectWidth, rectHeight))
            jCounter += 1
        iCounter +=1
    windowSurface.blit(colorGridStorage, (rect[0], rect[1]))

要绘制新的渐变,首先使用 createColorGrid(resolution, color1, color2, color3, color4) 以特定分辨率构建颜色块数组。低分辨率看起来就像游戏 I Love Hue 中的东西。获得 colorGrid 变量后,将其插入 drawColorGrid(colorGrid, rect)。这将采用 colorGrid 数组并将其 blit 到屏幕上给定的矩形内。在这种情况下,屏幕表面被命名为 windowSurface。

我是一个相当新的程序员,所以上面的代码肯定有一些优化。如果您愿意,请将它们指出给我,但这段代码非常适合我正在做的应用程序。它似乎足够流畅,每秒至少生成 20 个随机渐变并将其 blit 到全屏,这比我需要的要多得多。