纹理绘制的形状 - python pygame

Texturing drawn shapes - python pygame

我目前使用随机导入来创建五个随机 x、y 值并获取这些值并使用 pygame.draw.polygon () 命令绘制多边形。如果我有一个纹理正方形,我想在该形状的顶部应用而不是仅在 rgb 值上应用什么是最有效的方法?我想采用下面生成的多边形并且不对其形状进行硬编码,采用一般纹理正方形并将所有绿色制作为新纹理,就好像该形状是从纹理正方形中切出的一样。

import pygame,random
from pygame import*

height = 480
width = 640
#colors

red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
white = (255,255,255)
black = (0,0,0)

pygame.init()


points = [ ]

screen = pygame.display.set_mode((width,height))
pygame.display.set_caption("PlayBox")

r = random

for i in range(0,5):
    x = r.randrange(0,640)
    y = r.randrange(0,480)
    points.append([x,y])

running = True
while running == True:
    screen.fill(white)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            break

    pygame.draw.polygon(screen,green,points,0)
    pygame.display.update()      
pygame.display.update()

当然,一个选择是自己重新实现 "bucket fill" 算法, 并复制多边形内的像素。这将是很多工作,并且在纯 Python 中完成起来会很慢 - 尽管如此,它会让您进入图像处理的基础 http://en.wikipedia.org/wiki/Flood_fill

由于 Pygame 已经完成了繁重的工作,但只提供纯色填充, 方法是使用 pygame 的结果作为纹理的剪贴蒙版。不幸的是,这可能比它应该的更难。我希望我的样品在这里 对有相同需求的其他人有用。

Pygame 给了我们一些原语来操纵表面的颜色平面, 但他们绝对是低水平的。另一件事是这些原语需要 要安装的 numpy - 我不确定 Window 的 pyagames 安装程序是否包含它 - 否则人们 运行 你的项目必须被告知自己安装 numpy。

所以,要走的路是: 将你想要的纹理加载到一个表面上(为了减少头痛,一个相同尺寸的纹理 最终图像),以绘制要使用纹理绘制的形状 在遮罩表面中,具有 8bpp (B&W) - 作为透明度映射到 质地 - 他们使用 pygame 的 surfarray 实用程序将所有内容组合在一起:

# coding: utf-8

import random

import pygame

SIZE = 800,600

def tile_texture(texture, size):
    result = pygame.Surface(size, depth=32)
    for x in range(0, size[0], texture.get_width()):
        for y in range(0, size[1], texture.get_height()):
            result.blit(texture,(x,y))
    return result


def apply_alpha(texture, mask):
    """
    Image should be  a 24 or 32bit image,
    mask should be an 8 bit image with the alpha
    channel to be applied
    """
    texture = texture.convert_alpha()
    target = pygame.surfarray.pixels_alpha(texture)
    target[:] = pygame.surfarray.array2d(mask)
    # surfarray objets usually lock the Surface. 
    # it is a good idea to dispose of them explicitly
    # as soon as the work is done.
    del target
    return texture

def stamp(image, texture, mask):
    image.blit(apply_alpha(texture, mask), (0,0))


def main():
    screen = pygame.display.set_mode(SIZE)
    screen.fill((255,255,255))
    texture = tile_texture(pygame.image.load("texture.png"), SIZE)
    mask = pygame.Surface(SIZE, depth=8)
    # Create sample mask:
    pygame.draw.polygon(mask, 255, 
                        [(random.randrange(SIZE[0]), random.randrange(SIZE[1]) )
                         for _ in range(5)] , 0)

    stamp(screen, texture, mask)
    pygame.display.flip()
    while not any(pygame.key.get_pressed()):
        pygame.event.pump()
        pygame.time.delay(30)


if __name__ == "__main__":
    pygame.init()
    try:
        main()
    finally:
        pygame.quit()