Home > Blockchain >  Is it possible to resize an instance of a class inheriting pygame Surface?
Is it possible to resize an instance of a class inheriting pygame Surface?

Time:02-04

I am trying to make GUI elements using pygame (I know it's odd, but they are to be used inside a pygame made game). Here is a very simplified piece of code of how a UI element class looks like in my code:


import pygame
from typing import Tuple


class UIElement(pygame.Surface):

    def __init__(self, size: Tuple[int, int]) -> None:
        super().__init__(size)

        self.children = {}

    def draw(self) -> None:
        ...

Note that the class is just an extension of the pygame.Surface class. Now, what I would like to do is make those elements resizable, for example if the size is not prior knowledge, implementing a method with this signature:


def resize(self, size: Tuple[int, int]) -> None:
    ...

However, pygame doesn't allow for Surface objects to be resized in-place, which forces me to create a new UIElement instance with the right size. I would like this new instance to be a copy of my first instance, except for the size of the pygame.Surface, and this new instance should replace the first one. How would I do it from within the first instance with my resize method?

I looked through the copy module, but it doesn't seem to fit my issue.

Furthermore, I know it may seem simpler to just add a surface attribute to my class, which would be holding the pygame.Surface object, and set a new value for this attribute when needed but this would force me to go through tremendous architecture redesign work and I would prefer to avoid it.

If you have any idea as how to fix my issue, I would appreciate it.

CodePudding user response:

No you can't. I suggest using the simple approach. UIElement should not be a subclass of pygame.Surface. The pygame.Surface object should only be an attribute of the UIElement. All your problems are caused by inheritance.

A pygame.Surface object cannot be resized. A Surface is just a proxy object for an internally managed, SDL surface object with immutable size. PyGame has no API to change the object under the hood. All you can do is to create a new Surface with a different size and use pygame.transform.scale() to set the content of the scaled Surface:

class UIElement(pygame.Surface):
    # [...]

    def resize(self, size):
        scaled_element = UIElement(size)
        pygame.transform.scale(self, size, scaled_element) 
        scaled_element.children = self.children
        return scaled_element 
  •  Tags:  
  • Related