Pygame: управление коллизиями при создании 20 случайно расположенных объектов - PullRequest
1 голос
/ 01 ноября 2019

Я работаю над простым моделированием с использованием Pygame. Для начала мне нужно создать 20 объектов и расположить их случайным образом по краям игрового окна, исключая верхний край. SingleCell класс управляет объектами и определяет рандомизированные начальные позиции для спрайтов.

Затем этот класс вызывается в основном классе моделирования для создания 20 спрайтов и добавления их в группу:

def _create_cell(self):
        """Create a single sprite and add it to group"""

        for cell in range(0,self.settings.cell_count):
            c = SingleCell(self)
            c_width, c_height = c.rect.size

            self.cells.add(c)

Это все работает нормально, но довольно много спрайтов в конечном итоге перекрываются. Чтобы исправить это после изучения документов для pygame.sprite, я решил использовать pygame.sprite.spritecollideany() в цикле, чтобы проверить, не сталкиваются ли какие-либо из спрайтов в группе, и переместить их либо горизонтально, либо вертикально по ширине или высоте соответственно. +1 пиксель:

def _check_overlapping_cells(self):
        """Check cells group for collisions based on rect"""

        for cell in self.cells:
            if pygame.sprite.spritecollideany(cell, self.cells,
                                           collided=None) != 'None':
                #If the collision happens along the vertical boundary
                #move the sprite down by 1 height +1 pixel
                if cell.rect.x == 0 or cell.rect.x == (
                        self.settings.screen_width - cell.rect.width):
                    cell.rect.y += (cell.rect.height + 1)

                #If the collision along horizontal edge then update x-coord
                #by sprite width +1 pixel
                elif cell.rect.y == 0:
                    cell.rect.x += (cell.rect.width + 1)

Это сработало. Вроде, как бы, что-то вроде. Некоторые из спрайтов будут по-прежнему перекрывать других в своих новых местах. Поэтому вместо if я решил использовать цикл while, чтобы продолжать перемещать их, пока не останется больше столкновений:

def _check_overlapping_cells(self):
        """Check cells group for collisions based on rect"""

        for cell in self.cells:
            while pygame.sprite.spritecollideany(cell, self.cells,
                                           collided=None) != 'None':

К сожалению, это приводит к тому, что сим вступает в бесконечный циклперемещение спрайтов вокруг.

Я немного сбит с толку относительно того, как сделать это правильно. Любой совет?

РЕДАКТИРОВАТЬ: С тех пор я попробовал другой подход, пытаясь проверить столкновения, когда спрайт создается путем изменения метода _create_cell, так что теперь это выглядит так:

def _create_cell(self):
        """Create a single cell and add it to group"""

        for cell in range(0,self.settings.cell_count):
            c = SingleCell(self)
            c_width, c_height = c.rect.size

            if pygame.sprite.spritecollideany(c, self.cells,
                                           collided=None) != 'None':
                #If the collision happens along the vertical boundary
                #move the sprite up by 1 height +1 pixel
                if c.rect.x == 0 or c.rect.x == (
                        self.settings.screen_width - c.rect.width):
                    c.rect.y += (-c.rect.height - 1)
                    self.cells.add(c)

                #If the collision along horizontal edge then update x-coord
                #by sprite width +1 pixel
                elif c.rect.y == (self.settings.screen_height - c.rect.height):
                    c.rect.x += (c.rect.width + 1)
                    self.cells.add(c)

            elif pygame.sprite.spritecollideany(c, self.cells,
                                           collided=None) == 'None':
                self.cells.add(c)

Но этот способ приводит к созданию менее 20 спрайтов, а некоторые по-прежнему перекрываются.

1 Ответ

2 голосов
/ 01 ноября 2019

Возможно, что-то вроде этого:

def _create_cell(self):
    """Create a single cell and add it to group"""

    for cell in range(0,self.settings.cell_count):
        c = SingleCell(self)

        while spritecollideany(c, self.cells):
            c = SingleCell(self)

        c_width, c_height = c.rect.size
        self.cells.add(c)

По сути, цикл while продолжает генерировать новые ячейки, пока не найдет тот, который не сталкивается ни с одним в self.cells. Конечно, это невозможно, тогда оно будет зациклено навсегда. Вы можете добавить счетчик и прервать его, если он попытается сделать это слишком много раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...