如何在 pygame 中仅检测一次两个对象之间的碰撞?
How can I detect collision between two objects only once in pygame?
在我的游戏中,我有一群鱼 (10)。每条鱼都有一条视线(它们前面的弧形物体)。有鲨鱼,它们是食肉动物(它们在房间内随机移动)。每条鱼在开始时都被分配了一个智能编号。当一条鲨鱼进入鱼的视线时,我希望这条鱼只有在他的智力值大于随机生成的数字时才改变他的方向(或者至少以最佳方向离开)。
问题是,当我尝试执行此操作并且鲨鱼进入鱼的视线时,pygame 一直检测到碰撞,因此 python 一直生成随机数。例如,一条鱼的智力水平可能很低,但仍然有很高的概率从鲨鱼手中逃脱,因为 python 一直在检测碰撞,并且它有很多次尝试通过障碍物。对于那个例子,我实际上希望鱼在鲨鱼在视线范围内时很可能不会改变方向。
理想情况下,我希望 python 检测一次碰撞,当然,如果鲨鱼再次穿过视线,则再次检测一次。
这是我的代码,不知道它有多大帮助:
class RedFish(pygame.sprite.Sprite):
def __init__(self, newDNA):
pygame.sprite.Sprite.__init__(self)
self.direction = random.uniform(0, math.pi*2)
self.speed = 2
self.intelligence = 100
def update(self):
self.rect.x -= math.sin(self.direction) * self.speed
self.rect.y -= math.cos(self.direction) * self.speed
for shark in sharks:
if pygame.sprite.collide_mask(arcsList[self.arcIndex], shark):
temp = random.randrange(400)
if (temp < self.intelligence):
self.direction = self.direction*-1
谢谢!
您可以存储鱼 "saw" 的最后一条鲨鱼,并在更新循环的每次迭代中进行比较。
- 如果鱼再次看到同一条鲨鱼,不重新计算。
- 如果鱼看到另一条鲨鱼,重新计算并记住那条鲨鱼。
- 如果它没有看到鲨鱼,重置它的"memory"。
注意:为了让这个例子尽可能简单,我特意省略了很多计算代码。
class RedFish(pygame.sprite.Sprite):
def __init__(self, newDNA):
self.last_shark_seen = None
def update(self):
# track how many sharks we have collisions with
shark_collisions = 0
for shark in sharks:
if pygame.sprite.collide_mask(arcsList[self.arcIndex], shark):
shark_collisions += 1
if shark != self.last_shark_seen:
self.last_shark_seen = shark
# calculate new direction here
break
# no collisions means no sharks seen, reset the fish's memory
self.last_shark_seen = None
您需要跟踪何时看到了鲨鱼,或者看到了哪条鲨鱼。基本上更新碰撞检测器的频率是更新位置的十分之一(或第 12 或第 100)。
或者,一旦一条鱼没有看到鲨鱼,它就完蛋了,所以您可以将该列表添加到它看到但未能避免的鲨鱼列表中(以防它看到另一条鲨鱼),然后当您更新时可以通过列表说为了改变方向,一条鱼必须击败随机数生成器并且还没有输给鲨鱼
你可以尝试不同的随机分布,也许是向左倾斜的东西,所以即使一条笨鱼多次尝试,组合概率仍然很低
此外,如果您尝试模拟 "real" 条鱼,有些鱼的反应可能会较慢,但它们仍然有多次机会。
也许你可以缩短弧线?
在我的游戏中,我有一群鱼 (10)。每条鱼都有一条视线(它们前面的弧形物体)。有鲨鱼,它们是食肉动物(它们在房间内随机移动)。每条鱼在开始时都被分配了一个智能编号。当一条鲨鱼进入鱼的视线时,我希望这条鱼只有在他的智力值大于随机生成的数字时才改变他的方向(或者至少以最佳方向离开)。
问题是,当我尝试执行此操作并且鲨鱼进入鱼的视线时,pygame 一直检测到碰撞,因此 python 一直生成随机数。例如,一条鱼的智力水平可能很低,但仍然有很高的概率从鲨鱼手中逃脱,因为 python 一直在检测碰撞,并且它有很多次尝试通过障碍物。对于那个例子,我实际上希望鱼在鲨鱼在视线范围内时很可能不会改变方向。
理想情况下,我希望 python 检测一次碰撞,当然,如果鲨鱼再次穿过视线,则再次检测一次。
这是我的代码,不知道它有多大帮助:
class RedFish(pygame.sprite.Sprite):
def __init__(self, newDNA):
pygame.sprite.Sprite.__init__(self)
self.direction = random.uniform(0, math.pi*2)
self.speed = 2
self.intelligence = 100
def update(self):
self.rect.x -= math.sin(self.direction) * self.speed
self.rect.y -= math.cos(self.direction) * self.speed
for shark in sharks:
if pygame.sprite.collide_mask(arcsList[self.arcIndex], shark):
temp = random.randrange(400)
if (temp < self.intelligence):
self.direction = self.direction*-1
谢谢!
您可以存储鱼 "saw" 的最后一条鲨鱼,并在更新循环的每次迭代中进行比较。
- 如果鱼再次看到同一条鲨鱼,不重新计算。
- 如果鱼看到另一条鲨鱼,重新计算并记住那条鲨鱼。
- 如果它没有看到鲨鱼,重置它的"memory"。
注意:为了让这个例子尽可能简单,我特意省略了很多计算代码。
class RedFish(pygame.sprite.Sprite):
def __init__(self, newDNA):
self.last_shark_seen = None
def update(self):
# track how many sharks we have collisions with
shark_collisions = 0
for shark in sharks:
if pygame.sprite.collide_mask(arcsList[self.arcIndex], shark):
shark_collisions += 1
if shark != self.last_shark_seen:
self.last_shark_seen = shark
# calculate new direction here
break
# no collisions means no sharks seen, reset the fish's memory
self.last_shark_seen = None
您需要跟踪何时看到了鲨鱼,或者看到了哪条鲨鱼。基本上更新碰撞检测器的频率是更新位置的十分之一(或第 12 或第 100)。
或者,一旦一条鱼没有看到鲨鱼,它就完蛋了,所以您可以将该列表添加到它看到但未能避免的鲨鱼列表中(以防它看到另一条鲨鱼),然后当您更新时可以通过列表说为了改变方向,一条鱼必须击败随机数生成器并且还没有输给鲨鱼
你可以尝试不同的随机分布,也许是向左倾斜的东西,所以即使一条笨鱼多次尝试,组合概率仍然很低
此外,如果您尝试模拟 "real" 条鱼,有些鱼的反应可能会较慢,但它们仍然有多次机会。
也许你可以缩短弧线?