• 12
• 12
• 9
• 10
• 13

# Issues with enemy class

This topic is 815 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

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)

----Inside while loop----
----Draws the enemies----
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.

##### Share on other sites
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. Edited by Satharis

##### Share on other sites

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.

##### Share on other sites
    player.baddies = baddie_sprite_list
player.friendly = goodie_sprite_list

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

# --- Game logic should go here
all_sprites_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)

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.