渲染曲面如果在其父级的范围内

问题描述

我正在为我正在使用的GUI库添加对滚动面板的支持添加到滚动面板中的UI组件仅应在其父级边界之内呈现。

Component

class Component(pg.sprite.Sprite):
    def __init__(self):
        self.original_image = pg.Surface((10,10),pg.SRCALPHA)
        self.image = self.original_image.copy()
        self.image.fill((0,0))
        self.rect = self.image.get_rect()

我考虑过遍历滚动容器中的所有元素,然后找到位于滚动框外部的元素。如果是这样,则对像素进行迭代,如果像素位于父对象之外,则将其设置为透明。

基本思路:


class ScrollBox(Container):
    def __init__(self):
        self.elements = []

    def add_scroll_element(self,scrl_element):
        self.elements.append(scrl_element)

    # Called whenever there has been a scroll-up or scroll-down
    def redraw_children(self):

        for element in self.elements:

            child_x,child_y = element.rect.x,element.rect.y
            parent_x,parent_y = element.parent_screen.rect.x,element.parent_screen.rect.y

            # Check if element is within bounds
            if (child_y + element.rect.height) >= (parent_y + element.parent_screen.rect.height):
                """
                Extra logic should be added here to determine if the pixel is within it's bounds
                """
                for x_px in range(element.rect.width):
                    for y_px in range(element.rect.height):
                        element.change_pixel(x_px,y_px,(0,0))

解决方案可以工作,但是在性能上并不是很好,因为有太多的像素正在循环通过。

我对pygame中的蒙版或颜色键不是很熟悉,因此我正在寻找一种更好的方法来实现此行为,也许可以使用其中一个概念。

解决方法

渲染元素时,使用pygame.Surface.clip()在目标表面上设置矩形裁剪区域,并在渲染子元素后重置裁剪区域:

class ScrollBox(Container):
    # [...]

    def redraw_children(self):

        for element in self.elements:
    
            window.clip(element.parent_screen.rect) # set clipping region for this element

            # render the element
            # [...]        

            window.clip(None) # reset clipping region