colisión de pared de sprite de pygame

Estoy trabajando en un juego de plataformas en python y pygame. El código completo se puede encontrar en ” https://github.com/C-Kimber/FBLA_Game “. El problema que tengo es con la colisión entre el jugador sprite y los sprites de pared, específicamente las esquinas. Cuando el jugador presiona la tecla de movimiento del hacha y salta, el jugador no se mueve o se atasca. Aquí está la muestra de colisión:

def wallCollisions(self): block_hit_list = pygame.sprite.spritecollide(self, self.walls, False) for block in block_hit_list: if self.rect.bottom >= block.rect.top and self.rect.bottom  block.rect.left: self.rect.bottom = block.rect.top self.yvel = 0 self.onGround = True self.jumps = 1 elif self.rect.top = block.rect.bottom - 15: # Moving up; Hit the bottom side of the wall self.rect.top = block.rect.bottom self.yvel = 0 if self.rect.right >= block.rect.left and self.rect.right  block.rect.top+15: self.rect.right = block.rect.left#+1 self.xvel = 0 elif self.rect.left = block.rect.right - 15: # Moving left; Hit the right side of the wall self.rect.left = block.rect.right#-1 self.xvel = 0 = block.rect.right#-1 self.xvel = 0 

He incluido imágenes sobre lo que está pasando y lo que quiero. introduzca la descripción de la imagen aquí

He intentado otros métodos, como el uso de la velocidad como factores determinantes de colisión, pero esto es lo que está funcionando mejor hasta ahora. Si pudieras proporcionar una solución sería muy apreciado.

Gracias al usuario perezoso! La pregunta que él vinculó me dio una claridad muy necesaria. Me tomó un poco pero lo implementé. Creé una función para la colisión.

 def wallColl(self, xvel, yvel, colliders): for collider in colliders: if pygame.sprite.collide_rect(self, collider): if xvel > 0: self.rect.right = collider.rect.left self.xvel = 0 if xvel < 0: self.rect.left = collider.rect.right self.xvel = 0 if yvel < 0: self.rect.bottom = collider.rect.top self.onGround = True self.jumps = 3 self.yvel = 0 if yvel > 0: self.yvel = 0 self.rect.top = collider.rect.bottom 

Y luego los llamo en mi función de actualización.

 def update(self): self.rect.x += self.xvel # self.walls is an array of sprites. self.wallColl(self.xvel, 0, self.walls) self.rect.y -= self.yvel self.onGround = False self.wallColl(0, self.yvel, self.walls) self.wallCollisions() if self.otherplayers != None: self.playerCollisions() # Gravity if self.onGround == False: self.yvel-=.0066*self.mass self.boundries(highbound, lowbound, leftbound, rightbound) self.down = False 

El uso real en mi juego hace que la usabilidad sea casi perfecta. Aunque no es 100%, esta no es una respuesta perfecta.

La forma más fácil de manejar las colisiones con las paredes es mover el jugador recto o sprite a lo largo del eje x, verificar si colisiona con una pared y luego establecer su self.rect.right = wall.rect.left si se está moviendo hacia la right o self.rect.left = wall.rect.right si se está moviendo hacia la izquierda. Después haces lo mismo con el eje y. Debe hacer el movimiento por separado, de lo contrario no sabría la dirección y cómo restablecer la posición del rect.

 import pygame as pg from pygame.math import Vector2 class Player(pg.sprite.Sprite): def __init__(self, x, y, walls): super().__init__() self.image = pg.Surface((30, 50)) self.image.fill(pg.Color('dodgerblue1')) self.rect = self.image.get_rect(center=(x, y)) self.pos = Vector2(x, y) # Position vector. self.vel = Vector2(0, 0) # Velocity vector. self.walls = walls # A reference to the wall group. def update(self): self.pos += self.vel self.wall_collisions() def wall_collisions(self): """Handle collisions with walls.""" self.rect.centerx = self.pos.x for wall in pg.sprite.spritecollide(self, self.walls, False): if self.vel.x > 0: self.rect.right = wall.rect.left elif self.vel.x < 0: self.rect.left = wall.rect.right self.pos.x = self.rect.centerx self.rect.centery = self.pos.y for wall in pg.sprite.spritecollide(self, self.walls, False): if self.vel.y > 0: self.rect.bottom = wall.rect.top elif self.vel.y < 0: self.rect.top = wall.rect.bottom self.pos.y = self.rect.centery class Wall(pg.sprite.Sprite): def __init__(self, x, y, w, h): super().__init__() self.image = pg.Surface((w, h)) self.image.fill(pg.Color('sienna1')) self.rect = self.image.get_rect(topleft=(x, y)) def main(): screen = pg.display.set_mode((640, 480)) clock = pg.time.Clock() all_sprites = pg.sprite.Group() walls = pg.sprite.Group() wall = Wall(100, 200, 300, 30) wall2 = Wall(230, 70, 30, 300) walls.add(wall, wall2) all_sprites.add(wall, wall2) player = Player(300, 300, walls) all_sprites.add(player) done = False while not done: for event in pg.event.get(): if event.type == pg.QUIT: done = True keys = pg.key.get_pressed() if keys[pg.K_w]: player.vel.y = -3 elif keys[pg.K_s]: player.vel.y = 3 else: player.vel.y = 0 if keys[pg.K_a]: player.vel.x = -3 elif keys[pg.K_d]: player.vel.x = 3 else: player.vel.x = 0 all_sprites.update() screen.fill((30, 30, 30)) all_sprites.draw(screen) pg.display.flip() clock.tick(30) if __name__ == '__main__': pg.init() main() pg.quit() 
 elif self.rect.top <= block.rect.bottom and self.rect.top >= block.rect.bottom - 15: # Moving up; Hit the bottom side of the wall self.rect.top = block.rect.bottom self.yvel = 0 

¿No yvel estar configurado en un número positivo para que suba?