0

Is there a way to pass the special_flags argument to Group.draw so that it calls the .blit method with those flags? I've tried just passing it as a keyword argument like this:

group.draw(surface, special_flags=pygame.BLEND_SOURCE_ALPHA)

but it gives this error:

Traceback (most recent call last):
  File "C:\Users\MarciAdam\PycharmProjects\pygame_stuff_1\main.py", line 394, in <module>
    group.draw(surface, special_flags=pygame.BLEND_RGBA_MAX)
TypeError: draw() got an unexpected keyword argument 'special_flags'

I know I could do something like this:

for sprite in group.sprites():
    surface.blit(sprite.image, sprite.rect, special_flags=pygame.BLEND_SOURCE_ALPHA)

but I would need to duplicate a lot of the pygame code for the more complicated group types eg. LayeredUpdates.

MarcellPerger
  • 405
  • 3
  • 13

2 Answers2

0

Short answer:

What you want to do is not possible unless you implement it yourself.

You cannot pass that flag to pygame.sprite.Group.draw, because that function has only 1 argument (Also see What does pygame.sprite.Group() do):

draw(Surface) -> List[Rect]


Suggestions:

The only way is to draw the sprite with a "for" loop. I suggest to write a function for this or implement your own MyGroup class derived from pygame.sprite.Group:

class MyGroup(pygame.sprite.Group):
    def __init__(self, *args):
        super().__init__(*args) 
    def draw(self, surface, special_flags=0):
        for sprite in self:
            surface.blit(sprite.image, sprite.rect, special_flags = special_flags)
group = MyGroup()
group.draw(surface, special_flags=pygame.BLEND_RGBA_MAX)

If you want to do the same for pygame.sprite.LayeredUpdates or pygame.sprite.RenderUpdates, you have to implement all the drawing features of these objects yourself.


A completely different solution is to use pygame.sprite.DirtySprite. This class is derived from pygame.sprite.Sprite and has an additional blendmode attribute which is its the special_flags argument of blit.

class MySprite(pygame.sprite.DirtySprite):
    def __init__(self):
        super().__init__() 
        self.dirty = 2
        self.blendmode = pygame.BLEND_RGBA_MIN
        # [...]

Note, DirtySprite only works with pygame.sprite.LayeredDirty and all sprites in the group must be of this type.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • How would I do this with `pygame.sprite.LayeredUpdates` or `pygame.sprite.RenderUpdates`? Because I don't really want to copy out the entire source code of those `draw` functions unless I really have to. – MarcellPerger Feb 19 '23 at 11:16
  • @MarcellPerger You have to implement the layered update features all by yourself. There is no other way. You want a completely new feature, so you have to implement it. So the answer is: what you want to do is not possible unless you implement it yourself. – Rabbid76 Feb 19 '23 at 11:17
  • @MarcellPerger [`pygame.sprite.DirtySprite`](https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.DirtySprite) might be a solution for you. However, this is a completely different approach. – Rabbid76 Feb 19 '23 at 11:28
0

Update

It works in pygame version 2.3.0 now, see the documentation.
For older pygame versions see Rabbid76's answer.

MarcellPerger
  • 405
  • 3
  • 13