问题描述
我正在为我正在使用的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