Reputation: 23
Hello I'm working on getting my sideways shooter game up to speed. but I ran into a problem when I try to move the fleet of aliens down and to the left. I have set the self.rect.bottom >= screen_rect.bottom
. but this code is only responsive to my top row of aliens. I tried setting a number value instead but that does not give me the desired result. any help greatly appreciated.
this is my code for the aliens:
alien.py
def check_edges(self):
"""Return True if alien is at edge of screen."""
screen_rect = self.screen.get_rect()
if self.rect.bottom >= screen_rect.bottom or self.rect.top <= 0:
return True
def update(self):
"""Move the alien up or down."""
self.y += (self.settings.alien_speed *
self.settings.fleet_direction)
self.rect.y = self.y
and in alien_invasion.py
def _update_aliens(self):
"""
Check if the fleet is at an edge,
then update the positions of all aliens in the fleet.
"""
self._check_fleet_edges()
self.aliens.update()
def _create_fleet(self):
"""Create the fleet of aliens."""
# Create an alien and find the number of aliens in a row.
# Spacing between each alien is equal to one alien height.
alien = Alien(self)
alien_width = alien.rect.width
alien_height = alien.rect.height
# Determine the number of rows of aliens that fit on the screen.
ship_width = self.ship.rect.width
available_space_x = (self.settings.screen_width -
(2 * alien_width) + ship_width)
number_rows = available_space_x // (3 * alien_width)
available_space_y = self.settings.screen_height + (2 * alien_height)
number_aliens_y = available_space_y // (2 * alien_height)
# Create full fleet of aliens.
for alien_number in range(number_aliens_y):
for row_number in range(number_rows):
self._create_alien(alien_number, row_number)
def _create_alien(self, alien_number, row_number):
"""Create an alien and place it in the row."""
alien = Alien(self)
alien_width = alien.rect.width
alien_height = alien.rect.height
alien.rect.x = 1200 - (2 * alien_width) - (2 * alien.rect.width) * row_number
alien.y = alien_height + 2 * alien_height * alien_number
alien.rect.y = alien.y
self.aliens.add(alien)
def _check_fleet_edges(self):
"""Respond appropriately if any aliens have reached an edge."""
for alien in self.aliens.sprites():
if alien.check_edges():
self._change_fleet_direction()
break
def _change_fleet_direction(self):
"""Drop the entire fleet and change the fleet's direction"""
for alien in self.aliens.sprites():
alien.rect.x -= self.settings.fleet_left_speed
self.settings.fleet_direction *= -1
Upvotes: 2
Views: 309
Reputation: 23
So I stumbled my way to a solution eventually.
It works but I'm not sure it's the best way to do it.
I ended up keeping the
def _change_fleet_direction(self):
should I keep it as it's own helper function or could I included it in the def _set_fleet_direction(self, direction):
somehow?
I feel like the game is lagging a bit more then my original alien_invasion game.
Any tips?
This was the solution I ended up with:
def _check_fleet_edges(self):
screen_rect = self.screen.get_rect()
for alien in self.aliens.sprites():
if alien.rect.top <= screen_rect.top:
self._set_fleet_direction(1) # new direction is down
break
elif alien.rect.bottom >= screen_rect.bottom:
self._set_fleet_direction(-1) # new direction is up
break
for alien in self.aliens.sprites():
if alien.check_edges():
self._change_fleet_direction()
break
def _change_fleet_direction(self):
"""Moving the aliens left"""
for alien in self.aliens.sprites():
alien.rect.x -= self.settings.fleet_left_speed
def _set_fleet_direction(self, direction):
self.settings.fleet_direction = abs(self.settings.fleet_direction) *
direction
Upvotes: 0
Reputation: 211135
Your for
-loop breaks immediately after the 1st alien.
for alien in self.aliens.sprites(): if alien.check_edges(): self._change_fleet_direction() break
The break
statement must be in code block of the if
-statement. It's a matter of Indentation
for alien in self.aliens.sprites():
if alien.check_edges():
self._change_fleet_direction()
break
I recommend to make your code more robust. If an alien reaches the top, the new fleet direction should be downwards. If an alien reaches the bottom, the new fleet direction should be upwards.
Write a method _set_fleet_direction
instead of _change_fleet_direction
. The method has a direction
parameter that indicates the new direction. The argument has to be 1 for downwards and -1 for upwards. The new fleet_direction
can be calculated with the current absolute value (abs(x)
) multiplied by the new direction:
def _set_fleet_direction(self, direction):
self.settings.fleet_direction = abs(self.settings.fleet_direction) * direction
Set the direction dependent on the range check:
def _check_fleet_edges(self):
"""Respond appropriately if any aliens have reached an edge."""
screen_rect = self.screen.get_rect()
for alien in self.aliens.sprites():
if alien.top <= screen_rect.top:
self._set_fleet_direction(1) # new direction is down
break
elif alien.bottom >= screen_rect.bottom
self._set_fleet_direction(-1) # new direction is up
break
Upvotes: 1