Drawing an area or portion of a sprite by using Group class in Pygame

I'm trying to draw an area or portion of a sprite using the Group class from the sprite module.

So I have this class to handle my sprite:
(...and yes, pygame is already imported.)

class Sprite(pygame.sprite.Sprite):
    def __init__(self, player):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load(player)
        self.image = pygame.transform.scale(self.image, (300, 75))

        startPoint = (100, 500)
        self.rect = self.image.get_rect()
        self.rect.bottomleft = (startPoint)

Then, I upload the sprite using:

someFile = Sprite(join('res', 'file.png'))
spriteGroup = pygame.sprite.RenderUpdates(someFile)

Finally, I draw it by using spriteGroup.draw(source)

My problem, however, is that I want to draw only a small area or portion of the original file image. Now, I know that using Surface.blit() I can pass an optional area rectangle representing a smaller portion of the source Surface to draw.

The Group sub-class RenderUpdates has a draw() method, so it does not accept this kind of parameters... also, Surface.blit() (even if I could use it) is not an option since blit() expects coordinates to draw the source, but I already defined these in my class from above.

So... How could I pass arguments such as (0, 0, 75, 75) to represent the firsts x and y, width and height, respectively, of my sprite to draw only that portion?

Upvotes: 2

Views: 895

Answers (2)

Lee HoYo
Lee HoYo

Reputation: 1267

I find a way to solve it. Actually, the set_clip() method does not work. Here is my way using image.subsurface doc.

subsurface()  
    create a new surface that references its parent
    subsurface(Rect) -> Surface

In your code, you can try the following to just draw Rect(0,0,75,75).

class Sprite(pygame.sprite.Sprite):
    def __init__(self, player):
        pygame.sprite.Sprite.__init__(self)

        self.original = pygame.image.load(player)
        self.original = pygame.transform.scale(self.image, (300, 75))
        self.image = self.original.subsurface(Rect(0, 0, 75, 75))
        self.rect = self.image.get_rect()

Then, updateself.image and self.rect inside of your update function.

Upvotes: 1

Remolten
Remolten

Reputation: 2682

Here is what I would suggest.

  1. Inside of your __init__ function, store the image in 2 variables.

    # Stores the original image
    self.ogimage = pygame.image.load(player)
    self.ogimage = pygame.transform.scale(self.image, (300, 75))
    # Stores the image that is displayed to the screen
    self.image = self.ogimage
    
  2. Then, inside of an update function: set a clip on the original image, get that new image, and store it in image (the one that is automatically drawn to the screen).

    def update(self):
        self.ogimage.set_clip(pygame.Rect(0, 0, 100, 100))
        self.image = self.ogimage.get_clip()
    

Your sprite's image is now size 100x100, as measured from the origin of the original image. You can fiddle with the pygame.Rect inside of set_clip to get the image you want.

Upvotes: 1

Related Questions