I'm new to python and pygame and am trying to build a very simple "game" (it's more of a test for me to figure things out) in which you move a character around the screen and he can collide with walls and things. Everything is broken up into 32x32 tiles and the player is 32x64. This means that when his head hits a wall his feet are 2 tiles away and I've been trying to get it so that he's only 1 away, ie. I'm after a 32x32 hitbox starting at x=0, y=32 on the player image.
Do I need to create a separate rect to deal with this and if so how would I go about implementing it? Any help would be greatly appreciated.
Here's the code for my player class so far, hopefully it's not too messy:
class Player(pygame.sprite.Sprite):
'''The Main Player Class'''
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self) #Call sprite initialiser
self.image, self.rect = load_image("char.png")
screen = pygame.display.get_surface()
self.area = screen.get_rect()
self.rect.x, self.rect.y = x, y
self.x, self.y = x, y
self.vx, self.vy = 0, 0
self.movespeed = 2
def update(self):
self._walk()
def _walk(self):
if self.vx != 0:
self._walk_single_axis(self.vx, 0)
if self.vy != 0:
self._walk_single_axis(0, self.vy)
def _walk_single_axis(self, vx, vy):
"normalise for diagonal movement if necessary"
if self.vx != 0 and self.vy !=0:
norm = 1/(2**0.5)
else:
norm = 1
"set new x and y positions"
self.x += vx * self.movespeed * norm
self.y += vy * self.movespeed * norm
self.rect.x, self.rect.y = self.x, self.y
"check for collisions with any walls"
for wall in walls:
if self.rect.colliderect(wall.rect):
if vx > 0: #collide with the left side of the wall
self.rect.right = wall.rect.left
self.x = self.rect.x
if vx < 0:
self.rect.left = wall.rect.right
self.x = self.rect.x
if vy > 0:
self.rect.bottom = wall.rect.top
self.y = self.rect.y
if vy < 0:
self.rect.top = wall.rect.bottom
self.y = self.rect.y
"bound the player within the screen edges"
if self.rect.x < self.area.left:
self.rect.x = 0
if self.rect.x > self.area.right-32:
self.rect.x = self.area.right-32
if self.rect.y < self.area.top:
self.rect.y = 0
if self.rect.y > self.area.bottom-64:
self.rect.y = self.area.bottom-64
self.x and self.y are there because applying the movement directly to self.rect.x and self.rect.y caused the character to move at different speeds depending on which diagonal direction he was travelling in. self.vx and self.vy just return either +1 or -1 depending on the direction of travel.