Search code examples
pythonpygamespritecollisiondetection

How can I detect collision between two objects only once in pygame?


In my game, I have a population of fish (10). Each fish has a line of sight (an arc object in front of them). There are sharks, which are predators (they are moving around the room randomly). Each fish is assigned an intelligence number at the beginning. When a shark enters in a fish' line of sight, I want the fish to reverse his direction (or at least get away in the best direction) only if his intelligence number is greater than a random generated number.

The issue is that when I try to implement this and the shark gets in the line of sight of the fish, pygame keeps detecting a collision, so python keeps generating a random number. For example, a fish might have a very low intelligence level, but still has a very high probability to escape from the shark because python keeps detecting the collision, and it has many tries to pass the bar. For that example, I'd actually want the fish to very likely not change directions when the shark is in the line of sight.

Ideally, I want python to detect the collision once, and of course detect again if the shark goes through the line of sight again a separate time.

Here is my code, don't know how much it'd help:

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

Thanks!


Solution

  • You need to track when the shark was seen, or which shark was seen. Basically update the collision detector one tenth (or 12th or 100th) as often as you update position.

    Or, once a fish fails to see a shark, it's doomed, so you can add that list to a list of sharks it's seen and failed to avoid (in case it sees another shark), then when you update you can just go through the list saying that in order to change direction, a fish must beat the random number generator and also not have lost to the shark already

    You could try a different random distribution, maybe something that skews left, so even if a dumb fish had multiple tries, the combined probability would still be low

    Then again, if you're trying to simulate "real" fish, some might be slower to react, but they still get multiple chances.

    Maybe you could shorten the arc?