如何仅在pygame中填充窗口的某些圆形部分? [英] How to fill only certain circular parts of the window in pygame?

查看:269
本文介绍了如何仅在pygame中填充窗口的某些圆形部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为此,如果您熟悉它,请考虑Super Mario Maker 2的boo级别中的黑暗模式.我正在尝试围绕角色创建一个圆形聚光灯,这还将使圆圈范围内的任何内容都可见(例如,站立的地板的一部分,敌人或场景中的其他任何物体).我的计划是先绘制圆/聚光灯,然后绘制场景,再绘制角色.然后,我希望将聚光灯下未突出显示的所有内容涂黑.

For this, if you're familiar with it, think the dark mode in the boo levels in Super Mario Maker 2. I'm trying to create a circular spotlight around the character that will also make anything within the circles range visible (eg part of the floor being stood on, an enemy or anything else from the scene). My plan to do that is to first draw the circle/spotlight, then the scene and then the character. Then I want anything not highlighted by the spotlight to be blacked out.

所以我的问题是:

除了圆圈中的内容之外,有人知道如何填充整个屏幕吗?

Does anybody know how to fill the entire screen with the exception of what's within the circle?

推荐答案

我建议一个解决方案,该解决方案结合了裁剪区域

I suggest a solution, which combines a clipping region pygame.Surface.set_clip and drawing a black rectangle with a circular transparent area in the center.

定义半径并创建正方形 pygame.Surface 半径的两倍.

Define a radius and create a square pygame.Surface with twice the radius.

radius = 50
cover_surf = pygame.Surface((radius*2, radius*2))

设置用于标识透明颜色的白色键( set_colorkey )并在表面上绘制一个白色(透明)圆圈:

Set a white color key which identifies the transparent color (set_colorkey) a nd draw a white (transparent) circle on the surface:

cover_surf.set_colorkey((255, 255, 255))
pygame.draw.circle(cover_surf, (255, 255, 255), (radius, radius), radius)

定义要查看的圆形区域的中心(在以下clip_center中).
在主应用程序循环中,清除显示并设置剪切区域,绘制场景.在裁剪区域中更新显示绘图cover_surf之前:

Define the center of the circular region which you want to see (in the following clip_center).
In the main application loop, clear the display and set the clipping region, the draw the scene. Before you update the display draw cover_surf in the clipping region:

while run:
    # [...]

    # clear screen and set clipping region
    screen.fill(0)    
    clip_rect = pygame.Rect(clip_center[0]-radius, clip_center[1]-radius, radius*2, radius*2)
    screen.set_clip(clip_rect)

    # draw the scene
    # [...]

    # draw transparent circle and update display
    screen.blit(cover_surf, clip_rect)
    pygame.display.flip()

请参见示例:

import pygame
pygame.init()
screen = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()

radius = 50
cover_surf = pygame.Surface((radius*2, radius*2))
cover_surf.fill(0)
cover_surf.set_colorkey((255, 255, 255))
pygame.draw.circle(cover_surf, (255, 255, 255), (radius, radius), radius)

run = True
while run:
    clock.tick(60)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    clip_center = pygame.mouse.get_pos()

    # clear screen and set clipping region
    screen.fill(0)    
    clip_rect = pygame.Rect(clip_center[0]-radius, clip_center[1]-radius, radius*2, radius*2)
    screen.set_clip(clip_rect)

    # draw the scene
    for x in range(10):
        for y in range(10):
            color = (255, 255, 255) if (x+y) % 2 == 0 else (255, 0, 0)
            pygame.draw.rect(screen, color, (x*50, y*50, 50, 50))

    # draw transparent circle and update display
    screen.blit(cover_surf, clip_rect)
    pygame.display.flip()


如果您需要多个圆形绘图区域,则创建一个 pygame.Surface.set_clip ,其大小与显示屏相同,并设置白色键:


If you want multiple circular drawing areas, then create a pygame.Surface.set_clip with the same size as the display and set whit color key:

cover_surf = pygame.Surface((400, 400))
cover_surf.set_colorkey((255, 255, 255))

用黑色填充整个表面并在表面上绘制白色圆圈:

Fill the entire surface black and draw white circles on the surface:

cover_surf.fill(0)
pygame.draw.circle(cover_surf, (255, 255, 255), (100, 100), 50)
pygame.draw.circle(cover_surf, (255, 255, 255), (300, 300), 70)

在更新显示之前,先在窗口中关闭cover_surf:

Blit the cover_surf on the window, before updating the display:

while run:
    # [...]

    # draw transparent circle and update display
    screen.blit(cover_surf, (0, 0))
    pygame.display.flip()

请参见示例:

import pygame
pygame.init()
screen = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()

cover_surf = pygame.Surface((400, 400))
cover_surf.set_colorkey((255, 255, 255))

px = [100, 200, 300]
dx = [1, 2, 3] 

run = True
while run:
    clock.tick(60)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    # create cover surface
    cover_surf.fill(0)
    for i in range(3):
        radius = 40 + i*20
        pygame.draw.circle(cover_surf, (255, 255, 255), (px[i], 100+(i*100)), radius)
        px[i] += dx[i]
        if px[i] < radius or px[i] > 400 - radius:
            dx[i] = -dx[i]

    # draw the scene
    for x in range(10):
        for y in range(10):
            color = (255, 255, 255) if (x+y) % 2 == 0 else (255, 0, 0)
            pygame.draw.rect(screen, color, (x*50, y*50, 50, 50))

    # draw transparent circle and update display
    screen.blit(cover_surf, (0, 0))
    pygame.display.flip()

这篇关于如何仅在pygame中填充窗口的某些圆形部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆