所以我在写一个游戏。以下是碰撞检测的工作原理;有一个不可见的网格,对象(或者更确切地说,它们的引用)根据它们的位置从单元格中添加和删除。碰撞比较仅在同一单元格中的对象之间进行。
引用存储在set
每个单元所拥有的 Python 中。它必须是一个集合。当检测到碰撞时,将其存储在Collision
具有三个属性的对象中;碰撞的两个物体和发生碰撞的时间。当考虑到所有冲突时,它们会按时间排序,然后进行处理。
这是单个细胞用来检查碰撞的循环;
#grid.collisions is a list of recorded collisions, and self.objects is the set
#of objects currently in this cell.
for i in self.objects:
for j in self.objects:
if id(i) != id(j) and pygame.sprite.collide_rect(i, j):
grid.collisions.append(Collision(i, j))
问题是,这会比较相同的两个对象两次;如果我们有一个 set {1, 2, 3, 4}
,我们会比较(1, 2)
和 (2, 1)
。不仅如此,这些重复的比较还被添加到冲突的总列表中,从而破坏了整个系统!
我知道我不能索引集合,这意味着我不能做像for j in range(i, len(self.objects))
wherei
和j
are both integers 这样的事情。 如何绕过此限制以确保同一集合中的两个对象不会被比较两次? 我无法移除这些集合中的对象;只有当对象离开网格单元时,它们才会被移除。
由于每帧都会处理这些冲突,因此我宁愿避免创建新对象(实际代码不会Collisions
像示例那样创建新对象,我只是为了便于阅读而对其进行了简化)。我可以删除重复的比较,但是将每个碰撞与其他碰撞进行比较将是很多开销。