Как работает overlaps в superwires?

Возникла проблема с пониманием метода overlaps в модуле superwires. Данный модуль используется для обучения по книге Майкла Доусона "Программируем на Python". И в процессе изучения я столкнулся с проблемой того что информации по этой функции крайне мало. Вопрос заключается в следующем, объявляя функцию внутри класса я должен ее указывать как self.overlaps передавая ей объект self и название класса с которым проверяю столкновения? Если так то вот код и он не работает так. Вот два класса в которых я проверяю столкновения: Класс блока

class Block(games.Sprite):

    image = games.load_image("Block.png")

    def __init__(self, x, y):

        super(Block, self).__init__(image = Block.image,
                                    x = x, y = y, is_collideable = True)

    def update(self):
        self.check_collision()

    """Проверка на столкновения, здесь и кроется проблема"""
    def check_collision(self):
        if self.overlaps(Pong()): #Вот здесь проблема, почему не срабатывает?
            self.destroy()

class Pong(games.Sprite):
    
    image = games.load_image("Ball.png")
    speed = 1

    def __init__(self):
        super(Pong, self).__init__(image = Pong.image,
                                   x = games.screen.width/2,
                                   y = 350, dx = Pong.speed, dy = Pong.speed,
                                   is_collideable = True)
        


    def __str__(self):
        return "Мяч для пинг-понга"

    def update(self):
        self.check_collision()
    def change_direction(self, side):
        if side == "bottom" or side == "top":
            self.dy = -self.dy
        elif side == "left" or side == "right":
            self.dx = -self.dx
    def check_collision(self):
        if self.x > games.screen.width or self.x < 0:
            self.change_direction("left")
        elif self.y < 0:
            self.change_direction("top")
        elif self.y > games.screen.height:
            game_over()

        for sprite in self.overlapping_sprites:
            if isinstance(sprite, Block):
                Player.score.value += 10
                if(self.top <= sprite.bottom and
                   self.top > sprite.x):
                    self.change_direction("bottom")
                elif(self.bottom < sprite.x and
                     self.bottom >= sprite.top):
                    self.change_direction("top")
                elif(self.right >= sprite.left and
                     self.right < sprite.y):
                    self.change_direction("left")
                elif(self.left >= sprite.right and
                     self.right < sprite.y):
                    self.change_direction("right")
            elif isinstance(sprite, Player):
                self.change_direction("top")

Если я правильно понимаю метод принимает два объекта и если они пересекаются то он возвращает True, но в моем случае шарик застревает в блоке и блок не уничтожается, то есть не происходит перехода в True. Когда я в скобках указываю self.overlaps(self, Pong()) то он выдает ошибку overlaps() takes 2 positional arguments but 3 were given. Объясните пожалуйста что я делаю не так, как этот метод работает и что ему нужно передавать?


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

Автор решения: CrazyElf
if self.overlaps(Pong())

Таким образом вы создаёте новый объект Pong и проверяете столкновение с ним. Это явно не то, что вам нужно. Скорее всего вам нужно создать управляющий объект более высокого уровня, который обычно называют GameObject. И вот в этом объекте вы создаёте блоки и проверяете коллизии:

class GameObject():

    def __init__(self):

        self.blocks = [
            Block(x1, y1),
            Block(x2, y2),
            ...
        ]
        self.pong = Pong()

    def update(self):
        # возможно, тут ещё нужно сначала вызвать `update`
        # у всех блоков и у pong, я не уверен кто их вызывает
        # и затем проверить коллизии всех блоков с шариком
        for block in self.blocks:
            block.check_collision(self.pong)

Ну а внутри block.check_collision уже проверяете так:

    def check_collision(self, pong):
        if self.overlaps(pong):
            self.destroy()

Как-то так должно всё получиться.

→ Ссылка