Skip to main content
 首页 » 编程设计

python之为什么 Surface.unlock 无法解锁表面以进行 blitting

2025年05月04日41mq0036

我正在尝试将 alpha 值的 numpy 数组应用于表面。我能够这样做,但是在这个操作之后表面仍然被锁定,所以我不能将表面 blit 到我的显示器。

下面是一个简单的测试用例,使用 alpha 数组,g,pickled here .

import pygame as pg 
 
pg.init() 
screen = pg.display.set_mode((600, 600)) 
 
s = pg.Surface((100, 100)).convert_alpha() 
s.fill((126, 126, 126))  # make it grey 
pxa = pg.surfarray.pixels_alpha(s)  # reference the alpha values 
 
pxa[::] = g  # g is the array of alpha values 
del pxa  # shouldn't deleting the array be enough to unlock the surface? 
s.unlock()  # explicitly unlock for good measure 
 
s.get_locked()  # returns True 

那么是什么给了?无论如何,我尝试将表面 blitting 到 screen,但是(可以预见)我收到关于 s 仍然被锁定的错误。

非常欢迎您的建议!

请您参考如下方法:

制作 Sprite 类并将值放入更新函数中。这样,数组将在函数范围内创建和销毁。这是一个示例,您可以通过按空格键使灰色 block 透明:

import pygame 
from pygame.locals import QUIT, KEYDOWN, K_ESCAPE, K_SPACE, SRCALPHA 
 
 
class Game(object): 
    def __init__(self): 
        pygame.init() 
        self.width, self.height = 800, 800 
        pygame.display.set_caption("Surfarray test") 
        self.screen = pygame.display.set_mode((self.width, self.height)) 
        self.background = pygame.Surface((self.width, self.height)) 
        self.background.fill((255, 255, 255)) 
        self.background.convert() 
        self.bar = pygame.Surface((200, 100)) 
        self.bar.fill((255, 0, 0)) 
        self.bar.convert() 
 
        self.sprite = pygame.sprite.GroupSingle() 
        self.sprite.add(CustomSprite(pygame.Rect(5, 5, 100, 100))) 
 
    def input(self): 
        for event in pygame.event.get(): 
 
            if event.type == QUIT: 
                return False 
 
            if event.type == KEYDOWN: 
                if event.key == K_ESCAPE: 
                    return False 
                if event.key == K_SPACE: 
                    # make bar transparent by pressing the space bar 
                    self.sprite.update() 
 
    def main(self): 
        while True: 
            if self.input() is False: 
                return False 
            self.draw() 
 
    def draw(self): 
        self.screen.blit(self.background, (0, 0)) 
        self.screen.blit(self.bar, (5, 5)) 
        self.sprite.draw(self.screen) 
        pygame.display.update() 
 
 
class CustomSprite(pygame.sprite.Sprite): 
    def __init__(self, rect): 
        pygame.sprite.Sprite.__init__(self) 
        self.rect = rect 
        # SRCALPHA flag makes the pixel format include per-pixel alpha data 
        self.image = pygame.Surface((rect.width, rect.height), SRCALPHA) 
        self.image.convert_alpha() 
        self.image.fill((126, 126, 126)) 
 
    # magic happens here 
    def update(self): 
        pxa = pygame.surfarray.pixels_alpha(self.image) 
        pxa[:] = 100  # make all pixels transparent 
 
if __name__ == "__main__": 
    game = Game() 
    game.main()