如何在 pygame 中聚焦光线或如何仅绘制窗口的某些圆形部分? [英] How do I focus light or how do I only draw certain circular parts of the window in pygame?

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

问题描述

为此,如果你熟悉它,想想超级马里奥制造商 2 中嘘声级别的黑暗模式.我试图在角色周围创建一个圆形聚光灯,这也将使圆圈范围内的任何东西都可见(例如,站立的地板的一部分,敌人或场景中的任何其他东西).我的计划是先画圆圈/聚光灯,然后是场景,然后是角色.然后我希望聚光灯下没有突出显示的任何东西都被涂黑.

所以我的问题是:

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

解决方案

我提出了一个解决方案,它结合了一个裁剪区域

导入pygamepygame.init()屏幕 = pygame.display.set_mode((500, 500))时钟 = pygame.time.Clock()半径 = 50cover_surf = pygame.Surface((半径*2,半径*2))cover_surf.fill(0)cover_surf.set_colorkey((255, 255, 255))pygame.draw.circle(cover_surf, (255, 255, 255), (radius, radius), radius)运行 = 真运行时:时钟滴答(60)对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:运行 = 错误clip_center = pygame.mouse.get_pos()# 清屏并设置剪切区域屏幕填充(0)clip_rect = pygame.Rect(clip_center[0]-radius,clip_center[1]-radius,radius*2,radius*2)screen.set_clip(clip_rect)# 绘制场景对于范围内的 x(10):对于范围内的 y(10):颜色 = (255, 255, 255) if (x+y) % 2 == 0 else (255, 0, 0)pygame.draw.rect(屏幕,颜色,(x*50,y*50,50,50))# 绘制透明圆圈并更新显示screen.blit(cover_surf,clip_rect)pygame.display.flip()


如果你想要多个圆形绘图区域,那么创建一个

导入pygamepygame.init()屏幕 = pygame.display.set_mode((400, 400))时钟 = pygame.time.Clock()cover_surf = pygame.Surface((400, 400))cover_surf.set_colorkey((255, 255, 255))像素 = [100, 200, 300]dx = [1, 2, 3]运行 = 真运行时:时钟滴答(60)对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:运行 = 错误# 创建覆盖面cover_surf.fill(0)对于范围内的 i (3):半径 = 40 + i*20pygame.draw.circle(cover_surf, (255, 255, 255), (px[i], 100+(i*100)), radius)px[i] += dx[i]如果 px[i] <半径或 px[i] >400 - 半径:dx[i] = -dx[i]# 绘制场景对于范围内的 x(10):对于范围内的 y(10):颜色 = (255, 255, 255) if (x+y) % 2 == 0 else (255, 0, 0)pygame.draw.rect(屏幕,颜色,(x*50,y*50,50,50))# 绘制透明圆圈并更新显示screen.blit(cover_surf, (0, 0))pygame.display.flip()

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.

So my question is:

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.

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

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

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)

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()

Minimal example:

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()


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)

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()

Minimal example:

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天全站免登陆