Python alien invasion source code

Python project alien invasion

This project is a project that our teacher asked us to do after contacting Python for one semester. Of course, it was just contacted. It must have been written in accordance with the book. During this period, there were many mistakes, many rewrites and many changes. It took about four days. I didn't understand anything, so it was slow. Let's put the source code on it,
This is the renderings

alien_invasion.py

import pygame
from pygame.sprite import Group
from settings import Settings
from game_stats import GameStats
from scoreboard import Scoreboard
from button import Button
from ship import Ship
import game_functions as gf
def run_game():
    #Initialize the game and create a screen object
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode(
        (ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("Alien Invasion")
    #Create play button
    play_button=Button(ai_settings,screen,"play")
    #Create an instance to store game statistics and create a scoreboard
    stats=GameStats(ai_settings)
    sb=Scoreboard(ai_settings,screen,stats)
    ship = Ship(ai_settings,screen)
    bullets=Group()
    aliens=Group()
    #Creating alien groups
    gf.create_fleet(ai_settings,screen,ship,aliens)

    #Start the main cycle of the game
    while True:

        #Monitor keyboard and mouse events
        gf.check_events(ai_settings,screen,stats,sb,play_button,ship,
                        aliens,bullets)
        if stats.game_active:
            ship.update()
            #Make the most recently drawn screen visible
            gf.update_bullets(ai_settings,screen,stats,sb,ship,aliens,
                              bullets)
            gf.update_aliens(ai_settings,screen,stats,sb,ship,aliens,
                             bullets)
        gf.update_screen(ai_settings,screen,stats,sb,ship,aliens,
                         bullets, play_button)
run_game()

game_functions.py

In large projects, refactor existing code before adding new code. Refactoring aims to simplify the structure of existing code and make it easier to expand. Create a new module that will store a large number of functions to run the game alien invasion. By creating module game_ functions, which can avoid the too long of alien inasiopy and make its logic easier to understand.

import sys
from time import sleep
import pygame
from bullet import Bullet
from alien import Alien
def check_keydown_events(event,ai_settings,screen,ship,bullets):
    """Response key"""
    if event.key == pygame.K_RIGHT :
        # Move the ship to the right
        ship.moving_right = True
    elif event.key == pygame.K_LEFT :
        ship.moving_left = True
    elif event.key==pygame.K_SPACE:
        fire_bullet(ai_settings,screen,ship,bullets)
        #Create a bullet and add it to the group bullets
    elif event.key==pygame.K_q:
        sys.exit()
def check_keyup_events(event,ship):
    """Response release"""
    if event.key == pygame.K_RIGHT :
        # Move the ship to the right
        ship.moving_right = False
    elif event.key == pygame.K_LEFT :
        # Move the ship to the left
        ship.moving_left = False
def check_events(ai_settings,screen,stats,sb,play_button,ship,aliens,bullets):
    """Corresponding key and mouse events"""
    for event in pygame.event.get() :
        if event.type == pygame.QUIT :
            sys.exit()
        elif event.type==pygame.KEYDOWN:
            check_keydown_events(event,ai_settings,screen,ship,bullets)
        elif event.type==pygame.KEYUP:
            check_keyup_events(event,ship)
        elif event.type==pygame.MOUSEBUTTONDOWN:
            mouse_x,mouse_y=pygame.mouse.get_pos()
            check_play_button(ai_settings,screen,stats,sb,play_button,
                              ship,aliens,bullets,mouse_x,mouse_y)
def check_play_button(ai_settings,screen,stats,sb,play_button,ship,
                      aliens,bullets,mouse_x,mouse_y):
    """Click on the player play Button to start a new game"""
    button_clicked=play_button.rect.collidepoint(mouse_x,mouse_y)
    if button_clicked and not stats.game_active:
        #Reset game settings
        ai_settings.initialize_dynamic_settings()
        #hide cursor
        pygame.mouse.set_visible(False)
        #Reset game statistics
        stats.reset_stats()
        stats.game_active=True
        #Reset scoreboard image
        sb.prep_score()
        sb.prep_high_score()
        sb.prep_level()
        sb.prep_ships()
        #Empty alien list and bullet list
        aliens.empty()
        bullets.empty()
        #Create a new group of aliens and center the spacecraft
        create_fleet(ai_settings,screen,ship,aliens)
        ship.center_ship()
def update_screen(ai_settings,screen,stats,sb,ship,aliens,bullets,
                  play_button):
    """Update screen and switch to new screen"""
    #Redraw the screen every time you cycle
    screen.fill(ai_settings.bg_color)
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    aliens.draw(screen)
    #Show score
    sb.show_score()
    #If the game is inactive, draw the play button
    if not stats.game_active:
        play_button.draw_button()
    pygame.display.flip()
def update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets):
    """Update the location of bullets and delete the disappeared bullets"""
    #Update bullet position
    bullets.update()
    #Delete bullets that have disappeared
    for bullet in bullets.copy() :
        if bullet.rect.bottom <= 0 :
             bullets.remove(bullet)
    check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,
                                  aliens,bullets)

def check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,
                                  aliens,bullets):
    """In response to a collision between a bullet and an alien"""
    #Delete bullets and aliens in collision
    collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
    if collisions:
        for aliens in collisions.values():
            stats.score += ai_settings.alien_points*len(aliens)
            sb.prep_score()
        check_high_score(stats,sb)
    if len(aliens) == 0 :
        # Delete existing bullets and create a new group of Aliens
        bullets.empty()
        ai_settings.increase_speed()
        #Improve the level
        stats.level += 1
        sb.prep_level()
        create_fleet(ai_settings, screen, ship, aliens)
def fire_bullet(ai_settings,screen,ship,bullets):
    if len(bullets) < ai_settings.bullets_allowed :
        new_bullet = Bullet(ai_settings, screen, ship)
        bullets.add(new_bullet)
    # Move the ship to the left
def get_number_aliens_x(ai_settings,alien_width):
    available_space_x = ai_settings.screen_width - 2 * alien_width
    number_aliens_x = int(available_space_x / (2 * alien_width))
    return number_aliens_x
def get_number_rows(ai_settings,ship_height,alien_height):
    """How many lines of aliens can the screen 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 join 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.height*row_number
    aliens.add(alien)
def create_fleet(ai_settings,screen,ship,aliens):
    """Creating aliens"""
    #Create an alien and calculate how many aliens a row can hold
    #Space between aliens is alien width
    alien=Alien(ai_settings,screen)
    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 line of Aliens
    for row_number in range(number_rows):
     for alien_number in range(number_aliens_x):
         create_alien(ai_settings,screen,aliens,alien_number,
                      row_number)
def check_fleet_edges(ai_settings,aliens):
    """Take action when an alien reaches 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 down and change their direction"""
    for alien in aliens.sprites():
        alien.rect.y+=ai_settings.fleet_drop_speed
    ai_settings.fleet_direction *= -1
def ship_hit(ai_settings,screen,stats,sb,ship,aliens,bullets):
    """Responding to a spaceship hit by an alien"""
    if stats.ships_left>0:
        #Ship_ left -= 1
        stats.ships_left -= 1
        #Update scoreboard
        sb.prep_ships()
       #Empty alien list and bullet list
        aliens.empty()
        bullets.empty()
        #Create a new group of aliens and put the spacecraft 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.game_active=False
        pygame.mouse.set_visible(True)
def update_aliens(ai_settings,screen,stats,sb,ship,aliens,bullets):
    """Update the location of all aliens in the alien population"""
    check_fleet_edges(ai_settings,aliens)
    aliens.update()
    #Detect collisions between aliens and spacecraft
    if pygame.sprite.spritecollideany(ship,aliens):
        ship_hit(ai_settings,screen,stats,sb,ship,aliens,bullets)
    check_aliens_bottom(ai_settings,screen,stats,sb,ship,aliens,bullets)

def check_aliens_bottom(ai_settings,screen,stats,sb,ship,aliens,
                        bullets):
    """Check if any 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:
         #It's handled like a spaceship hit
         ship_hit(ai_settings,screen,stats,sb,ship,aliens,bullets)
         break
def check_high_score(stats,sb):
    """Check if the new highest score is born"""
    if stats.score > stats.high_score:
        stats.high_score = stats.score
        sb.prep_high_score()

alien.py

Most of the aliens

import pygame
from pygame.sprite import Sprite
class Alien(Sprite):
    """Represents a single alien human"""
    def __init__(self,ai_settings,screen):
        """Initialize the alien and set its starting position"""
        super(Alien, self).__init__()
        self.screen=screen
        self.ai_settings=ai_settings
        #Load the alien image and set its rect property
        self.image=pygame.image.load('images/alien.bmp')
        self.rect=self.image.get_rect()
        #Each alien was initially near the top 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 in designated locations"""
     self.screen.blit(self.image,self.rect)
    def check_edges(self):
        """If the alien is on the edge of the screen, go back 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 right"""
         self.x += (self.ai_settings.alien_speed_factor *
                       self.ai_settings.fleet_direction)
         self.rect.x=self.x

bullet.py

In charge of bullets

import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
    """A class of bullet management for a team of spaceships"""
    def __init__ (self,ai_settings,screen,ship):
        """Create a bullet object where the ship is located"""
        super(Bullet,self).__init__()
        self.screen=screen
        #Create a rectangle representing the bullet at (0.0) and set it in the correct position
        self.rect=pygame.Rect(0,0,ai_settings.bullet_width,
                          ai_settings.bullet_height)
        self.rect.centerx=ship.rect.centerx
        self.rect.top=ship.rect.top
        #Store bullet position in decimal
        self.y=float(self.rect.y)
        self.color=ai_settings.bullet_color
        self.speed_factor=ai_settings.bullet_speed_factor
    def update(self):
        """Move the bullet up"""
        #Update the small value indicating the bullet position
        self.y-=self.speed_factor
        #Update rectde position of bullet
        self.rect.y=self.y
    def draw_bullet(self):
        """Draw bullets on the screen"""
        pygame.draw.rect(self.screen,self.color,self.rect)

button.py

Responsible button

import pygame.font
class Button():
    def __init__(self,ai_settings,screen,msg):
        """Initialize button properties"""
        self.screen=screen
        self.screen_rect=screen.get_rect()
        #Set button size and other properties
        self.width,self.height=200,50
        self.button_color=(1,220,212)
        self.text_color=(255,255,255)
        self.font=pygame.font.SysFont(None,48)
        #Create and center the button's rect object
        self.rect=pygame.Rect(0,0,self.width,self.height)
        self.rect.center=self.screen_rect.center
        #Button labels only need to be created once
        self.prep_msg(msg)
    def prep_msg(self,msg):
        """take msg Render to image and center button"""
        self.msg_image=self.font.render(msg,True,self.text_color,
                                        self.button_color)
        self.msg_image_rect=self.msg_image.get_rect()
        self.msg_image_rect.center=self.rect.center
    def draw_button(self):
        #Draw a color filled button to draw text
        self.screen.fill(self.button_color,self.rect)
        self.screen.blit(self.msg_image,self.msg_image_rect)

game_stats.py

Statistics game information

class GameStats():
    """Track game statistics"""
    def __init__(self,ai_settings):
        """Initialize statistics"""
        self.ai_settings=ai_settings
        self.reset_stats()
        #Make the game inactive at the beginning
        self.game_active=False
        self.high_score=0
    def reset_stats(self):
        """Initializes statistics that may change during play"""
        self.ships_left=self.ai_settings.ship_limit
        self.score=0
        self.level=0

scoreboard.py

Scores

import pygame.font
from pygame.sprite import Group
from ship import Ship
class Scoreboard():
    """Categories of realistic score information"""
    def __init__(self,ai_settings,screen,stats):
        """Attribute involved in initializing display score"""
        self.screen=screen
        self.screen_rect=screen.get_rect()
        self.ai_settings=ai_settings
        self.stats=stats
        #Font settings used to display score information
        self.text_color=(30,30,30)
        self.font=pygame.font.SysFont(None,48)
        #Prepare initial score image
        self.prep_score()
        self.prep_high_score()
        self.prep_level()
        self.prep_ships()
    def prep_score(self):
        """Convert score to a rendered image"""
        rounded_score=int(round(self.stats.score,-1))
        score_str="{:,}".format(rounded_score)
        score_str=str(self.stats.score)
        self.score_image=self.font.render(score_str,True,self.text_color,
                                          self.ai_settings.bg_color)
        #Put the score in the top right corner of the screen
        self.score_rect=self.score_image.get_rect()
        self.score_rect.right=self.screen_rect.right-20
        self.score_rect.top=20
    def show_score(self):
        """Display score and maximum score on screen"""
        self.screen.blit(self.score_image,self.score_rect)
        self.screen.blit(self.high_score_image,self.high_score_rect)
        self.screen.blit(self.level_image,self.level_rect)
        #Draw spacecraft
        self.ships.draw(self.screen)
    def prep_high_score(self):
        """Convert highest score to rendered image"""
        high_score=int(round(self.stats.high_score,-1))
        high_score_str="{:,}".format(high_score)
        self.high_score_image=self.font.render(high_score_str,True,
        self.text_color,self.ai_settings.bg_color)
        #Center the highest score on the top of the screen
        self.high_score_rect=self.high_score_image.get_rect()
        self.high_score_rect.centerx=self.screen_rect.centerx
        self.high_score_rect.top=self.score_rect.top
    def prep_level(self):
        """Convert levels to rendered images"""
        self.level_image=self.font.render(str(self.stats.level),True,
                                          self.text_color,self.ai_settings.bg_color)
        #Put the grade below the score
        self.level_rect =self.level_image.get_rect()
        self.level_rect.right=self.score_rect.right
        self.level_rect.top=self.score_rect.bottom+10
    def prep_ships(self):
        """Show how many ships are left"""
        self.ships=Group()
        for ship_number in range(self.stats.ships_left):
            ship=Ship(self.ai_settings,self.screen)
            ship.rect.x=10+ship_number*ship.rect.width
            ship.rect.y=10
            self.ships.add(ship)

settings.py

Every time you add a new feature to a game, you'll usually introduce some new settings as well. Next, write a module named settings, which contains a class named settings, which is used to store all settings in one place, so as not to replace
Add settings everywhere in the code. In this way, we can pass one setting object instead of many different settings. In addition, this makes function calls easier, and it's easier to change the look of the game as the project grows: to change the game, just change it
settings.py Values in without looking for different settings scattered in the file.

class Settings():
 """Store the set class of alien invasion"""
 def __init__(self):
    """Initialize game settings"""
    #screen setting
    self.screen_width = 1200
    self.screen_height = 800
    self.bg_color = (164, 177, 161)
    #Spaceship setup
    self.ship_limit = 3
    #Bullet setting
    self.bullet_width=3
    self.bullet_height=15
    self.bullet_color=60,60,60
    self.bullets_allowed = 3
    #Alien settings
    self.fleet_drop_speed=10
    #How to speed up the game
    self.speedup_scale=1.1
    #Alien points increase speed
    self.score_scale=1.5
    self.initialize_dynamic_settings()
 def initialize_dynamic_settings(self):
    self.ship_speed_factor = 1.5
    self.bullet_speed_factor = 7
    self.alien_speed_factor = 0.6
    #fleet_ 1 for direction to right, - 1 for left
    self.fleet_direction=1
    #scoring
    self.alien_points=50
 def increase_speed(self):
    """Increase speed settings"""
    self.ship_speed_factor*=self.speedup_scale
    self.bullet_speed_factor*=self.speedup_scale
    self.alien_speed_factor*=self.speedup_scale
    self.alien_points=int(self.alien_points*self.score_scale)
    self.alien_points=int(self.alien_points*self.score_scale)

ship.py

Manage most of the ship's behavior

import pygame
from pygame.sprite import Sprite
class Ship(Sprite) :
    def __init__(self, ai_settings, screen):
        """"Initialize the spacecraft and set its initial position"""
        super(Ship,self).__init__()
        self.screen = screen
        self.ai_settings = ai_settings
        #Loading spacecraft image and obtaining its external rectangle
        self.image=pygame.image.load('images/ship.bmp')
        self.rect=self.image.get_rect()
        self.screen_rect=screen.get_rect()
        #Put each new ship in the center of the bottom of the screen
        self.rect.centerx=self.screen_rect.centerx
        self.rect.bottom=self.screen_rect.bottom
        self.center=float(self.rect.centerx)
        #Mobile sign
        self.moving_right = False
        self.moving_left = False
    def update(self):
        """Adjust the position of the spacecraft according to the moving signs"""
        #Update the center value of the ship instead of rect
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.center += self.ai_settings.ship_speed_factor
        if self.moving_left and self.rect.left > 0:
            self.center -= self.ai_settings.ship_speed_factor
        #according to self.center Update rect object
        self.rect.centerx = self.center
    def blitme (self):
        """Draw the spacecraft at the designated location"""
        self.screen.blit(self.image,self.rect)
    def center_ship(self):
        """Center the ship on the screen"""
        self.center=self.screen_rect.centerx

Among them, the picture can be screenshot of the rendering of the home page, and then converted into a bitmap, if you need the source code @ qq82401402. com

Tags: Python Attribute Mobile

Posted on Fri, 19 Jun 2020 06:46:49 -0400 by ignorant