Pygame animation now showing on screen
Question:
In my game there is an animation of "exploding" when the ship hits something and loses 1 hp. This is the code that triggers self.first_player_ship.explode()
:
def _first_player_ship_hit(self):
"""Respond to the first player ship being hit by an alien."""
if self.first_player_ship.exploding:
return
if self.stats.ships_left > 0:
self.first_player_ship.explode()
self.first_player_ship.shield_on = False
self.settings.thunder_bullet_count = 1
if self.settings.first_player_bullets_allowed > 1:
self.settings.first_player_bullets_allowed -= 2
self.stats.ships_left -= 1
self.first_player_ship.center_ship()
self.sb.prep_hp()
else:
self.stats.player_one_active = False
if self.stats.player_two_active:
self.first_player_bullets.empty()
else:
self.stats.game_active = False
pygame.mouse.set_visible(True)
The problem is that the animation works well until the player loses his last hp. The ship just disappears without the animation playing.
I suspect that it might have something to do with the update method in my game, when the ship loses all it’s hp becomes inactive, and when it’s inactive it’s not blitted on the screen anymore.
def _update_screen(self):
"""Update images on the screen, and flip to the new screen."""
if self.stats.player_one_active:
self.first_player_ship.blitme()
In the _first_player_ship_hit(self), I tried to put the first_player_ship.explode() before setting the inactive flag to False but it still didn’t work.
Link to game repo: https://github.com/KhadaAke/Alien-Onslaught
Answers:
Since I have found a solution for my problem, I will post it here.
I created these two methods (the ones for the other ship are similar):
def _thunderbird_ship_hit(self):
"""Respond to the Thunderbird ship being hit by an alien, bullet or asteroid."""
if self.stats.thunderbird_hp >= 0:
self._destroy_thunderbird()
self.thunderbird_ship.set_immune()
def _destroy_thunderbird(self):
"""Destroy the thunderbird ship then center it."""
self.thunderbird_ship.explode()
self.thunderbird_ship.state.shielded = False
self.settings.thunderbird_bullet_count = 1
if self.settings.thunderbird_bullets_allowed > 1:
self.settings.thunderbird_bullets_allowed -= 2
self.stats.thunderbird_hp -= 1
self.thunderbird_ship.center_ship()
self.score_board.create_health()
And I modified my method that draws the ships on screen like this to check if the ship’s hp is < 0 and is not in the exploding state before setting the alive state to False.
def _draw_game_objects(self):
"""Draw game objects and the score on screen."""
for ship in self.ships:
# Check the state of the Thunderbird and Phoenix ships and update their "alive" state.
if ship == self.thunderbird_ship:
health = self.stats.thunderbird_hp
else:
health = self.stats.phoenix_hp
if health < 0 and not ship.state.exploding:
ship.state.alive = False
# Draw the ships on screen only when alive.
if ship.state.alive:
ship.blitme()
In my game there is an animation of "exploding" when the ship hits something and loses 1 hp. This is the code that triggers self.first_player_ship.explode()
:
def _first_player_ship_hit(self):
"""Respond to the first player ship being hit by an alien."""
if self.first_player_ship.exploding:
return
if self.stats.ships_left > 0:
self.first_player_ship.explode()
self.first_player_ship.shield_on = False
self.settings.thunder_bullet_count = 1
if self.settings.first_player_bullets_allowed > 1:
self.settings.first_player_bullets_allowed -= 2
self.stats.ships_left -= 1
self.first_player_ship.center_ship()
self.sb.prep_hp()
else:
self.stats.player_one_active = False
if self.stats.player_two_active:
self.first_player_bullets.empty()
else:
self.stats.game_active = False
pygame.mouse.set_visible(True)
The problem is that the animation works well until the player loses his last hp. The ship just disappears without the animation playing.
I suspect that it might have something to do with the update method in my game, when the ship loses all it’s hp becomes inactive, and when it’s inactive it’s not blitted on the screen anymore.
def _update_screen(self):
"""Update images on the screen, and flip to the new screen."""
if self.stats.player_one_active:
self.first_player_ship.blitme()
In the _first_player_ship_hit(self), I tried to put the first_player_ship.explode() before setting the inactive flag to False but it still didn’t work.
Link to game repo: https://github.com/KhadaAke/Alien-Onslaught
Since I have found a solution for my problem, I will post it here.
I created these two methods (the ones for the other ship are similar):
def _thunderbird_ship_hit(self):
"""Respond to the Thunderbird ship being hit by an alien, bullet or asteroid."""
if self.stats.thunderbird_hp >= 0:
self._destroy_thunderbird()
self.thunderbird_ship.set_immune()
def _destroy_thunderbird(self):
"""Destroy the thunderbird ship then center it."""
self.thunderbird_ship.explode()
self.thunderbird_ship.state.shielded = False
self.settings.thunderbird_bullet_count = 1
if self.settings.thunderbird_bullets_allowed > 1:
self.settings.thunderbird_bullets_allowed -= 2
self.stats.thunderbird_hp -= 1
self.thunderbird_ship.center_ship()
self.score_board.create_health()
And I modified my method that draws the ships on screen like this to check if the ship’s hp is < 0 and is not in the exploding state before setting the alive state to False.
def _draw_game_objects(self):
"""Draw game objects and the score on screen."""
for ship in self.ships:
# Check the state of the Thunderbird and Phoenix ships and update their "alive" state.
if ship == self.thunderbird_ship:
health = self.stats.thunderbird_hp
else:
health = self.stats.phoenix_hp
if health < 0 and not ship.state.exploding:
ship.state.alive = False
# Draw the ships on screen only when alive.
if ship.state.alive:
ship.blitme()