pygame.Surface.set_at() 如何在 for 循环中工作?

How does pygame.Surface.set_at() work in a for loop?

我正在为像素艺术编写代码,并将 Surface 另存为文件。但是 .set_at() 方法似乎不起作用。

class SelectRect:

    def __init__(self, xpos: int, ypos: int, w: int, h: int, rect_colour: tuple or list):
        self.rect = pygame.Rect(xpos, ypos, w, h)
        self.colour = rect_colour
        self.x = xpos
        self.y = ypos

    def render(self, surf):
        pygame.draw.rect(surf, self.colour, self.rect)


selected_rects = []
colour_rects = []

for i in range(15):
    colour_rects.append(SelectRect(512, 16 * i, TILE_SIZE, TILE_SIZE, colours[i]))


colour = WHITE

l_mouse_down = False
r_mouse_down = False

export_surf = pygame.Surface((32, 32))
export_surf.set_at((32, 32), CYAN)


rects = []
y = 0
for i in range(32):
    x = 0
    for o in range(32):
        rects.append(SelectRect(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE, None))
        x += 1
    y += 1


while True:

    screen.fill((32, 32, 32))

    mx, my = pygame.mouse.get_pos()

    if l_mouse_down:
        for rect in rects:
            if rect.rect.collidepoint(mx, my):
                if rect not in selected_rects:
                    selected_rects.append(rect)
                rect.colour = colour

        for rect in colour_rects:
            if rect.rect.collidepoint(mx, my):
                colour = rect.colour

    if r_mouse_down:
        for rect in rects:
            if rect.rect.collidepoint(mx, my):
                if rect in selected_rects:
                    selected_rects.remove(rect)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                pygame.quit()
                sys.exit()
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_e:    # todo, export in jpeg or png, sup2
                for rect in selected_rects:
                    export_surf.set_at((rect.x, rect.y), rect.colour)
            if event.key == pygame.K_c:
                selected_rects.clear()
            if event.key == pygame.K_f:
                for rect in rects:
                    selected_rects.append(rect)
                    rect.colour = colour
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                l_mouse_down = True
            if event.button == 3:
                r_mouse_down = True
        if event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                l_mouse_down = False
            if event.button == 3:
                r_mouse_down = False

    for rect in rects:
        if rect not in selected_rects:
            pygame.draw.rect(screen, (64, 64, 64), rect.rect)
        else:
            rect.render(screen)
    for rect in colour_rects:
        rect.render(screen)

    pygame.draw.rect(screen, colour, [512, 496, 16, 16])

    screen.blit(export_surf, (0, 0))

    pygame.display.update()
    clock.tick(framerate)

tl;博士:

我有一个矩形网格(实际上是 SelectRects),它存储一种颜色。当我导出时,我循环遍历这些矩形并将 export_surface 上的相应像素更改为该颜色。 这似乎不起作用。我试过画一个半径为1的圆,还是不行。

如果曲面的大小为32 x 32,则坐标(32, 32)越界。左上角像素坐标为(0, 0),右下角像素坐标为(31, 31):

export_surf.set_at((32, 32), CYAN)

export_surf = pygame.Surface((32, 32))
export_surf.set_at((31, 31), CYAN)

坐标(rect.x, rect.y)也越界了,因为rect指定了屏幕上的位置

您必须将 (rect.x, rect.y) 除以瓷砖的大小:

export_surf.set_at((rect.x // TILE_SIZE, rect.y // TILE_SIZE), rect.colour)

export_surf.set_at((rect.x, rect.y), rect.colour)