【问题标题】:Pygame: managing collisions when creating 20 randomly placed objectsPygame:在创建 20 个随机放置的对象时管理碰撞
【发布时间】:2019-11-01 05:42:35
【问题描述】:

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

这行得通。有点。一些精灵仍会在新位置与其他精灵重叠。因此,我决定使用while 循环而不是if 来继续移动它们,直到不再有碰撞:

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 个,并且由于某种原因有些仍然重叠。

【问题讨论】:

    标签: python pygame


    【解决方案1】:

    大概是这样的:

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

    【讨论】:

    • 谢谢!这行得通。比我尝试做的要简单得多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    相关资源
    最近更新 更多