Python learning notes - game project

Posted by randydg on Mon, 31 Jan 2022 01:23:10 +0100

Add alien row

To create an alien colony, you need to calculate how many lines the screen can hold and repeat the cycle of creating one line of aliens a corresponding number of times.
In order to calculate the number of rows that can be accommodated, we calculate the available vertical space by subtracting the screen height from the upper margin of the first row of Aliens (alien height), the height of the spacecraft, and the distance between the original alien population and the spacecraft (twice the alien height):

available_space_y = ai_settings.screen_height – 3 * alien_height – ship_height

This will leave a certain blank area above the ship to give players time to shoot aliens.
Leave a certain blank area below each line and set it to the height of aliens. To calculate the number of rows that can be accommodated, we divide the available vertical space by twice the alien height (similarly, if this calculation is wrong, we can find it immediately, and then adjust the spacing to a reasonable value).

number_rows = available_height_y / (2 * alien_height)

Once you know how many lines you can fit, you can repeat the code that creates one line:

def get_number_rows(ai_settings, ship_height, alien_height):
    """Calculate how many lines the screen can hold"""
    available_space_y = (ai_settings.screen_height -
                         (3 * alien_height) - ship_height)
    number_rows = int(available_space_y / (2 * alien_height))
    return number_rows

def create_alien(ai_settings, screen, aliens, alien_number, row_number):
    """Create an alien and place it on the current line"""
    alien = Alien(ai_settings, screen)
    alien_width = alien.rect.width
    alien.x = alien_width + 2 * alien_width * alien_number
    alien.rect.x = alien.x
    alien.rect.y = alien.rect.height + 2 * alien.rect.h * row_number
    aliens.add(alien)

def create_fleet(ai_settings, screen, ship, aliens):
    """Create alien groups"""
    # Create an alien and calculate how many aliens a row can hold
    # Alien spacing is alien width
    alien = Alien(ai_settings, screen)
    alien_width = alien.rect.width
    number_aliens_x = get_number_aliens_x(ai_settings, alien_width)
    number_rows = get_number_rows(ai_settings, ship.rect.height,
                                  alien.rect.height)

    # Create alien groups
    for row_number in range(number_rows):
        for alien_number in range(number_aliens_x):# Create an alien and add it to the current line
            create_alien(ai_settings, screen, aliens, alien_number,
                        row_number)

To calculate how many lines the screen can hold, we use the function get_ number_ The previous calculation of available is implemented in rows()_ space_ Y and number_ The rows formula.

In create_ In the definition of Fleet (), a formal parameter is added to store the ship object
alien_ invasion. Calling create_ in PY When fleet(), the actual parameter ship needs to be passed:

alien_invasion.py

# Create alien groups
gf.create_fleet(ai_settings, screen, ship, aliens)

Let aliens move

Next, let the alien crowd move to the right on the screen, hit the edge of the screen, move down a certain distance, and then move in the opposite direction. We will continue to move all aliens until all aliens are eliminated, an alien hits a spaceship, or an alien reaches the bottom of the screen. Let's let the aliens move to the right first.

Move aliens to the right

To move aliens, we will use alien Py and call it for every alien in the alien population.

First, add a setting to control the speed of Aliens:
settings.py

class Settings():
    """A class that stores all the settings of alien invasion"""
    def __init__(self):
        """Initialize game settings"""
        # screen setting
        self.screen_width = 1200
        self.screen_height = 800
        self.bg_color = (230, 230, 230)

        # Spacecraft settings
        self.ship_speed_factor = 1.5

        # Bullet setting
        self.bullet_speed_factor = 1
        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = 60,60,60
        
        # Alien settings
        self.alien_speed_factor = 1

Then, use this setting to implement update():
alien.py

    def update(self):
        """Move aliens to the right"""
        self.x += self.ai_settings.alien_speed_factor
        self.rect.x = self.x

alien_invasion.py

    # Game main loop
    while True:
        gf.check_events(ai_settings, screen, ship, bullets)
        ship.update()
        bullets.update()
        gf.update_aliens(aliens)
        gf.update_screen(ai_settings, screen, ship, aliens, bullets)

game_functions.py

def update_aliens(aliens):
    """Update the location of all aliens in the alien population"""
    aliens.update()

We call the method update() on the marshalling aliens, which will automatically call the method update() on each alien. If you run this game now, you will see the aliens move to the right and gradually disappear at the right edge of the screen.

Create settings that represent the direction of alien movement

Let's create a setting that allows aliens to hit the right edge of the screen and move down and then left.
settings.py

# Alien settings
        self.alien_speed_factor = 1
        self.fleet_drop_speed = 10
        # flee_ A direction of 1 indicates moving to the right, and a direction of - 1 indicates moving to the left
        self.fleet_diretion = 1

Set fleet_drop_speed specifies the speed at which the aliens move down when they hit the edge of the screen. It's good to separate this speed from the horizontal speed, so you can adjust the two speeds separately.

Check if aliens hit the edge of the screen

Now we need to write a method to check whether aliens hit the edge of the screen, and modify update() to make each alien move in the right direction.

    def check_edges(self):
        """If the alien is on the edge of the screen, return True"""
        screen_rect =self.screen.get_rect()
        if self.rect.right >= screen_rect.right:
            return True
        elif self.rect.left <= 0:
            return True

    def update(self):
        """Move aliens left or right"""
        self.x += (self.ai_settings.alien_speed_factor *
                        self.ai_settings.fleet_direction)
        self.rect.x = self.x

When aliens reach the edge of the screen, they need to move the whole group of aliens down and change their moving direction. We need to be on the game_functions.py makes major changes because we want to check here whether aliens have reached the left or right edge. To do this, we write the function check_fleet_edges() and change_fleet_direction() and update_aliens():
game_functions.py

def check_fleet_edges(ai_settings, aliens):
    """Response measures when aliens reach the edge"""
    for alien in aliens.sprites():
        if alien.check_edges():
            change_fleet_direction(ai_settings, aliens)
            break


def change_fleet_direction(ai_settings, aliens):
    """Move the whole group of aliens down and change their direction"""
    for alien in aliens.sprites():
        alien.rect.y += ai_settings.fleet_drop_speed
    ai_settings.fleet_direction *= -1

def update_aliens(ai_settings, aliens):
    """Check whether there are aliens at the edge of the screen and update the location of the whole group of aliens"""
    check_fleet_edges(ai_settings, aliens)
    aliens.update()

We modified the function update_aliens(), in which check is called_ fleet_ Edges() to determine if aliens are at the edge of the screen. Now, the function update_aliens() contains the formal parameter ai_settings, so when we call it, we specify and AI_ Parameters corresponding to settings:
alien_invasion.py

# Game main loop
    while True:
        gf.check_events(ai_settings, screen, ship, bullets)
        ship.update()
        gf.update_bullets(bullets)
        gf.update_aliens(ai_settings, aliens)
        gf.update_screen(ai_settings, screen, ship, aliens, bullets)

Now when we run the program, we will find that aliens will move down and reverse when they hit the edge.

See the blog in the next section for details.

Topics: Python Game Development