3

だから私はゲームを書いています。衝突検出の仕組みは次のとおりです。目に見えないグリッドがあり、オブジェクト (またはその参照) は、セルの位置に基づいてセルに追加および削除されます。衝突比較は、同じセル内のオブジェクト間でのみ行われます。

set参照は、各セルが所有する Python に格納されます。セットでなければなりません。衝突が検出されると、Collision3 つの属性を持つオブジェクトに保存されます。衝突した 2 つのオブジェクトと、衝突が発生した時刻。すべての衝突が考慮されると、それらは時間でソートされてから処理されます。

これは、個々のセルが衝突をチェックするために使用するループです。

#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))

問題は、これが同じ 2 つのオブジェクトを 2 回比較することです。セットがあれば{1, 2, 3, 4}、 と を比較(1, 2) (2, 1)ます。それだけでなく、これらの重複した比較が衝突の全リストに追加され、システム全体が壊れてしまいます!

セットにインデックスを付けることができないことはわかっています。つまり、for j in range(i, len(self.objects))whereijare both integers のようなことはできません。 この制限を回避して、同じセット内の 2 つのオブジェクトが 2 回比較されないようにするにはどうすればよいですか? これらのセット内のオブジェクトを削除できません。これらは、オブジェクトがグリッド セルを離れた場合にのみ削除されます。

これらの衝突はフレームごとに処理されるため、新しいオブジェクトを作成することは避けたいと思います (実際のコードはCollisionsサンプルのように新しいオブジェクトを作成しません。読みやすくするために単純化しました)。重複した比較を削除することもできますが、すべての衝突を他の衝突と比較すると、多くのオーバーヘッドが発生します。

4

3 に答える 3

7

セットのすべてのユニークな組み合わせを比較することが目標である場合は、次を利用できますitertools.combinations

from itertools import combinations

for i, j in combinations(self.objects, 2):
    if pygame.sprite.collide_rect(i, j):
        grid.collisions.append(Collision(i, j))

例:

aSet = set([1,2,3,4])
list(combinations(aSet, 2))
# [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]

combinations複数のインデックスと一時リストを管理するのに比べて、かなり効率的なジェネレーターを生成します

于 2012-07-24T05:03:30.550 に答える
1

リストを作ってみてはどうですか?

objects=list(self.objects)
for i in range(len(objects)):
  for j in range(i+1,len(objects)):
     if pygame.sprite.collide_rect(objects[i], objects[j]):
       grid.collisions.append(Collision(objects[i], objects[j]))

別の方法を次に示します。

objects=[]
for i in range(self.objects):
  for j in objects:
    if pygame.sprite.collide_rect(i, j):
      grid.collisions.append(Collision(i, j))
    objects.append(i)
于 2012-07-24T04:56:56.317 に答える
1

コードを次のように変更!=<ます。

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))
于 2012-07-24T05:14:33.813 に答える