本文介绍了为什么 Surface.unlock 无法解锁表面以进行 blitting?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 alpha 值的 numpy 数组应用于表面.我可以这样做,但此操作后表面仍保持锁定状态,因此我无法将表面闪烁到我的显示器上.

I'm trying to apply a numpy array of alpha values to a surface. I'm able to do so, but the surface remains locked after this operation such that I cannot blit the surface to my display.

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

Below is a simple test case, using the alpha array, 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 仍然被锁定的错误.

So what gives? I tried blitting the surface to screen anyway, but (predictably) I get an error about s still being locked.

欢迎提供建议!

推荐答案

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

Make a sprite class and put the values in an update function. This way, the array will be created and destroyed within the scope of the function. Here's an example in which you can make the grey block transparent by pressing the space bar:

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

这篇关于为什么 Surface.unlock 无法解锁表面以进行 blitting?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-26 05:44