首页 > 解决方案 > Pygame 中的多个显示对象

问题描述

我了解 Pygame 中不可能有多个窗口:Pygame 中的多个显示

但是,是否可以有多个显示对象,而实际上只有一个显示给用户?

例如,假设我有以下代码,它显示 2 个绿色圆圈和 2 个红色三角形:

import pygame

WIDTH, HEIGHT = 800, 600
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
FPS = 60
BLACK = (0, 0, 0)
GREEN = (0, 128, 0)
RED = (255, 0, 0)


def draw_window():

    # Set display background
    WIN.fill(BLACK)  
    
    # Draw shapes
    pygame.draw.circle(surface=WIN, center=(400, 300), radius=20, color=GREEN)
    pygame.draw.polygon(surface=WIN, points=((410, 270), (460, 320), (390, 290)), color=RED)
    pygame.draw.circle(surface=WIN, center=(200, 150), radius=30, color=GREEN)
    pygame.draw.polygon(surface=WIN, points=((180, 190), (200, 140), (190, 270)), color=RED)
    
    # Update display
    pygame.display.update() 


def main():

    clock = pygame.time.Clock()
    run = True
    while run:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
        draw_window()

在此处输入图像描述

如果我想将像素数据导出到一个 numpy 数组,并计算每种颜色的出现次数,我可以使用pygame.surfarray.pixels2dnp.unique 来实现

data = pygame.surfarray.pixels2d(WIN)
unique, counts = np.unique(data, return_counts=True)
print(dict(zip(unique, counts)))

它返回每种颜色的像素数:

{0: 474303, 32768: 3380, 16711680: 2317}

但是,假设我想计算 4 个形状中每一个的像素数(而不是向用户显示的每种颜色),我可以简单地为每个形状分配一个唯一的颜色,例如在下面的代码中,这会给我我需要什么(即 4 个形状中的每一个的像素数)。但这样做时,我向用户显示了“错误”的颜色(即他们应该只看到绿色和红色,而不是绿色红色、黄色和蓝色)。

是否可以创建单独的“隐藏”版本的绘图(例如,为分析目的使用不同的颜色),这些版本与用户的显示分开?我知道我在 Pygame 中不能有多个窗口,但我想知道是否仍然可以创建多个显示对象——实际上只有一个显示给用户?

我想一种解决方法可能是仅为单个帧绘制每个“隐藏”版本(即,当我导出到 numpy 数组时),但这似乎不是一个非常优雅的解决方案。当隐藏的绘图暂时显示时,用户可能会注意到突然的“闪烁”,这将是一个糟糕的用户体验。

有一个更好的方法吗?

import pygame
import numpy as np

WIDTH, HEIGHT = 800, 600
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
FPS = 60


BLACK = (0, 0, 0)
GREEN = (0, 128, 0)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
BLUE = (0, 0, 255)


def draw_window():

    # Set display background
    WIN.fill(BLACK)

    # Draw shapes
    pygame.draw.circle(surface=WIN, center=(400, 300), radius=20, color=GREEN)
    pygame.draw.polygon(surface=WIN, points=((410, 270), (460, 320), (390, 290)), color=RED)
    pygame.draw.circle(surface=WIN, center=(200, 150), radius=30, color=YELLOW)
    pygame.draw.polygon(surface=WIN, points=((180, 190), (200, 140), (190, 270)), color=BLUE)

    # Update display
    pygame.display.update()


def main():

    clock = pygame.time.Clock()
    run = True
    count_colours = True
    while run:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
        draw_window()

        while count_colours:  # Run once only
            data = pygame.surfarray.pixels2d(WIN)
            unique, counts = np.unique(data, return_counts=True)
            print(dict(zip(unique, counts)))
            count_colours = False


if __name__ == "__main__":
    main()

输出:

{0: 474303, 255: 1256, 32768: 867, 16711680: 1061, 16776960: 2513}

在此处输入图像描述

标签: pythonnumpypygame

解决方案


推荐阅读