Python programming from introduction to practice project 1 -- alien invasion

Posted by shmeeg on Sat, 15 Jan 2022 08:41:00 +0100

preface

First of all, the blogger taught himself the theoretical knowledge of the first 10 chapters of python programming from introduction to practice. He thought he needed to do some projects to consolidate and test his self-study achievements, so he chose the alien invasion project to practice. The article is only used as my study notes in the process of making the project, and does not need to be used for other purposes. I hope the great God passing by will not hesitate to give me advice.

step1

A brief description of the game alien invasion: in the game, the player controls a spaceship that initially appeared at the bottom and center of the screen. Players can use the arrow keys to move the ship around, and can also use the space bar to shoot. At the beginning of the game, a group of aliens appeared in the sky and they moved down the screen. The player's task is to shoot these aliens. After players wipe out all aliens, a group of new aliens will appear, and they move faster. As long as an alien hits the player's ship or reaches the bottom of the screen, the player loses a ship. After the player loses three ships, the game is over~

step2

After planning the project, of course, it is the installation environment to knock the code. Because of the hands-on training project, the installation process of the compilation environment is omitted (there are many detailed tutorials on CSDN, which can be searched by yourself). In order to knock aliens, I installed pycharm and pygame (python has been installed before)

pycharm installation tutorial reference: PyCharm installation tutorial (Windows) | rookie tutorial (runoob.com)

step3

The next step is to type the code. I'm the step in the reference book. Then go to pycharm to type the code, and then combine the comments to see the specific role of the code. Up to now, I haven't finished the project completely. I take notes while tapping and compare the Buddhist system~

The current project process is as follows:

First, create an alien_invasion.py file to create an empty Pygame window. After that, it is gradually found that this file is completely regarded as our main file. The following functions are independent. Just import it with import. Here's what I'm doing right now, alien_invasion.py file code, and the code for subsequent function implementation will continue to be updated and added.

import  sys

import pygame
from pygame.sprite import Group

from settings import Settings
from ship import Ship
from alien import  Alien
import  game_functions as gf

def run_game():
    #Initialize the game and create a screen object
    # Initialize pygame, set and screen objects
    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 a spaceship
    ship = Ship(ai_settings,screen)

    # Create a group for storing bullets
    bullets = Group()

    # Create an alien
    alien = Alien(ai_settings,screen)

    # Start the main cycle of the game
    while True:
        gf.check_events(ai_settings,screen,ship,bullets)
        ship.update()
        gf.update_bullets(bullets)
        gf.update_screen(ai_settings,screen,ship,alien,bullets)


run_game()

Create settings class: each time you add new features to the game, some new settings will usually be introduced. Similarly, the following are my current settings Py file code, which will continue to be added later.

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 settings
        self.bullet_speed_factor = 1
        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = 60,60,60
        self.bullets_allowed = 10

Create ship class: after selecting the image used to represent the ship, you need to display it on the screen. Here is my current ship Py file code. In addition, I downloaded the image file of the spacecraft from the extracurricular resources on the official website of this book. I also posted the picture below

import  pygame

class Ship():

    def __init__(self,ai_settings,screen):
        """"Initialize the spacecraft and set its initial test position"""
        self.screen = screen
        self.ai_settings = ai_settings

        # Load the ship image and obtain its circumscribed rectangle
        self.image = pygame.image.load('D:/alien_invasion/images/ship.bmp')
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        # Place 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

        # Store small values in the ship's property cebter
        self.center = float(self.rect.centerx)

        # Move flag
        self.moving_right = False
        self.moving_left = False

    def update(self):
        """"Adjust the position of the spacecraft according to the moving sign"""
        # 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 ship at the specified location"""
        self.screen.blit(self.image,self.rect)

The pictures of the spacecraft are as follows:

Refactoring: module game_functions

In large projects, it is often necessary to refactor existing code before adding new code. Refactoring aims to simplify the structure of existing code and make it easier to expand. I have to say that the reconfiguration module is my biggest gain in this project. It is really amazing. The previous training projects of the school are small and medium-sized, and the future work must be large-scale projects. The reconfiguration module really greatly simplifies the structure of the code, so that the code Xiaobai can quickly read the code program. One word describes: absolutely!

import sys

import  pygame
from bullet import Bullet

def check_keydown_events(event,ai_settings,screen,ship,bullets):
    """Response key"""
    if event.key == pygame.K_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)
    elif event.key == pygame.K_q:
        sys.exit()

def fire_bullet(ai_settings,screen,ship,bullets):
    """"If the limit is not reached, fire a bullet"""
        # Create a bullet and add it to the group bullets
    if len(bullets) < ai_settings.bullets_allowed:
        new_bullet = Bullet(ai_settings,screen,ship)
        bullets.add(new_bullet)

def check_keyup_events(event,ship):
    """"Release response"""
    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):
    """"Respond to 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)

def update_bullets(bullets):
    """"Update the location of bullets and delete disappeared bullets"""
    # Update bullet location
    bullets.update()

    # Delete lost bullets
    for bullet in bullets.copy():
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)


def update_screen(ai_settings,screen,ship,alien,bullets):
    """Update image on screen,And switch to a new screen"""
    # Redraw the screen each time you cycle
    screen.fill(ai_settings.bg_color)
    # Redraw all bullets behind ships and aliens
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    alien.blitme()

    # Make recently drawn screens visible
    pygame.display.flip()

Create Bullet class: to add shooting function. We will write the code to fire bullets (small rectangles) when players press the spacebar. The Bullet will travel up the screen and disappear when it reaches the upper edge of the screen.

import  pygame
from pygame.sprite import Sprite

class Bullet(Sprite):
    """"A class that manages bullets fired by spacecraft"""

    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 the correct position
        self.rect = pygame.Rect(0,0,ai_settings.bullet_width,
                                ai_settings.bullet_width)
        self.rect.centerx = ship.rect.centerx
        self.rect.top = ship.rect.top
        # Stores the bullet position in decimal places
        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 decimal value representing the bullet position
        self.y -= self.speed_factor
        # Update the position of rect representing the bullet
        self.rect.y = self.y

    def draw_bullet(self):
        """"Draw bullets on the screen"""
        pygame.draw.rect(self.screen,self.color,self.rect)

Create Alien class: the behavior of each Alien is controlled by the Alien class.

import pygame
from pygame.sprite import Sprite

class Alien(Sprite):
    """"Class representing a single alien"""

    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 rec attribute
        self.image = pygame.image.load('D:/alien_invasion/images/alien.bmp')
        self.rect = self.image.get_rect()

        # Each alien was initially 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 the specified location"""
        self.screen.blit(self.image,self.rect)

Alien images are as follows:

step4} summary

At present, the progress display effect of my project is that players can move around the automatic spacecraft. The spacecraft can only move inside the screen (not outside the screen). At the same time, players can fire bullets by pressing the space bar. 10 bullets can be fired at the most right time on the screen (to ensure the shooting life rate of bullets). When the number of bullets displayed on the screen is less than 10, players can continue to fire bullets. At the same time, the first alien will be displayed at the top left of the screen (it still can't move at present). The following picture shows the effect of my current project. I will continue to improve my alien invasion game project next week!

Topics: Python Game Development