0

I'm trying to make it so then when an enemy collides with the player, a single life is lost and the player is positioned at the center of the screen. It works about half of the time, but the other half of the time two or three lives are lost from one collision.

def collide(self):
        for enemy in enemies:
            if ((robot.hitbox[0] < enemy.x + 16 < robot.hitbox[0] + robot.hitbox[2]) or (robot.hitbox[0] < enemy.x - 16 < robot.hitbox[0] + robot.hitbox[2])) and ((robot.hitbox[1] < enemy.y + 16  < robot.hitbox[1] + robot.hitbox[3]) or (robot.hitbox[1] < enemy.y - 16  < robot.hitbox[1] + robot.hitbox[3])):
                robot.alive = False
                robot.x = 400
                robot.y = 300
                for enemy in enemies:
                    enemies.remove(enemy)
                robot.lives -= 1
                robot.alive = True

This is a function under the class Enemy which is called inside of the Enemy's draw function, which is called in the while loop.

while running:
    ## add if robot.alive == True into loop
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False 

    userInput = pygame.key.get_pressed()

    if len(enemies) <= 3:
        randSpawnX = random.randint(32, 768)
        randSpawnY = random.randint(77, 568)
        if (robot.x - 100 <= randSpawnX <= robot.x + 100) or (robot.y - 100 <= randSpawnY <= robot.y + 100):
            randSpawnX = random.randint(32, 768)
            randSpawnY = random.randint(77, 568)
        else:
            enemy = Enemy(randSpawnX, randSpawnY)
            enemies.append(enemy)

    if robot.alive == True:     
        for enemy in enemies:
            enemy.move()
        robot.shoot()
        robot.movePlayer(userInput)

    drawGame()

Could anyone help me figure out why this is occurring? I believe it's because multiple collisions are registering but since I move the robot to the middle of the screen as soon as the first hit is registered and before the lives are lost, why is this happening?

  • 1
    This looks like some brand of [debouncing](https://en.wikipedia.org/wiki/Switch#Contact_bounce), and you want to set a time window in which more damage can occur. – ti7 Apr 20 '21 at 17:40
  • 1
    Please read about [`pygame.Rect.colliderect`](https://www.pygame.org/docs/ref/rect.html) and *[How do I detect collision in pygame?](https://stackoverflow.com/questions/29640685/how-do-i-detect-collision-in-pygame/65064907#65064907) – Rabbid76 Apr 20 '21 at 17:43
  • @ti7 Must be since using the pygame.Rect.colliderect didn't solve it. How would I go about implementing this? Threading? – Charlie McHenry Apr 22 '21 at 01:14

1 Answers1

0

Read How do I detect collision in pygame? and use pygame.Rect / colliderect() for the collision detection.

Read How to remove items from a list while iterating? and iterate through a copy of the list.

If you encounter a collision, it is not enough to change the player's x and y attributes. You also need to change the hitbox. Additionally break the loop when a collision is detected:

def collide(self):
    robot_rect = pygame.Rect(*robot.hitbox)
    for enemy in enemies[:]:
        enemy_rect = pygame.Rect(enemy.x, enemy.y, 16, 16)
        if robot_rect.colliderrect(enemy_rect):
            enemies.remove(enemy)
            robot.x, robot.y = 400, 300
            robot.hitbox[0] = robot.x
            robot.hitbox[1] = robot.y
            robot.lives -= 1
            break
Rabbid76
  • 202,892
  • 27
  • 131
  • 174