如何聚焦光线或如何仅在 pygame 中绘制窗口的某些圆形部分?
Posted
技术标签:
【中文标题】如何聚焦光线或如何仅在 pygame 中绘制窗口的某些圆形部分?【英文标题】:How do I focus light or how do I only draw certain circular parts of the window in pygame? 【发布时间】:2020-05-07 12:11:04 【问题描述】:为此,如果您熟悉它,请考虑一下 Super Mario Maker 2 中嘘级别中的黑暗模式。我正在尝试在角色周围创建一个圆形聚光灯,这也会使圆圈范围内的任何东西都可见(例如,站立的部分地板、敌人或现场的其他任何东西)。我的计划是先画圆圈/聚光灯,然后是场景,然后是角色。然后我希望任何没有被聚光灯突出显示的东西都被涂黑。
所以我的问题是:
有人知道如何填满整个屏幕,但圆圈内的内容除外?
【问题讨论】:
【参考方案1】:我建议一个解决方案,它结合了一个剪切区域pygame.Surface.set_clip
,并在中心绘制一个带有圆形透明区域的黑色矩形。
定义一个半径并创建一个半径为两倍的正方形pygame.Surface
。
radius = 50
cover_surf = pygame.Surface((radius*2, radius*2))
设置一个标识透明颜色的白色键(set_colorkey
)并在表面上绘制一个白色(透明)圆圈:
cover_surf.set_colorkey((255, 255, 255))
pygame.draw.circle(cover_surf, (255, 255, 255), (radius, radius), radius)
定义你想看到的圆形区域的中心(在下面的clip_center
)。
在主应用程序循环中,清除显示并设置剪切区域,绘制场景。在您更新剪辑区域中的显示绘制cover_surf
之前:
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()
最小示例: repl.it/@Rabbid76/PyGame-ClipCircularRegion-2
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
并设置白色颜色键:
cover_surf = pygame.Surface((400, 400))
cover_surf.set_colorkey((255, 255, 255))
将整个曲面填充为黑色,并在曲面上绘制白色圆圈:
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
:
while run:
# [...]
# draw transparent circle and update display
screen.blit(cover_surf, (0, 0))
pygame.display.flip()
最小示例: repl.it/@Rabbid76/PyGame-ClipCircularRegion-3
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 中绘制窗口的某些圆形部分?的主要内容,如果未能解决你的问题,请参考以下文章