Reputation: 1
I want to try making a platform game with pygame
.
For some reason, if I check only x or y collisions, everything works fine, but as soon as I check them both every time my player hits the ground or the ceiling, it just teleports on the side of the block. I tried a few print statements to verify if a collision happened at all, and it didn't if both collision checks are active as soon the player hits the ground without checking for collision it teleports on the side.
This is my code, collisions are handled with the collision_x()
and collision_y()
methods:
# Get player input
def get_player_input(self):
global do_move, player_speed_y, player_speed_x
do_move = True
key = pygame.key.get_pressed()
if key[pygame.K_d] and do_move:
self.player.move_ip(player_speed_x, 0)
self.pos_0_x = self.player.x + player_speed_x
elif key[pygame.K_a] and do_move:
self.player.move_ip(-player_speed_x, 0)
self.pos_0_x = self.player.x - player_speed_x
elif key[pygame.K_s] and do_move:
self.player.move_ip(0, player_speed_y)
self.pos_0_y = self.player.y + player_speed_y
elif key[pygame.K_w] and do_move:
self.player.move_ip(0, -player_speed_y)
self.pos_0_y = self.player.y - player_speed_y
# Get collisions with the player on x
def collisions_x(self):
global do_move, player_speed_x
self.map_gen()
for sprite in self.tiles.sprites():
if sprite.rect.colliderect(self.player):
if self.player.x > self.pos_0_x: # Check if player is colliding on his left side
do_move = False
self.player.x = self.player.x + 1
self.player.y = self.pos_0_y
if self.player.x < self.pos_0_x: # Check if player is colliding on his right side
do_move = False
self.player.x = self.player.x - 1
self.player.y = self.pos_0_y
# Get collisions with the player on y
def collisions_y(self):
global do_move, player_speed_y
self.map_gen()
for sprite in self.tiles.sprites():
if sprite.rect.colliderect(self.player):
if self.player.y < self.pos_0_y: # Check if player is colliding on his bottom side
do_move = False
player_speed_y = 0
self.player.y = self.player.y - 1
if self.player.y > self.pos_0_y: # Check if player is colliding on his top side
do_move = False
self.player.y = self.player.y + 1
# Put the player on the screen
def update_player(self, surface):
self.get_player_input()
self.collisions_x()
self.collisions_y()
pygame.draw.rect(WIN, (200, 0, 0), self.player)
Upvotes: 0
Views: 81
Reputation: 1
At the end I partially managed to solve the issue. Now, collisions happen without problems. The only thing that I can't get to work right now is the fact that when the player hits the ground, for some unknown reason it can't go left anymore.
Here is the updated code:
This is the gravity function
def apply_gravity(self):
self.player.y += player_speed_y + 0.5 * gravity
The collisions_x() function handles x collisions
def collisions_x(self):
global player_speed_x
self.map_gen()
for sprite in self.tiles.sprites():
if self.player.colliderect(sprite):
if self.player.right > sprite.rect.right: # Check if player is colliding on his left side
self.player.left = sprite.rect.right
if self.player.left < sprite.rect.left: # Check if player is colliding on his right side
self.player.right = sprite.rect.left
The collisions_y() function handles y collisions (at the moment only downwards)
def collisions_y(self):
global player_speed_y
for sprite in self.tiles.sprites():
if self.player.colliderect(sprite):
if player_speed_y > 0:
self.player.bottom = sprite.rect.top
And this function is then called in the loop to draw all on the screen
def update_player(self, surface):
self.get_player_input()
self.apply_gravity()
self.collisions_x()
self.collisions_y()
pygame.draw.rect(surface, (200, 0, 0), self.player)
Here is a short video the indicates what my problem looks like:
https://www.youtube.com/watch?v=IVRG0Th75YI
Upvotes: 0