<p>我认为Maximilian Peters的基本思想是正确的,但是要删除的项应该保存在<code>set</code>而不是<code>list</code>中,以避免活动键多次出现在其中的问题。为了进一步加快碰撞检测过程,我将比较循环更改为使用<a href="https://docs.python.org/2/library/itertools.html#itertools.combinations" rel="nofollow">^{<cd3>}</a>生成器函数,以便只测试唯一的对象对</p>
<p>我还必须添加大量的脚手架,使它有可能在一个上下文中测试代码,就像你可能有它运行在</p>
<pre><code>from itertools import combinations
import math
CRITICAL_DIST = 2.0e0
class ObjectC(object):
def __init__(self, x, y, z):
self.posn = x, y, z
def __repr__(self):
return '{}({}, {}, {})'.format(self.__class__.__name__, *self.posn)
class Game(object):
def remove_collisons(self):
to_remove = set()
for key1, key2 in combinations(self.actives, 2):
# Calculate distance.
deltas = (
(self.actives[key2].posn[0] - self.actives[key1].posn[0])**2,
(self.actives[key2].posn[1] - self.actives[key1].posn[1])**2,
(self.actives[key2].posn[2] - self.actives[key1].posn[2])**2)
distance = math.sqrt(sum(deltas))
# Check for collision.
if distance <= CRITICAL_DIST:
to_remove |= {key1, key2} # both objects should be removed
if to_remove:
print('removing: {!r}'.format(list(to_remove)))
self.actives = {
k: v for k, v in self.actives.items() if k not in to_remove}
x1, y1, z1 = 0, 1, 2
x2, y2, z2 = 1, 2, 3
x3, y3, z3 = 2, 3, 1
actives = {'missile' : ObjectC(x1, y1, z1),
'target' : ObjectC(x2, y2, z2),
'clutter' : ObjectC(x3, y3, z3),
} # ...
game = Game()
game.actives = actives
print('before: {}'.format(game.actives))
game.remove_collisons()
print('after: {}'.format(game.actives))
</code></pre>
<p>输出:</p>
<pre class="lang-none prettyprint-override"><code> before: {'clutter': ObjectC(2, 3, 1), 'target': ObjectC(1, 2, 3), 'missile': ObjectC(0, 1, 2)}
removing: ['target', 'missile']
after: {'clutter': ObjectC(2, 3, 1)}
</code></pre>