DulmievMusa
DulmievMusa

Reputation: 13

How to pin an image in the center of sprite rect

Sprite class. I wanted to make the hitbox of a square character smaller than the sprite itself, but I ran into a problem that I don't know how to pin the image in the middle. Is it possible to pin a picture for the Sprite class not at the rect's coordinates 0,0, but for example -20, -20 (so that the picture is in the middle)? Or is the only option is to create a second Rect for the hitbox? It's just inconvenient because you can't find an intersection with a group of sprites through a simple method because it only works with self.rect enter image description here

Upvotes: 1

Views: 155

Answers (1)

Rabbid76
Rabbid76

Reputation: 210880

This is not something that can be handled automatically with pygame.sprite.Sprite. Either you have to add a second rectangle (htibox) for collision detection and implement collision detection manually or you have to implement drawing the sprite and do it manually.

Howevver, if you have a large image with a small object or character sprite on it, you can find the bounds of the object pygame.Surface.get_bounding_rect (of course this works only if the area around the object or character is transparent):

hitbox = image.get_bounding_rect()

Also see How to get the correct dimensions for a pygame rectangle created from an image.

One option could be to get a subsurface of the original sprite with the actual boundaries of the character. This shrinks the image to the actual size of the character on the image. e.g.:

class Player(pygame.sprite.Sprite):
    def __init__(self, cx, cy, image):
        super().__init__() 
        self.rect = image.get_bounding_rect()
        self.image = image.subsurface(self.rect)
        self.rect.center = (cx, cy)

To pin an image in the center of a hit box, get the center of the pygame.Rect and the bounding rectangle of the image. Set the center of the bounding rectangle with the center of the image and use the bounding rectangle of the image to blit the image:

center = hitbox.center
image_rect = image.get_rect()
image_rect.center = center
screen.blit(image, image_rect)

This all can be written with one line of code:

screen.blit(image, image.get_rect(center = hitbox.center))

Minimal example:

import pygame

pygame.init()
screen = pygame.display.set_mode((200, 200))
clock = pygame.time.Clock()
image = pygame.Surface((100, 100))
image.fill("orange")
hitbox = pygame.Rect(0, 0, 50, 50)

run = True
while run:
    clock.tick(100)
    run = not any(e for e in pygame.event.get() if e.type == pygame.QUIT)
    hitbox.center = pygame.mouse.get_pos()
    screen.fill("white")
    screen.blit(image, image.get_rect(center = hitbox.center))
    pygame.draw.rect(screen, "yellow", hitbox)
    pygame.display.update()

Upvotes: 1

Related Questions