Issues with enemy class

Started by
3 comments, last by Caraket 8 years, 3 months ago

class Enemy(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height, health, bullet):
        super().__init__()
        print("Created a new sprite:", id(self))

        self.width = width
        self.height = height

        self.image = pygame.Surface([self.width, self.height])
        self.image.fill(RED)

        self.rect = self.image.get_rect()

        self.rect.x = x
        self.rect.y = y

        self.change_x = 0
        self.change_y = 0

        self.bullet = bullet

        self.health = health
        self.grid = None

        self.alive = True

    def update(self):
        self.rect.x += self.change_x
        if self.rect.x >= SCREEN_WIDTH - self.width:
            self.change_x *= -1
        elif self.rect.x <= 0:
            self.change_x *= -1
        self.rect.y += self.change_y
        if self.rect.y >= SCREEN_HEIGHT:
            self.change_y *= -1
        elif self.rect.y <= 0:
            self.change_y *= -1

        bullet_hit_list = pygame.sprite.spritecollide(self, self.bullet, True)

        for bullet in bullet_hit_list:
            self.health -= 1

        if self.health <= 0:
            self.alive = False
        else:
            self.alive = True


			
 ----Main Program----
 ----Creates the enemies----
 width = 20
    height = 20
    margin = 5
    for row in range(3):
        for column in range(10):
            baddie = Enemy((margin + width) * column + margin, (margin + height) * row + margin,
                           width, height, 3, bullet_list)
            baddie_sprite_list.add(baddie)
			

----Inside while loop----
----Draws the enemies----
if baddie.alive == True:
    baddie_sprite_list.draw(screen) 

I am having an issue and was wondering if I could get some help. If more info is necessary please let me know.

I am trying to make a basic space shooter game using only primitive shapes for the time being.

Everything works fine until the player shoots an enemy sprite. Unless it is the last sprite rendered nothing happens. When the last sprite is shot 3 times(which is the amount of health each instance of enemy should have -1 for each bullet) all the enemy sprites disappear, however if you shoot at where they were the bullets still disappear like they hit an object.

Thank you for any help in advance.

Added full game below if needed.

Advertisement
I don't really python but from my layman's perspective you are making an Enemy and making baddie refer to it, then adding it to your list of baddies.

That means baddie will be set to the last enemy you made. You then check if baddie is alive before drawing all of the baddies in your list. You should actually be checking if each baddie is alive before drawing it instead of just checking the last one. For instance if you have 3 baddies if you shoot the first two, they'll always be drawn even if they die, and if you shoot the third one the entire group will appear to die.

Least that's what it looks like to me.

SIDENOTE: Usually objects in games(and enemies for that matter) should be separated logically from their visual representation. You'd be better off say, making an enemy class that has a position and dimensions, and then in your drawing code if they are all made of the same red square or whatever, you can just have one red square and draw it at the position of each baddie that is alive still. You don't need each enemy to have its own copy of a sprite.

As per usual in programming, the devil is in the details. Mind showing us the rest of the main program? In particular, the rest of the while loop.

As Satharis said, I think you are accessing the same (last created) Enemy at every step of the loop, but I also think that you never remove any Enemies from the baddie_sprite_list, so all the Enemies get rendered at each step of the while loop.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]


    player.baddies = baddie_sprite_list
    player.friendly = goodie_sprite_list

    player.baddie_sound = pygame.mixer.Sound("baddie.ogg")
    player.baddie_sound.set_volume(0.5)

    player.goodie_sound = pygame.mixer.Sound("goodie.ogg")
    player.goodie_sound.set_volume(1)

    # Loop until the user clicks the close button.
    done = False
    # -------- Main Program Loop -----------
    while not done:
        done = player.done
        # --- Main event loop
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True

            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_DOWN:
                    player.move(0, 3)
                elif event.key == pygame.K_UP:
                    player.move(0, -3)
                elif event.key == pygame.K_LEFT:
                    player.move(-3, 0)
                elif event.key == pygame.K_RIGHT:
                    player.move(3, 0)

            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_DOWN:
                    player.move(0, -3)
                elif event.key == pygame.K_UP:
                    player.move(0, 3)
                elif event.key == pygame.K_LEFT:
                    player.move(3, 0)
                elif event.key == pygame.K_RIGHT:
                    player.move(-3, 0)

            elif event.type == pygame.MOUSEBUTTONDOWN:
                # Fire a bullet if the user clicks the mouse button
                bullet = Bullet()
                # Set the bullet so it is where the player is
                bullet.rect.x = player.rect.x + 9
                bullet.rect.y = player.rect.y
                # Add the bullet to the lists
                bullet_list.add(bullet)
                all_sprites_list.add(bullet)

        # --- Game logic should go here
        all_sprites_list.update()
        baddie_sprite_list.update()
        # --- Drawing code should go here

        # First, clear the screen to white. Don't put other drawing commands
        # above this, or they will be erased with this command.
        screen.fill(WHITE)
        all_sprites_list.draw(screen)
        if baddie.alive == True:
            baddie_sprite_list.draw(screen)
        # baddie_sprite_list.draw(screen)

        texts(player.score, screen)

        # --- Go ahead and update the screen with what we've drawn.
        pygame.display.flip()

        # --- Limit to 60 frames per second
        clock.tick(60)

    # Close the window and quit.
    pygame.quit()

Here is the rest of the while loop and a little extra. I understand what you two are saying. I will give it a try to separate the object from the drawing like Satharis has suggested, and I will see what I can find on removing them from the 'Group' when they are killed. Thank you both for your help. I greatly appreciate it.

Well after messing around with it and trying some of the suggestions you mentioned I got it work close to the way I wanted. Thank you for all your help.

This topic is closed to new replies.

Advertisement