Python Project Learns Alien Invasion in Practice Creating Alien Spacecraft and Implementing Alien Dynamic Mobility

Keywords: Mobile

Alien Invasion

This blog follows the previous one: Setting up a spaceship to fire bullets https://blog.csdn.net/Ace_bb/article/details/104845723
This blog enables you to add dynamic aliens spacecraft to your game window.

Alien Spacecraft

Spacecraft Picture Resources: Links: https://pan.baidu.com/s/1onui_yfopP2ko1SoqtZ6EQ
Extraction Code: snnw
Depending on the size of the game screen, add a certain number of rows and columns of spacecraft to cover a fixed area of the screen.The ship moves left and right, one cycle to the left and one space down.This cycle achieves the approximation effect of a mobile spaceship.

Steps to achieve:

  1. Add a single ship
  2. Add multiple ships to the screen
  3. To achieve the effect of moving a spaceship from left to right
  4. Achieve downward movement of spacecraft

Create Alien Class

Similar to Ship, Alien s set the basic properties of aliens, including aliens'pictures, location, size, margins, and so on.

import pygame
from pygame.sprite import Sprite
class Alien(Sprite):
    # Humans representing a single aliens
    def __init__(self,ai_settings,screen):
        # Initialize aliens and set their starting position
        super(Alien,self).__init__()
        self.screen = screen
        self.ai_settings = ai_settings
        # Load aliens images and set their screen properties
        self.image = pygame.image.load('images/alien.bmp')
        self.rect = self.image.get_rect()
        # Each alien was originally near the upper left corner of the screen
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height
        # Store the exact location of Aliens
        self.x = float(self.rect.x)
    def blitme(self):
        # Draw aliens at specified locations
        self.screen.blit(self.image,self.rect)

    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

    def check_edges(self):
        # Return to True if the aliens are at the edge of the screen
        screen_rect = self.screen.get_rect()
        if self.rect.right >= screen_rect.right:
            return True
        elif self.rect.left <=0:
            return True

This is the complete code for the Alien class, with functions for updating the location of aliens and for determining whether to move to the boundary, for now.
Next, create an alien instance in the alien_invasion.py main file.
Core Code:

# Create an Alien
    alien = Alien(ai_settings,screen)
gf.update_screen(ai_settings, screen, ship,aliens,bullets)

Full code:

import sys
import pygame
from setting import Settings
from pygame.sprite import Group
from ship import Ship
import game_functions as gf
from alien import Alien
from game_stats import GamStats
def run_game():
    # Initialize the game and create a screen object
    pygame.init()  #Initialize background settings
    ai_settings = Settings()
    screen = pygame.display.set_mode(
        (ai_settings.screen_width, ai_settings.screen_height))
    #Create a sceen window
    pygame.display.set_caption("Alien Invasion")
    # Create an instance to store game statistics
    stats = GamStats(ai_settings)
    #Create a ship
    ship = Ship(ai_settings,screen)
    # Create an Alien
    alien = Alien(ai_settings,screen)
    #Set background color
    bg_color = (230, 230, 230)
    # Create a group to store bullets and store all valid bullets.
    # Manage fired bullets
    bullets = Group()
    # Create an empty group to store all aliens
    aliens=Group()
    # Create an Alien Population
    gf.create_fleet(ai_settings,screen,ship,aliens)
    
    #Start the main cycle of the game
    #Cycle Control Management Screen Update
    while True:
        gf.check_events(ai_settings,screen,ship,bullets)
        if stats.game_active:
            ship.update()
            # Update bullet trajectory
            gf.update_bullets(ai_settings,screen,ship,aliens,bullets)
            gf.update_aliens(ai_settings,stats,screen,ship,aliens,bullets) # Update Alien Location
            gf.update_screen(ai_settings, screen, ship,aliens,bullets)
run_game()

This complete code is also the complete code for alien_invasion.py for the entire project.

Then show the Alien ship on the screen
Core Code:

def update_screen(ai_settings, screen, ship,aliens,bullets):
    # Update the image on the screen and switch to a new screen
    #Redraw the screen every time you cycle
    screen.fill(ai_settings.bg_color)    #There can only be one parameter
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    aliens.draw(screen)
    # Make recently drawn screens visible
    pygame.display.flip()

Show multiple rows and aliens

Calculate the number of aliens a row can hold

# Calculate how many aliens each row can hold
    # Calculate areas that aliens can create, margined from the edge of the screen
    available_space_x = ai_settings.screen_width - 2*alien_width
    # Calculate the number of aliens a row can release
    number_aliens_x = int(available_space_x / (2*alien_width))

The first line of code calculates how much space each line can have to store an alien ship after removing a certain margin, which can be set by itself.
The second line calculates how many aliens can be stored by calculating the vacancies

Calculate how many aliens can be displayed

There should also be margins up and down:

# Calculate how many aliens 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))

Create an Alien Population

Modify in alien_invasion.py:

# Manage fired bullets
    bullets = Group()
    # Create an empty group to store all aliens
    aliens=Group()
    # Create an Alien Population
    gf.create_fleet(ai_settings,screen,ship,aliens)
gf.update_screen(ai_settings, screen, ship,aliens,bullets)

Modify in game_functions.py:

# Get the number of Aliens
def get_number_aliens_x(ai_settings,alien_width):
    # Calculate how many aliens each row can hold
    # Calculate areas that aliens can create, margined from the edge of the screen
    available_space_x = ai_settings.screen_width - 2*alien_width
    # Calculate the number of aliens a row can release
    number_aliens_x = int(available_space_x / (2*alien_width))
    return number_aliens_x

def get_number_rows(ai_settings,ship_height,alien_height):
    # Calculate how many aliens 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

# Create Aliens
def create_alien(ai_settings,screen,aliens,alien_number,row_number):
    # Create an aliens and put them 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.x = alien_width +2*alien_width * alien_number
    alien.rect.x = alien.x
    alien.rect.y = alien.rect.height + 2*alien.rect.height*row_number
    aliens.add(alien)
               
def create_fleet(ai_settings,screen,ship,aliens):
    # Create an Alien Population
    # Create an aliens and calculate how many aliens a row can hold
    # Alien Spacing is Alien Width
    alien = Alien(ai_settings,screen) # Create an Alien
    number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)
    
    number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)
    
    # Create the First Alien
    for row_number in range(number_rows):
        for alien_number in range(number_aliens_x):
            # Create an aliens and add them to your current line
            create_alien(ai_settings,screen,aliens,alien_number,row_number)

Modified in alien_invasion.py:

# Create an Alien Population
    gf.create_fleet(ai_settings,screen,ship,aliens)

Realizing Alien Movement

Make the following changes in the settings.py file:
Set the speed of a ship's movement

 		# Alien Parameter Settings
        self.alien_speed_factor = 1
        # Aliens move down when they hit the edge of the screen
        self.fleet_drop_speed = 10
        # Flet_direction 1 indicates right movement, -1 indicates left movement
        self.fleet_direction = 1

Make the following modifications in alien.py Alien, an aliens human:

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

Modified in alien_invasion.py:

	#Start the main cycle of the game
    #Cycle Control Management Screen Update
    while True:
        gf.check_events(ai_settings,screen,ship,bullets)
        if stats.game_active:
            ship.update()
            # Update bullet trajectory
            gf.update_bullets(ai_settings,screen,ship,aliens,bullets)
            gf.update_aliens(ai_settings,stats,screen,ship,aliens,bullets) # Update Alien Location
            gf.update_screen(ai_settings, screen, ship,aliens,bullets)

Check if aliens are moving to the edge:
In alien.py

	def check_edges(self):
        # Return to True if the aliens are at the edge of the screen
        screen_rect = self.screen.get_rect()
        if self.rect.right >= screen_rect.right:
            return True
        elif self.rect.left <=0:
            return True
    

Move down and change the direction of Aliens
In game_function.py

def check_fleet_edges(ai_settings,aliens):
    # Take action 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 whole groups 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,stats,screen,ship,aliens,bullets):
    # Check if aliens have reached the edge
    check_fleet_edges(ai_settings,aliens)
    # Update the location of all aliens in the Alien Population
    aliens.update()
    # Detecting collisions between aliens and spaceships
    # Spritecollideanyaccepts two parameters, a sprite and a marshalling.
    # It checks if any members of the group have collided with the elves and returns None if no collisions have occurred
    if pygame.sprite.spritecollideany(ship,aliens):
        print("Ship hit!!!")
        
    if pygame.sprite.spritecollideany(ship,aliens):
        ship_hit(ai_settings,stats,screen,ship,aliens,bullets)
    check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)

In alien_invasion.py

#Start the main cycle of the game
    #Cycle Control Management Screen Update
    while True:
        gf.check_events(ai_settings,screen,ship,bullets)
        if stats.game_active:
            ship.update()
            # Update bullet trajectory
            gf.update_bullets(ai_settings,screen,ship,aliens,bullets)
            gf.update_aliens(ai_settings,stats,screen,ship,aliens,bullets) # Update Alien Location
            gf.update_screen(ai_settings, screen, ship,aliens,bullets)

Complete code in several files:
alien.py file

import pygame
from pygame.sprite import Sprite
class Alien(Sprite):
    # Humans representing a single aliens
    def __init__(self,ai_settings,screen):
        # Initialize aliens and set their starting position
        super(Alien,self).__init__()
        self.screen = screen
        self.ai_settings = ai_settings
        # Load aliens images and set their screen properties
        self.image = pygame.image.load('images/alien.bmp')
        self.rect = self.image.get_rect()
        # Each alien was originally near the upper left corner of the screen
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height
        # Store the exact location of Aliens
        self.x = float(self.rect.x)
    def blitme(self):
        # Draw aliens at specified locations
        self.screen.blit(self.image,self.rect)

    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

    def check_edges(self):
        # Return to True if the aliens are at the edge of the screen
        screen_rect = self.screen.get_rect()
        if self.rect.right >= screen_rect.right:
            return True
        elif self.rect.left <=0:
            return True

In the set.py file:

class Settings():
    """ Classes that store all settings for the game,Store some basic parameters"""
    def __init__(self):
        """ Initialize game settings"""
        #screen setting
        self.screen_width = 900
        self.screen_height  = 600
        self.bg_color =  (230,230,230)
        # Ship Settings
        # Setting the property ship_speed_factor to control the speed of a ship
        # Move a spaceship 1.5 pixels
        self.ship_speed_factor = 1.0
        self.ship_limit = 3

        # Bullet Settings
        self.bullet_speed_factor = 1 # Bullet Speed
        self.bullet_width = 3 
        self.bullet_height = 15
        self.bullet_color = 60, 60, 60
        self.bullets_allowed = 10 # Limit the number of bullets

        # Alien Parameter Settings
        self.alien_speed_factor = 1
        # Aliens move down when they hit the edge of the screen
        self.fleet_drop_speed = 10
        # Flet_direction 1 indicates right movement, -1 indicates left movement
        self.fleet_direction = 1

game_function.py file

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleep
# Set Keyboard Button Events
def check_keydown_events(event,ai_settings,screen,ship,bullets):
    # Right arrow keys for response keys
    # Check to see if the right arrow key is pressed by reading event.key
    if event.key == pygame.K_RIGHT:
        # Move the ship to the right
        # ship.rect.centerx += 1 Ship Moves Right
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        # Move the ship to the left
        # ship.rect.centerx -= 1
        ship.moving_left = True
    elif event.key == pygame.K_SPACE: # Set fire instructions
        fire_bullet(ai_settings, screen, ship, bullets)
    # Exit the game when Q is pressed
    elif event.key == pygame.K_q:
        sys.exit()

def check_keyup_events(event ,ship):
    # Respond Loose
    if event.key == pygame.K_RIGHT:
        ship.moving_right = False
    elif event.key == pygame.K_LEFT:
        ship.moving_left = False
        
def check_events(ai_settings,screen,ship,bullets):
    """ Response to key and mouse events, specifying events to check in this method """
    # Events are acquired through the pygame.event.get() method
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
         # Each key registers a KEYDOWN
         # When a KEYDOWN event is detected, we need to check that a specific key is pressed
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event,ai_settings,screen,ship,bullets)
        # Event triggered when the arrow key is released, setting move_right or move_left to false
        elif event.type == pygame.KEYUP:
            check_keyup_events(event,ship)
        

def update_screen(ai_settings, screen, ship,aliens,bullets):
    # Update the image on the screen and switch to a new screen
    #Redraw the screen every time you cycle
    screen.fill(ai_settings.bg_color)    #There can only be one parameter
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    aliens.draw(screen)
    # Make recently drawn screens visible
    pygame.display.flip()

def update_bullets(ai_settings,screen,ship,aliens,bullets):
    # Update the position of the bullet and remove the disappeared bullet 4303987588749
    bullets.update()
    # Clear out-of-bounds bullets to prevent memory usage
    # Traverse through the copy of the bullet group, check each bullet in the copy to see if it reaches the top
    for bullet in bullets.copy():
        # Delete bullets if they reach the top
        if bullet.rect.bottom<=0:
            bullets.remove(bullet)
        # print(len(bullets)) # Print out the remaining number of bullets
    check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets)

def check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets):
    # groupcollide traverses all bullets in the marshalling bullets and all aliens in the marshalling aliens.
    # groupcollide returns a key-value pair when bullets overlap with an aliens rect
    collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)
    if len(aliens) ==0 :
        # Delete existing bullets and create a group of Aliens
        bullets.empty()
        create_fleet(ai_settings,screen,ship,aliens)
def fire_bullet(ai_settings, screen, ship, bullets):
    # Launch a bullet if the limit has not been reached
    # Create a bullet and add it to the marshalling bullets
    # Launch bullets when space is pressed, and limit the number of bullets
    if len(bullets) < ai_settings.bullets_allowed:
        new_bullet = Bullet(ai_settings, screen, ship)
        bullets.add(new_bullet)
# Get the number of Aliens
def get_number_aliens_x(ai_settings,alien_width):
    # Calculate how many aliens each row can hold
    # Calculate areas that aliens can create, margined from the edge of the screen
    available_space_x = ai_settings.screen_width - 2*alien_width
    # Calculate the number of aliens a row can release
    number_aliens_x = int(available_space_x / (2*alien_width))
    return number_aliens_x

def get_number_rows(ai_settings,ship_height,alien_height):
    # Calculate how many aliens 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

# Create Aliens
def create_alien(ai_settings,screen,aliens,alien_number,row_number):
    # Create an aliens and put them 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.x = alien_width +2*alien_width * alien_number
    alien.rect.x = alien.x
    alien.rect.y = alien.rect.height + 2*alien.rect.height*row_number
    aliens.add(alien)
               
def create_fleet(ai_settings,screen,ship,aliens):
    # Create an Alien Population
    # Create an aliens and calculate how many aliens a row can hold
    # Alien Spacing is Alien Width
    alien = Alien(ai_settings,screen) # Create an Alien
    number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)
    
    number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)
    
    # Create the First Alien
    for row_number in range(number_rows):
        for alien_number in range(number_aliens_x):
            # Create an aliens and add them to your current line
            create_alien(ai_settings,screen,aliens,alien_number,row_number)

def check_fleet_edges(ai_settings,aliens):
    # Take action 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 whole groups 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,stats,screen,ship,aliens,bullets):
    # Check if aliens have reached the edge
    check_fleet_edges(ai_settings,aliens)
    # Update the location of all aliens in the Alien Population
    aliens.update()
    # Detecting collisions between aliens and spaceships
    # Spritecollideanyaccepts two parameters, a sprite and a marshalling.
    # It checks if any members of the group have collided with the elves and returns None if no collisions have occurred
    if pygame.sprite.spritecollideany(ship,aliens):
        print("Ship hit!!!")
        
    if pygame.sprite.spritecollideany(ship,aliens):
        ship_hit(ai_settings,stats,screen,ship,aliens,bullets)
    check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)

def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):
    # Respond to ships hit by aliens
    # Reduce ships_left by 1
    if stats.ships_left > 0:
        stats.ships_left -= 1
        # Empty the aliens and bullets lists
        aliens.empty()
        bullets.empty()
        # Create a new group of aliens and place the ship in the center of the bottom of the screen
        create_fleet(ai_settings,screen,ship,aliens)
        ship.center_ship()
        # suspend
        sleep(0.5)
    else:
        stats.geme_active = False

def check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets):
    # Check if aliens have reached the bottom of the screen
    screen_rect = screen.get_rect()
    for alien in aliens.sprites():
        if alien.rect.bottom >= screen_rect.bottom:
            # Handle as if a ship had been hit
            ship_hit(ai_settings,stats,screen,ship,aliens,bullets)
            break

In alien_invasion.py

import sys
import pygame
from setting import Settings
from pygame.sprite import Group
from ship import Ship
import game_functions as gf
from alien import Alien
from game_stats import GamStats
def run_game():
    # Initialize the game and create a screen object
    pygame.init()  #Initialize background settings
    ai_settings = Settings()
    screen = pygame.display.set_mode(
        (ai_settings.screen_width, ai_settings.screen_height))
    #Create a sceen window
    pygame.display.set_caption("Alien Invasion")
    # Create an instance to store game statistics
    stats = GamStats(ai_settings)
    #Create a ship
    ship = Ship(ai_settings,screen)
    # Create an Alien
    alien = Alien(ai_settings,screen)
    #Set background color
    bg_color = (230, 230, 230)
    # Create a group to store bullets and store all valid bullets.
    # Manage fired bullets
    bullets = Group()
    # Create an empty group to store all aliens
    aliens=Group()
    # Create an Alien Population
    gf.create_fleet(ai_settings,screen,ship,aliens)
    
    #Start the main cycle of the game
    #Cycle Control Management Screen Update
    while True:
        gf.check_events(ai_settings,screen,ship,bullets)
        if stats.game_active:
            ship.update()
            # Update bullet trajectory
            gf.update_bullets(ai_settings,screen,ship,aliens,bullets)
            gf.update_aliens(ai_settings,stats,screen,ship,aliens,bullets) # Update Alien Location
            gf.update_screen(ai_settings, screen, ship,aliens,bullets)
run_game()


The complete code given is actually the whole game, because it is a blog that is written after it is finished, so there is no further split. You can look at it all first, then split it up. Actually, a strong code reader can just look at the code directly.

154 original articles were published, 11 were praised, 10,000 visits+
Private letter follow

Posted by OMorchoe on Sat, 14 Mar 2020 19:27:47 -0700