Pygame:创建20个随机放置的对象时管理碰撞

时间:2019-11-01 05:42:35

标签: python pygame

我正在使用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':

不幸的是,这导致SIM卡进入了一个看似永无止境的移动精灵的循环。

我对如何正确执行感到有些困惑。有什么建议吗?

编辑: 此后,我尝试了另一种尝试通过修改_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 个答案:

答案 0 :(得分:2)

也许是这样的:

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中的任何单元格都不冲突的单元格为止。当然,这是不可能的,然后它将永远循环。您可以添加一个计数器,如果尝试太多次则中止。