In this project , To add an alien in the upper left corner of the screen , Then calculate how many aliens can be accommodated on the screen according to the alien's margin and screen size , To create a series of Aliens , Make it fill the top half of the size screen ;
 Then we need to make aliens move to both sides and below until they are shot down by aliens , An alien collides with a spaceship or an alien arrives at the bottom of the screen , Shooting down all aliens , When aliens hit the ship or reach the bottom of the screen , Another group of aliens will appear on the screen ;
 In order to avoid endless repetition of the game and boring , Can limit the number of ships available to players , When the number of ships runs out , game over .
 The code is shown below :
1.alien_invasion.py
import sys import pygame from time import sleep from settings import Settings 
from ship import Ship from bullet import Bullet from alien import Alien from 
game_stats import GameStats class AlienInvasion: """  Classes that manage game resources and behaviors  """ def 
__init__(self): """  Initialize games and create game resources  """ pygame.init() self.settings = Settings() 
self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN) 
self.settings.screen_width = self.screen.get_rect().width 
self.settings.screen_height = self.screen.get_rect().height 
pygame.display.set_caption("Alien Invasion") #  Create an instance to store game statistics  self.stats = 
GameStats(self) self.ship = Ship(self) self.bullets = pygame.sprite.Group() 
self.aliens = pygame.sprite.Group() self._create_fleet() def run_game(self): 
"""  Start the main cycle of the game  """ while True: self._check_events() if self.stats.game_active: 
self.ship.update() self._update_bullets() self._update_aliens() 
self._update_screen() def _update_bullets(self): """  Update the location of bullets and delete missing bullets  """ # 
 Update bullet location  self.bullets.update() #  Delete missing bullets  for bullet in self.bullets.copy(): if 
bullet.rect.bottom <= 0: # ########  There are changes here  # if bullet.rect.right >= 
self.ship.screen_rect.right: self.bullets.remove(bullet) 
self._check_bullet_alien_collisions() def _check_bullet_alien_collisions(self): 
"""  Responding to the impact of bullets and aliens  """ #  Delete bullets and aliens that collide  pygame.sprite.groupcollide(self.bullets, 
self.aliens, True, True) ''' 
 function sprite.groupcollide() For each element in a group rect For each element in the same group rect And compare . ''' if not 
self.aliens: #  Delete all existing bullets and create a new group of Aliens  self.bullets.empty() self._create_fleet() def 
_update_aliens(self): """  Check if there are aliens at the edge of the screen , And update the location of all aliens in the alien population  """ 
self._check_fleet_edges() self.aliens.update() #  Detect collisions between aliens and spacecraft  if 
pygame.sprite.spritecollideany(self.ship, self.aliens): print("Ship hit!!!") 
self._ship_hit() #  Check if any aliens have reached the bottom of the screen  self._check_aliens_bottom() def 
_ship_hit(self): """  The response ship was hit by aliens  """ if self.stats.ships_left > 0: # 
 take ships_left reduce 1 self.stats.ships_left -= 1 #  Empty the remaining aliens and bullets  self.aliens.empty() 
self.bullets.empty() #  Create a new group of Aliens , And put the spacecraft in the center at the bottom of the screen  self._create_fleet() 
self.ship.center_ship() #  suspend  sleep(0.5) else: self.stats.game_active = False 
def _check_events(self): """  Respond to key and mouse events  """ for event in pygame.event.get(): if 
event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: #  Press the key  
self._check_keydown_events(event) elif event.type == pygame.KEYUP: #  Release key  
self._check_keyup_events(event) def _check_keydown_events(self, event): """ 
 Response key  """ if event.key == pygame.K_RIGHT: #  The key pressed is the right arrow key  #  Move the ship to the right  
self.ship.moving_right = True elif event.key == pygame.K_LEFT: #  The key pressed is the left arrow key  # 
 Move the ship to the left  self.ship.moving_left = True elif event.key == pygame.K_UP: #  Move the ship up  
self.ship.moving_up = True elif event.key == pygame.K_DOWN: #  Move the ship down  
self.ship.moving_down = True elif event.key == pygame.K_q: sys.exit() elif 
event.key == pygame.K_SPACE: self._fire_bullet() def _check_keyup_events(self, 
event): """  Response release  """ if event.key == pygame.K_RIGHT: #  The released key is the right arrow key  
self.ship.moving_right = False elif event.key == pygame.K_LEFT: #  The released key is the left arrow key  
self.ship.moving_left = False elif event.key == pygame.K_UP: #  The released key is the up arrow key  
self.ship.moving_up = False elif event.key == pygame.K_DOWN: #  The released key is the down arrow key  
self.ship.moving_down = False def _fire_bullet(self): """ 
 Create a bullet , And add it to the group bullets in  """ if len(self.bullets) < 
self.settings.bullets_allowed: new_bullet = Bullet(self) 
self.bullets.add(new_bullet) def _create_fleet(self): """  Create alien colony  """ # 
 Create an alien and calculate how many aliens a row can hold  #  Alien spacing is alien width  alien = Alien(self) alien_width, 
alien_height = alien.rect.size availiable_space_x = self.settings.screen_width 
- (2 * alien_width) number_aliens_x = availiable_space_x // (2 * alien_width) + 
1 #  Calculate how many lines of aliens the screen can hold  ship_height = self.ship.rect.height availiable_space_y = 
(self.settings.screen_height - (3 * alien_height) - ship_height) number_rows = 
availiable_space_y // (2 * alien_height) #  Create alien colony  for row_number in 
range(number_rows): for alien_number in range(number_aliens_x): 
self._create_alien(alien_number, row_number) def _create_alien(self, 
alien_number, row_number): """  Create an alien and add it to the current row  """ alien = Alien(self) 
alien_width, alien_height = alien.rect.size alien.x = alien_width + 2 * 
alien_width * alien_number alien.rect.x = alien.x #  It's important here !!! #  If writing : # 
alien.rect.x = alien_width + 2 * alien_width * alien_number #  There will only be a list of aliens on the screen  # 
 as a result of (alien_width + 2 * alien_width * alien_number) # 
 Is to calculate the position of the current alien on the current line , Then use alien attributes x To set its rect Location of , This is the process of creating alien ranks , It doesn't show the alien movement  # 
alien Is a class Alien() Instance of , stay Alien() in alien.x Changing all the time , Utilization function _update_aliens() to update , To show aliens moving left and right  
alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number 
self.aliens.add(alien) def _check_fleet_edges(self): """  Take appropriate measures when aliens reach the edge  """ 
for alien in self.aliens.sprites(): if alien.check_edges(): 
self._change_fleet_firection() break def _check_aliens_bottom(self): """ 
 Check if any aliens have reached the bottom of the screen  """ screen_rect = self.screen.get_rect() for alien in 
self.aliens.sprites(): if alien.rect.bottom >= screen_rect.bottom: #  Deal with it like a ship was hit  
self._ship_hit() break def _change_fleet_firection(self): """  Move the whole group of aliens down , And change their direction  
""" for alien in self.aliens.sprites(): alien.rect.y += 
self.settings.fleet_drop_speed self.settings.fleet_direction *= -1 def 
_update_screen(self): """  Update image on screen , And switch to a new screen  """ 
self.screen.fill(self.settings.bg_color) self.ship.blitme() for bullet in 
self.bullets.sprites(): bullet.draw_bullet() self.aliens.draw(self.screen) 
pygame.display.flip() if __name__ == '__main__': #  Create a game instance and run the game  ai = 
AlienInvasion() ai.run_game() 
2.settings.py
class Settings: """  Store games 《 Alien invasion 》 Classes for all settings in  """ def __init__(self): """  Initialize game settings  
""" #  screen setting  self.screen_width = 1500 self.screen_height = 800 self.bg_color = 
(227, 227, 227) #  Spacecraft setup  self.ship_speed = 1.5 #  speed : Each cycle will move 1.5 pixel  self.ship_limit 
= 3 #  Number of spacecraft limit  #  Bullet setup  self.bullet_speed = 3.0 self.bullet_width = 3 
self.bullet_height = 15 self.bullet_color = (60, 60, 60) #  Bullet color  
self.bullets_allowed = 10 #  Number of bullets allowed in the screen  #  Alien settings  self.alien_speed = 1.0 
self.fleet_drop_speed = 10 # fleet_direction by 1 Indicates shift right , by -1 Indicates shift left  self.fleet_direction 
= 1 
3.alien.py
import pygame from pygame.sprite import Sprite class Alien(Sprite): """ 
 Class representing a single alien  """ def __init__(self, ai_game): """  Initialize aliens and set their starting position  """ 
super().__init__() self.screen = ai_game.screen self.settings = 
ai_game.settings #  Load alien images and set their rect attribute  self.image = 
pygame.image.load('images/alien.bmp') self.rect = self.image.get_rect() # 
 Every alien was originally near the top left corner of the screen  self.rect.x = self.rect.width self.rect.y = self.rect.height # 
 Store the exact horizontal position of Aliens  self.x = float(self.rect.x) def check_edges(self): """ 
 If aliens are at the edge of the screen , Just return True """ screen_rect = self.screen.get_rect() if self.rect.right 
>= screen_rect.right or self.rect.left <= 0: return True def update(self): """ 
 Move aliens left or right  """ self.x += (self.settings.alien_speed * 
self.settings.fleet_direction) self.rect.x = self.x 
4.ship.py
import pygame class Ship: """  Classes for managing spacecraft  """ def __init__(self, ai_game): """ 
 Initialize the spacecraft and set its initial position  """ self.screen = ai_game.screen self.settings = ai_game.settings 
self.screen_rect = ai_game.screen.get_rect() #  Load the ship image and get its circumscribed rectangle  self.image = 
pygame.image.load('images/ship.bmp') self.rect = self.image.get_rect() # 
 For every new ship , Put it in the center at the bottom of the screen  self.rect.midbottom = self.screen_rect.midbottom # # 
 Make the spaceship appear in the center of the screen instead of the center at the bottom of the screen  # self.rect.center = self.screen_rect.center # # 
 Make the spaceship appear on the left side of the screen  # self.rect.midleft = self.screen_rect.midleft #  Attributes on the ship x Store decimal value in  
self.x = float(self.rect.x) self.y = float(self.rect.y) #  Move flag  
self.moving_right = False self.moving_left = False self.moving_up = False 
self.moving_down = False def update(self): """  Adjust the position of the spacecraft according to the moving signs  """ # 
 Update the ship instead of rect Object's x value  if self.moving_right and self.rect.right < 
self.screen_rect.right: self.x += self.settings.ship_speed if self.moving_left 
and self.rect.left > 0: self.x -= self.settings.ship_speed #  Update the ship instead of rect Object's y value  
if self.moving_down and self.rect.bottom < self.screen_rect.bottom: self.y += 
self.settings.ship_speed if self.moving_up and self.rect.top > 0: self.y -= 
self.settings.ship_speed #  according to self.x to update rect object  self.rect.x = self.x # 
 according to self.y to update rect object  self.rect.y = self.y def center_ship(self): """  Center the ship at the low end of the screen  """ 
self.rect.midbottom = self.screen_rect.midbottom self.x = float(self.rect.x) 
def blitme(self): """  Draw the spaceship at the specified position  """ self.screen.blit(self.image, self.rect) 
5.bullet.py
import pygame from pygame.sprite import Sprite class Bullet(Sprite): """ 
 The class that manages the bullets fired by the spacecraft  """ def __init__(self, ai_game): """  Create a bullet position at the current position of the ship  """ 
super().__init__() self.screen = ai_game.screen self.settings = 
ai_game.settings self.color = self.settings.bullet_color # 
 stay (0,0) Creates a rectangle representing bullets at , Then set the correct position  self.rect = pygame.Rect(0, 0, 
self.settings.bullet_width, self.settings.bullet_height) self.rect.midtop = 
ai_game.ship.rect.midtop #  Store bullet position in decimal  self.y = float(self.rect.y) # self.x = 
float(self.rect.x) def update(self): """  Move the bullet up  """ #  Update decimal value indicating bullet position  self.y -= 
self.settings.bullet_speed #  Update for bullets rect Location of  self.rect.y = self.y # def 
update(self): # """  Move the bullet to the right  """ # #  Update decimal value indicating bullet position  # self.x += 
self.settings.bullet_speed # #  Update for bullets rect Location of  # self.rect.x = self.x def 
draw_bullet(self): """  Draw bullets on screen  """ pygame.draw.rect(self.screen, self.color, 
self.rect) 
6.game_stats.py
class GameStats: """  Track game statistics  """ def __init__(self, ai_game): """  Initialize statistics  
""" self.settings = ai_game.settings self.reset_stats() #  The game was active when it first started  
self.game_active = True def reset_stats(self): """  Initialize statistics that may change during game operation  """ 
self.ships_left = self.settings.ship_limit 
Technology