Обработка столкновений в pygame

Шарики летают по области экрана и сталкиваются со стенами. При столкновении со стеной шарик должен изменить направление движения. Всё хорошо, пока обрабатываются только столкновения с верхней стеной и левой стеной. Но стоит добавить обработку столкновений с нижней стеной и с правой - шарики перестают летать.

pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("My Game")
clock = pygame.time.Clock()

dots_sprites = pygame.sprite.Group()
walls_sprites = pygame.sprite.Group()


# WALLS
top_wall = Wall(0, 0, WIDTH, 5)
bot_wall = Wall(0, HEIGHT - 5, WIDTH-5, HEIGHT)     # !!!
right_wall = Wall(WIDTH - 5, 0, WIDTH, HEIGHT)      # !!!
left_wall = Wall(0, 0, 5, HEIGHT)
walls_sprites.add(top_wall, bot_wall, left_wall, right_wall)
# WALLS

# DOTS
dots = [Dot() for i in range(10)]
for dot in dots:
    dots_sprites.add(dot)
# DOTS

running = True

while running:
    clock.tick(FPS)
    for event in pygame.event.get():
        # check for closing window
        if event.type == pygame.QUIT:
            running = False
    for dot in dots_sprites.sprites():
        dot.update()
        if pygame.sprite.collide_rect(dot, left_wall):
            if isinstance(dot, Dot):
                dot.invert_speed_x()
        if pygame.sprite.collide_rect(dot, right_wall):
            if isinstance(dot, Dot):
                dot.invert_speed_x()
        if pygame.sprite.collide_rect(dot, top_wall):
            if isinstance(dot, Dot):
                dot.invert_speed_y()
        if pygame.sprite.collide_rect(dot, bot_wall):
            if isinstance(dot, Dot):
                dot.invert_speed_y()

    screen.fill(BLACK)
    dots_sprites.draw(screen), walls_sprites.draw(screen)
    pygame.display.flip()

pygame.quit()

Wall

class Wall(pygame.sprite.Sprite):
def __init__(self, x0, y0, x, y):
    pygame.sprite.Sprite.__init__(self)
    self.x0 = x0
    self.y0 = y0
    self.x = x
    self.y = y
    rect_width = self.x - self.x0
    rect_height = self.y - self.y0
    self.color = RED
    self.image = pygame.Surface([self.x, self.y], pygame.SRCALPHA)
    pygame.draw.rect(self.image, self.color, (self.x0, self.y0, rect_width,  rect_height))
    self.rect = self.image.get_rect()

Dot

class Dot(pygame.sprite.Sprite):
def __init__(self, speed=2, mass=10, size=25):
    pygame.sprite.Sprite.__init__(self)
    self.x = random.randint(size//2, WIDTH - size//2)
    self.y = random.randint(size//2, HEIGHT - size//2)
    self.start_speed = speed
    self.speed_x = self.start_speed * random.choice([-1, 1])
    self.speed_y = self.start_speed * random.choice([-1, 1])
    self.mass = mass
    self.size = size
    self.image = pygame.Surface([self.size, self.size], pygame.SRCALPHA)
    pygame.draw.circle(self.image, WHITE, (size // 2, size // 2), size // 2)
    self.rect = self.image.get_rect()
    self.rect.x, self.rect.y = self.x - size // 2, self.y - size // 2

def invert_speed_x(self):
    self.speed_x = -self.speed_x
def invert_speed_y(self):
    self.speed_y = -self.speed_y
def update(self):
    self.rect.x += self.speed_x
    self.rect.y += self.speed_y

Ответы (1 шт):

Автор решения: DisanD_08

Ну вот маленький кусок кода для отталкивания мячика от стен

def update(self):
        self.rect.x += self.speedx
        self.rect.y += self.speedy
        if self.rect.left > WIDTH:
            self.speedx -= 5#
        if self.rect.right < 0:
            self.speedx += 5#
        if self.rect.top > HEIGHT:
            self.speedy -= 5#
        if self.rect.bottom < 0:
            self.speedy += 5#

там где стоит "#", вы можете свободно менять значение цифр, это скорость мячика

Надеюсь смог вам помочь =)

→ Ссылка