Try to write a game in python. This game is called alien invasion

Keywords: Python Attribute pip Windows

preface

The text and pictures of this article are from the Internet, only for learning and communication, and do not have any commercial use. The copyright belongs to the original author. If you have any questions, please contact us in time for handling.

Install pygame and create a ship that can move left and right

Install pygame

My computer is windows 10, python3.6, pygame download address: https://pypi.python.org/pypi/Pygame/1.9.3 Please download the corresponding Python version of pygame and run the following command

$ pip install wheel
$ pip install pygame‑1.9.3‑cp36‑cp36m‑win_amd64.whl

 

Creating Pygame window and responding to user input

Create a new folder alien_ And create a new alien in the folder_ invasion.py File, enter the following code.

import sys
import pygame
def run_game():
    #initialize game and create a dispaly object
    pygame.init()
    screen = pygame.display.set_mode((1200,800))
    pygame.display.set_caption("Alien Invasion")
    # set backgroud color
    bg_color = (230,230,230)

    # game loop
    while True:
        # supervise keyboard and mouse item
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
        # fill color
        screen.fill(bg_color)
        # visualiaze the window
        pygame.display.flip()
run_game()

Running the above code, we can get a gray interface window:

$ python alien_invasion.py

Create settings class

In order to create some new functions conveniently in the process of writing the game, we write an additional settings module which contains a settings class to store all the settings in one place. This makes it easier to change the look of the game as the project grows in the future. First of all, let's take alien_invasion.py The size and color of the display screen are modified. First in alien_ Create a python file under the innovation folder settings.py And add the following code to it:

class Settings(object):
    """docstring for Settings"""
    def __init__(self):
        # initialize setting of game

        # screen setting
        self.screen_width = 1200
        self.screen_height = 800
        self.bg_color = (230,230,230)

And then in alien_invasion.py Import the Settings class and use the related Settings. Modify them as follows:

import sys
import pygame
from settings import Settings
def run_game():
    #initialize game and create a dispaly 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")
    # set backgroud color
    bg_color = (230,230,230)

    # game loop
    while True:
        # supervise keyboard and mouse item
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
        # fill color
        screen.fill(ai_settings.bg_color)
        # visualiaze the window
        pygame.display.flip()
run_game()

Add spaceship image

Next, we need to add the ship to the game. To draw the player's ship on the screen, we'll load an image and draw it using the Pygame() method blit(). Almost all kinds of image files can be used in the game, but bitmap (. bmp) files are the easiest because Pygame loads bitmaps by default. While other types of images can be loaded, additional libraries need to be installed. We recommend to go to the free image material website to find images: https://pixabay.com/ We are in the main project folder (alien_ Create a new folder called images, and put the following bmp pictures into it.

Next, we create the spaceship class ship.py :

import pygame
class Ship():

    def __init__(self,screen):
        #initialize spaceship and its location
        self.screen = screen

        # load bmp image and get rectangle
        self.image = pygame.image.load('image/ship.bmp')
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        #put spaceship on the bottom of window
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom

    def blitme(self):
        #buld the spaceship at the specific location
        self.screen.blit(self.image,self.rect)

Finally, we draw the spaceship on the screen, that is, in alien_invasion.py The blitme method is invoked in the file:

import sys
import pygame
from settings import Settings
from ship import Settings
def run_game():
    #initialize game and create a dispaly object
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    ship = Ship(screen)
    pygame.display.set_caption("Alien Invasion")
    # set backgroud color
    bg_color = (230,230,230)

    # game loop
    while True:
        # supervise keyboard and mouse item
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
        # fill color
        screen.fill(ai_settings.bg_color)
        ship.blitme()
        # visualiaze the window
        pygame.display.flip()
run_game()

Refactoring: module game_functions

In large projects, it is often necessary to refactor existing code before adding new code. The purpose of refactoring is to simplify the structure of code and make it easier to expand. We're going to implement a game_functions module, which will store a large number of functions for the game Alien invasion to run. By creating the module game_functions to avoid alien_invasion.py Too long, making its logic easier to understand.

Function check_events()

First, we move the code for managing events to a name called check_ In the function of events(), the purpose is to isolate the event loop

import sys
import pygame

def check_events():
    #respond to  keyboard and mouse item
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

And then we modified alien_invasion.py Code, importing game_functions module, and replace the event loop with the function check_events() call:

import sys
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
def run_game():
    #initialize game and create a dispaly object
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    ship = Ship(screen)
    pygame.display.set_caption("Alien Invasion")
    # set backgroud color
    bg_color = (230,230,230)

    # game loop
    while True:
        # supervise keyboard and mouse item
        gf.check_events()
        # fill color
        screen.fill(ai_settings.bg_color)
        ship.blitme()
        # visualiaze the window
        pygame.display.flip()
run_game()

Function update_screen()

Move the code that updates the screen to a name called update_screen() function, and put this function in the module game_ In functions:

def update_screen(ai_settings,screen,ship):
    # fill color
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    # visualiaze the window
    pygame.display.flip()

Among them, alien_ The innovation is as follows:

import sys
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
def run_game():
    #initialize game and create a dispaly object
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    ship = Ship(screen)
    pygame.display.set_caption("Alien Invasion")
    # set backgroud color
    bg_color = (230,230,230)

    # game loop
    while True:
        # supervise keyboard and mouse item
        gf.check_events()
        gf.update_screen(ai_settings,screen,ship)
run_game()

From the above process, we find that: in the actual development process, we write the code as simple as possible at the beginning, and refactor when the project becomes more and more complex. Next, we start to deal with the dynamic aspects of the game.

Flying a spaceship

Here we want to achieve is to make the player through the left and right arrow keys to control the spacecraft left and right.

Response button

Because in pygame, every key is registered as a KEYDOWN event. In check_ In events (), we use the event.type After the KEYDOWN event is detected, it is necessary to further determine which key it is. The code is as follows:

def check_events(ship):
    #respond to  keyboard and mouse item
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                #move right
                ship.rect.centerx +=1

Allow constant movement

When the player holds down the right arrow, we want the ship to move continuously until the player releases it. Here we judge by KETUO event. So we set a flag bit moving_right for continuous movement. The principle is as follows:

When the spaceship is stationary, the sign is moving_right will be false. When the player presses the right arrow, we set the flag to True; when the player releases, we reset the flag to false. This move attribute is one of the ship attributes. We use the ship class to control it. Therefore, we add an attribute name to this class, moving_right and an update() method to detect the flag moving_ Status of right.

ship

        self.moving_right = False
    def update(self):
        if self.moving_right:
            self.rect.centerx +=1

game_functions

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                #move right
                ship.moving_right = True
        elif event.type == pygame.KEYUP:
            if event.key = pygame.K_RIGHT:
                ship.moving_right = False

Finally, in alien_ The update() method is invoked in invasion.

    while True:
        # supervise keyboard and mouse item
        gf.check_events(ship)
        ship.update()

Move left and right

Previously, we moved to the right, and then moved to the left. The logic is similar, and the code will not be pasted.

Adjust the speed of the ship

Currently, each time the while loop is executed, the spacecraft can move at most one pixel. We can add ship in settings_ speed_ Factor, used to control the speed of the spacecraft. We will use this property to determine the maximum distance the spacecraft can move in each cycle. Settings:

class Settings(object):
    """docstring for Settings"""
    def __init__(self):
        # initialize setting of game

        # screen setting
        self.screen_width = 1200
        self.screen_height = 800
        self.bg_color = (230,230,230)
        self.ship_speed_factor = 1.5

Ship:

class Ship():

    def __init__(self,ai_settings,screen):
        #initialize spaceship and its location
        self.screen = screen
        self.ai_settings = ai_settings

Limit the range of motion of the spacecraft

If the player holds down the arrow for a long time, the Ship will disappear. How to stop the Ship when it reaches the edge of the screen? Here, we only need to modify the update method in the Ship class to add a logical judgment.

restructure

Here we will mainly check_ The events() function is refactored, and part of the code is divided into two parts: one deals with the KEYDOWN event, and the other deals with the KEYUP event. game_functions:

def check_keydown_events(event,ship):
    if event.key == pygame.K_RIGHT:
        #move right
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        #move right
        ship.moving_left = True 
def check_keyup_events(event,ship):
    if event.key == pygame.K_RIGHT:
        ship.moving_right = False
    elif event.key == pygame.K_LEFT:
        #move right
        ship.moving_left = False
def check_events(ship):
    #respond to  keyboard and mouse item
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event,ship)
        elif event.type == pygame.KEYUP:
            check_keyup_events(event,ship)

Shooting

Next, add the shooting function to make the player fire bullets when pressing the space bar. The bullets will go up the screen and disappear when they reach the screen.

Add bullet settings

Add some bullet properties to the Settings class. Here we create a dark gray bullet 3 pixels wide and 15 pixels high. The speed of the bullet is slightly slower than that of the spacecraft.

Create a Bullet class

 
import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):
    """A class to manage bullets fired from the ship."""

    def __init__(self, ai_settings, screen, ship):
        """Create a bullet object, at the ship's current position."""
        super().__init__()
        self.screen = screen

        # Create bullet rect at (0, 0), then set 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 a decimal value for the bullet's position.
        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 the screen."""
        # Update the decimal position of the bullet.
        self.y -= self.speed_factor
        # Update the rect position.
        self.rect.y = self.y

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

Store bullets in group

After defining the Bullet class and the necessary settings, you can write the code, which will fire a Bullet every time the player presses the space bar. First of all, we are in alien_ Create a group in the invasion to store all valid bullets.

def run_game():
    #initialize game and create a dispaly object
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    ship = Ship(ai_settings,screen)
    bullets = Group()
    pygame.display.set_caption("Alien Invasion")
    # set backgroud color
    bg_color = (230,230,230)

    # game loop
    while True:
        # supervise keyboard and mouse item
        gf.check_events(ai_settings, screen, ship,bullets)
        ship.update()
        bullets.update()
        gf.update_screen(ai_settings, screen, ship,bullets)

FireStarter

Here we modify check_keydown_events() function, to monitor the event that the player presses the space bar. Update needs to be modified here_ The screen () function ensures that each bullet can be redrawn every time the screen is updated. Let's look at the effect:

Remove missing bullets

In alien_ Delete the disappeared bullet from the invasion.

import sys
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
from pygame.sprite import Group
def run_game():
    #initialize game and create a dispaly object
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    ship = Ship(ai_settings,screen)
    bullets = Group()
    pygame.display.set_caption("Alien Invasion")
    # set backgroud color
    bg_color = (230,230,230)

    # game loop
    while True:
        # supervise keyboard and mouse item
        gf.check_events(ai_settings, screen, ship,bullets)
        ship.update()
        bullets.update()
        for bullet in bullets.copy():
            if bullet.rect.bottom <=0:
                bullets.remove(bullet)
        gf.update_screen(ai_settings, screen,ship,bullets)
run_game()

Limit the number of bullets

In order to encourage players to shoot with targets, we stipulate that only three bullets can exist on the screen at the same time. We only need to check whether the number of bullets that have not disappeared is less than 3 before creating bullets.

Create update_bullets() function

In order to make alien_ The code in the invasion is more simple. We will check the code of bullet management and move it to game_ In the functions module:

def update_bullets(bullets):
    bullets.update()
    for bullet in bullets.copy():
        if bullet.rect.bottom<=0:
            bullets.remove(bullet)

Create fire_bullet() function

Here we move the firing code to a separate function:

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) 

Add aliens and detect collisions

Before we finish the new task, we will add a shortcut key Q:

Create the first alien

It's the same as creating a spaceship

class Alien(Sprite):
    """A class to represent a single alien in the fleet."""

    def __init__(self, ai_settings, screen):
        """Initialize the alien, and set its starting position."""
        super().__init__()
        self.screen = screen
        self.ai_settings = ai_settings

        # Load the alien image, and set its rect attribute.
        self.image = pygame.image.load('images/alien.bmp')
        self.rect = self.image.get_rect()

        # Start each new alien near the top left of the screen.
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        # Store the alien's exact position.
        self.x = float(self.rect.x)
    def blitme(self):
        """Draw the alien at its current location."""
        self.screen.blit(self.image, self.rect)

Creating a group of Aliens

Here we first determine how many aliens a row can hold and how many lines to draw. There are a lot of code changes here. You can see the effect directly

Mobile aliens

We created static aliens. Now we need to make them move. Here, we set the speed of Alien movement in the Settings class, and then use the update method in the Alien class to realize the movement

Shooting aliens

If you want to shoot aliens, you must first detect whether there is a collision between two group members. In the game, collision is the overlap of game elements. Here we use sprite.groupcollide() to detect collisions between members of two groups. When a bullet hits an alien, it needs to know immediately, and at the same time make the alien being collided disappear immediately. Therefore, we need to detect the collision immediately after updating the position of the bullet.

End the game

Here we also need to know when to end the game. There are several situations:

The actual effect of the spacecraft being destroyed and the alien reaching the bottom of the screen:

scoring

Finally, we will add a Play button to the game, which is used to start the game as needed and restart the game after the end of the game. We will also implement a scoring system that will speed up the pace as the player level increases.

Add Play button

Here we can initialize the game to inactive state, when we click the Button, the game will start. Because there is no built-in way to create buttons in Pygame. So we can create a solid rectangle with its own label by creating a Button class. We determine whether the click event occurs by detecting whether the coordinates of the mouse after clicking collide with the buttons we draw.

Improve the level

In order to make the game more difficult and more interesting after the player has eliminated the enemy, we can modify it in the Settings class to add static initial value and dynamic initial value.

Score, rank, remaining spacecraft

 

Posted by jsims on Mon, 29 Jun 2020 02:55:29 -0700