'Hitbox not centering on the player rect? [duplicate]
Making a platformer and the player class has following code. I have created the hitbox from original rect with a -30 reduced width, but it still creates the hitbox in the topleft of the rect. I tried adding the hitbox center to rect center in the update method but it is not working.
Is it something to do with the rect having a pos parameter which passes into the level class? I can't seem to figure this one out, please help. Does the hitbox need to have this paramter instead?
class Player(Character):
def __init__(self, pos, groups, obstacle_sprites, create_run_particles, create_jump_particles, player_shoot):
super().__init__(groups)
self.display_surf = pygame.display.get_surface()
# animation setup
self.import_assets()
self.vel = pygame.math.Vector2()
self.state = 'idle'
self.facing = 1
self.frame_index = 0
self.frame_rate = 0.2
self.image = self.animations['idle'][self.frame_index]
self.rect = self.image.get_rect(topleft = pos)
self.hitbox = self.rect.inflate(-30, 0)
def input(self):
if not self.hold:
keys = pygame.key.get_pressed()
# move input
if keys[pygame.K_RIGHT]:
self.vel.x = 1
self.facing = 1
elif keys[pygame.K_LEFT]:
self.vel.x = -1
self.facing =-1
else:
self.vel.x = 0
if keys[pygame.K_DOWN]:
self.crouched = True
elif keys[pygame.K_UP] and self.grounded:
self.crouched = False
self.jump()
# elif self.on_wall and self.hang_cooldown >= 1 and self.hang_cooldown <=
if keys[pygame.K_z] and not self.grounded and self.hang_cooldown < HANG_TIME:
self.grab_wall = True
self.hang_cooldown += 1
else:
self.grab_wall = False
def jump(self):
self.vel.y = - JUMP_HEIGHT
self.create_jump_particles()
def x_collisions(self):
for sprite in self.obstacle_sprites.sprites():
if sprite.hitbox.colliderect(self.hitbox):
if self.vel.x > 0:
self.vel.x = 0
self.hitbox.right = sprite.hitbox.left
if self.grab_wall == True and self.vel.y > 0:
self.vel.y = -4
self.on_wall = True
self.x_collided = True
if self.hitbox.centerx < sprite.hitbox.top:
self.hitbox.bottomright == sprite.hitbox.midtop
if self.vel.x < 0:
self.vel.x = 0
self.hitbox.left = sprite.hitbox.right
if self.grab_wall == True and self.vel.y > 0:
self.vel.y = -4
self.on_wall = True
self.x_collided = True
if self.hitbox.centerx < sprite.hitbox.top:
self.hitbox.bottomleft == sprite.hitbox.midtop
def y_collisions(self):
for sprite in self.obstacle_sprites.sprites():
if sprite.hitbox.colliderect(self.hitbox):
if self.vel.y > 0:
self.hitbox.bottom = sprite.hitbox.top
self.vel.y = 0
self.grounded = True
elif self.vel.y < 0:
self.hitbox.top = sprite.hitbox.bottom
self.vel.y = 0
if self.vel.y < 0 or self.vel.y > 1:
self.grounded = False
def update(self):
self.input()
self.get_state()
self.animate('loop')
self.cooldowns()
if self.hold:
self.state = 'facing'
else:
self.hitbox.x += self.vel.x * self.speed
self.rect.center = self.hitbox.center
self.can_wallslide()
self.x_collisions()
self.gravity()
self.y_collisions()
Solution 1:[1]
Solved. Giving the tile sprites a hitbox attribute too and creating the hitbox width gives desired result providing I leave the player hitbox at 0.
I am now worried my tiles are effectively 'smaller' and my player is same size? This could cause issues with smaller sprites slotting between the gaps?
Advice would be great!
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 | Matt |
