'Pygame bounding rect is not on sprite center
I have a problem with pygame.
I'm just trying to understand collisions. I would like to implement a rectangle around my player with self.rect = self.image.get_bounding_rect() but the rectangle is off center and i cant find a way to center it on my player sprite.
This is what the rectangle looks like at the moment:
Here is my Player class:
import pygame
# Class Variable
player_sprite_group = pygame.sprite.Group()
class Player(pygame.sprite.Sprite):
def __init__(self, window_size, health, name):
pygame.sprite.Sprite.__init__(self)
self.image = self.load_character_sprites()
self.rect = self.image.get_bounding_rect()
self.health = health
self.current_state = "idle"
self.direction = "right"
self.name = name
self.rect.center = window_size[0] / 2, window_size[1] / 2
self.moving_speed = 6
self.x_moving_velocity = 0
self.y_moving_velocity = 0
self.add_player_to_sprite_group()
def load_character_sprites(self):
return pygame.image.load("../Assets/Hero Knight/Sprites/HeroKnight/Idle/HeroKnight_Idle_0.png")
def state(self, set_state, direction):
if direction == "right":
self.direction = "right"
if direction == "left":
self.direction = "left"
if set_state == "idle":
self.current_state = set_state
if set_state == "walking":
self.current_state = set_state
if set_state == "fight":
self.current_state = set_state
if set_state == "jump":
self.current_state = set_state
def collision(self):
pass
# player movement
def player_movement(self, keys_pressed):
if keys_pressed[pygame.K_w] or keys_pressed[pygame.K_s] or keys_pressed[pygame.K_a] or keys_pressed[pygame.K_d]:
self.state("walking", self.direction)
if keys_pressed[pygame.K_UP] or keys_pressed[pygame.K_w]:
self.rect.y -= self.moving_speed
if keys_pressed[pygame.K_DOWN] or keys_pressed[pygame.K_s]:
self.rect.y += self.moving_speed
if keys_pressed[pygame.K_LEFT] or keys_pressed[pygame.K_a]:
if self.direction != "left":
self.state("moving", "left")
self.image = pygame.transform.flip(self.image, True, False)
self.rect.x -= self.moving_speed
if keys_pressed[pygame.K_RIGHT] or keys_pressed[pygame.K_d]:
if self.direction != "right":
self.state("walking", "right")
self.image = pygame.transform.flip(self.image, True, False)
self.rect.x += self.moving_speed
def set_current_location(self):
pass
def update_player(self):
player_sprite_group.update()
def draw_player(self, screen):
pygame.draw.rect(screen, (255, 0, 255), self.rect)
player_sprite_group.draw(screen)
def add_player_to_sprite_group(self):
player_sprite_group.add(self)
And here is my my pygame file with its settings and game loop:
import pygame
import sys
from pygame.locals import *
from debug import debug
from player import Player
# clock implementation
clock = pygame.time.Clock()
# window name
pygame.display.set_caption("Dungeon crawler")
# Set the window size
window_size = [1200, 720]
# no frame window
window_frame_noframe = NOFRAME
# frame window
window_frame_frame = 0
# init the game window
screen = pygame.display.set_mode(window_size, window_frame_noframe, 32)
# create player object
player_one = Player(window_size, 100, "knight")
# test rect
test_rect = pygame.Rect(200, 300, 50, 50)
# game main loop
while True:
# clear screen
screen.fill((146, 244, 255))
# debugging methods
debug(clock, 10, 10)
debug(player_one.current_state, 30, 10)
debug(player_one.direction, 60, 10)
debug(player_one.rect, 90, 10)
# player movement
key_pressed = pygame.key.get_pressed()
player_one.player_movement(key_pressed)
# event loop
for event in pygame.event.get():
if event.type == QUIT:
# close the window and end the game
pygame.quit()
sys.exit()
# draw collision rect
pygame.draw.rect(screen, (255, 255, 255), test_rect)
# draw and update player
player_one.update_player()
player_one.draw_player(screen)
# show window
pygame.display.update()
# set fps to 60 with clock
clock.tick(60)
I hope you can help me with this problem
Solution 1:[1]
The top left of the rectangle returned by get_bounding_rect() is not (0, 0) and the size of the bounding rectangle is not the size of the image. When using the original image and the bounding rectangle, the offset of the bounding rectangle is not considered. You have to use the bounding rectangle to get a subsurface of the iamge:
class Player(pygame.sprite.Sprite):
def __init__(self, window_size, health, name):
pygame.sprite.Sprite.__init__(self)
self.image = self.load_character_sprites()
self.rect = self.image.get_bounding_rect()
self.image = self.image.subsurface(self.rect)
self.rect.center = window_size[0] / 2, window_size[1] / 2
# [...]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Rabbid76 |
