python - 创建一个 'frame' 隐藏除了它在 pygame 中包含的所有内容

标签 python pygame crop viewport

我刚开始使用 pyGame,我想创建一个框架来裁剪我在屏幕上显示的任何内容。 即独立于我的世界包含什么,这个框架应该涵盖除它包含的内容之外的所有内容。

将它想象成用于在 iphone 上裁剪图像的框架(见下图)。最终我想让框架具有交互性,这样我就可以移动它或改变它的大小,但暂时静态框架就可以了。 而且我不知道从哪里开始..感谢任何帮助!

[ example of cropping frame[1]

最佳答案

有多种方法可以做到这一点;一种方法是在整个屏幕上绘制一个黑色的 Surface,但在那个黑色的 Surface 中有一个“洞”。

创建该“洞”的一种简单方法是使用正确的 colorkey 简单地绘制一个矩形。什么是colorkey

When blitting this Surface onto a destination, any pixels that have the same color as the colorkey will be transparent

听起来很有用,所以让我们试一试:

import random
import pygame as pg

IMAGE = pg.Surface((50, 50), pg.SRCALPHA)
pg.draw.polygon(IMAGE, (240, 120, 0), [(0, 50), (25, 0), (50, 50)])

class Actor(pg.sprite.Sprite):

    def __init__(self, grp, bounds, pos):
        self._layer = 0
        pg.sprite.Sprite.__init__(self, grp)
        self.image = IMAGE
        self.rect = self.image.get_rect(center=pos)
        self.vec = pg.math.Vector2()
        # just a random directon for movement
        self.vec.from_polar((10, random.randrange(0, 360)))
        self.bounds = bounds

    def update(self):
        self.rect.move_ip(*self.vec)
        # try staying on screen
        if not self.bounds.contains(self.rect):
            self.vec.from_polar((10, random.randrange(0, 360)))

class Cursor(pg.sprite.Sprite):
    def __init__(self, grp, bounds):
        self._layer = 1000
        pg.sprite.Sprite.__init__(self, grp)
        self.image = pg.Surface((bounds.width, bounds.height))
        self.image.set_colorkey(pg.Color('yellow'))
        # we start with the entire screen black
        # if the screen should be fully visible at the start, we could use yellow instead
        self.image.fill(pg.Color('black'))
        self.rect = self.image.get_rect()
        # here we store the position of the mouse when we start drawing the hole
        self.start = None
        # here we store the entire rect of the hole so we can later move it around
        self.inner_rect = None

    def mousedown(self):
        self.start = pg.mouse.get_pos()

    def mouseup(self):
        self.start = None

    def move(self, rel):
        self.inner_rect.move_ip(rel)
        self.recreate()

    def update(self):
        if not self.start:
            return
        pos = pg.mouse.get_pos()
        p = pos[0] - self.start[0], pos[1] - self.start[1]
        self.inner_rect = pg.Rect(self.start, p)
        self.recreate()

    def recreate(self):
        # here we update our hole
        self.image.fill(pg.Color('black'))
        pg.draw.rect(self.image, pg.Color('yellow'), self.inner_rect)
        pg.draw.rect(self.image, pg.Color('white'), self.inner_rect, 2)

def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()
    all_sprites = pg.sprite.LayeredUpdates()
    cursor = Cursor(all_sprites, screen.get_rect())
    for _ in range(20):
        Actor(all_sprites, screen.get_rect(), (random.randrange(600), random.randrange(440)))

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            if event.type == pg.MOUSEBUTTONDOWN:
                if event.button == 1:
                    cursor.mousedown()
            if event.type == pg.MOUSEBUTTONUP:
                if event.button == 1:
                    cursor.mouseup()    
            if event.type == pg.MOUSEMOTION:
                if pg.mouse.get_pressed()[2]:
                    cursor.move(event.rel)

        all_sprites.update()
        screen.fill(pg.Color('darkblue'))
        all_sprites.draw(screen)

        pg.display.flip()
        clock.tick(60)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()

enter image description here

使用鼠标左键开始绘制框架,然后使用鼠标右键移动它。

如您所见,我们有一个黑色 Surface,颜色为黄色。当我们想让屏幕的一部分可见时,我们绘制一个黄色矩形,它又是透明的,使其下方的场景可见。

关于python - 创建一个 'frame' 隐藏除了它在 pygame 中包含的所有内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48545516/

相关文章:

python - 如何对 CSV 文件中的数据进行聚类(或分组)?

python - Pygame alpha 值

python - 如何使用 sprite 表中的多个图像创建行走角色

python - 通过坐标提取 PDF 页面的区域

android - 裁剪 Intent 问题

python - 我可以在 Python 中将 io.BytesIO() 流通过管道传输到 subprocess.popen() 吗?

python - 使用Python处理来自url的img

python - 移动度数 pygame

WPF-如何在 <Image> 控件中显示 ImageSource 的裁剪区域?

python - 使用 os.path.expandvars 时防止出现空环境变量