Item 1: Alien Invasion

0 project planning

0.1 project overview

In the game alien invasion, players control a spaceship that appears at the bottom and center of the screen. Players can use the up, down or left keys to move the ship, and can also use the space bar to shoot. At the beginning of the game, an alien Legion appeared at the top of the screen. While moving left and right, they kept moving down. The mission of the game is to shoot these aliens. After players kill all aliens, there will be a group of aliens who move faster. Only when the spaceship hits an alien or the alien reaches the bottom of the screen, the player loses one spaceship. When the player loses three spaceships, the game ends.

0.2 tool preparation

pygame

To write a small game in python, you need the help of pygame.

pygame installation is also very simple

pip install pygame

In cmd, use the above statement to install.

In order to use pygame normally in pychar

The following steps need to be performed:

Open pychart, File -- Settings -- Project:WorkSpace -- Python Interpreter

Click the plus sign on the right, search for Pygame, and then click Install (PS: it may take some time to load here, wait patiently)

1 start game project

1.1 create Pygame window and respond to user input

When everything is ready, run a simple code to generate a game window

#alien_invasion.py
import sys	#Package required to exit the game
import pygame	#Packages needed to develop games

def run_game():	#Define a function run_game is used to control the start of the game
	pygame.init()	#Initialize the background settings so that Pygame works correctly
	screen = pygame.display.set_mode((1200,800))	
    #Call pyGame display. set_ Mode to create a display window called screen
	pygame.display.set_caption("Alien Invasion")
	bg_color = (230,230,230)	#Define bg_color is (230)
	while True:		
        #The while loop is used to control the operation of the game. The loop includes an event loop and the code to manage screen updates. The whole game is constantly refreshed.
		for event in pygame.event.get():
			if event.type == pygame.QUIT:	
                sys.exit()	#When pyGame After the QUIT event, call sys.. Exit() to exit the game
		screen.fill(bg_color)	#Use screen The fill () method will the BG defined earlier_ Color is used to fill the screen.
		pygame.display.flip()	#By calling pyGame display. Flip () to update the whole screen, erase the old screen and keep the latest screen displayed. The pychart interpreter is interpreted as Update the full display Surface to the screen

run_game()

Operation results:

Well, a game panel is born, and then add some interesting things to it.

1.2 create setting class

In order to make it easier to set up later and make the code simpler, a setting class is created here

#settings.py
class Settings():
    def __init__(self):

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

After putting the setting parameter into the setting class, alien_ invasion. The code in py should also have some changes:

import sys
import pygame
		
def run_game():
	pygame.init()
	ai_settings = Settings()	#Another ai_settings is Settings()
	screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    #Call AI directly_ Width and height in settings
	pygame.display.set_caption("Alien Invasion")
	# bg_color = (230,230,230)
	while True:
		for event in pygame.event.get():
			if event.type == pygame.QUIT:
				sys.exit()
		screen.fill(ai_settings.bg_color)
            #Call AI directly_ Background color in settings
		pygame.display.flip()

run_game()

After doing this, I thought it could run, but I found that the operation reported an error

Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
  File "D:\Dev\Python\WorkSpace\Alienandspace\alien_invasion.py", line 17, in <module>
    run_game()
  File "D:\Dev\Python\WorkSpace\Alienandspace\alien_invasion.py", line 6, in run_game
    ai_settings = Settings()
NameError: name 'Settings' is not defined

Process finished with exit code 1

The reason is that I put alien_invasion.py and setting Py is divided into two files, but stored in the same directory. I think it can be called, but it doesn't work. Start trying to solve it.

It was found that the settings were not imported.

Therefore, alien_ invasion. Add statement to PY

from settings import Settings

Run successfully!

Therefore, we can learn here that different files in the same directory need to be imported before using the functions in their files

Up to now, the two documents and codes are:

#settings.py
class Settings():
    def __init__(self):

        self.screen_width=1200
        self.screen_height=800
        self.bg_color=(230,230,230)
#alien_invasion.py
import sys
import pygame
from settings import Settings

def run_game():
	pygame.init()
	ai_settings = Settings()
	screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
	pygame.display.set_caption("Alien Invasion")
	# bg_color = (230,230,230)
	while True:
		for event in pygame.event.get():
			if event.type == pygame.QUIT:
				sys.exit()
		screen.fill(ai_settings.bg_color)
		pygame.display.flip()

run_game()

It preliminarily realizes the drawing of the window and the adjustment of the size and background color.

2 add ship image

http://pixabay.com A free gallery website, slow

Create an images folder in the root directory of the project, where all future images will be stored

2.1 create Ship class

#ship.py
import pygame
class Ship():
    def __init__(self,screen):
        self.screen = screen
        self.image = pygame.image.load('images/ship.bmp')	#Loading graphics
        self.rect = self.image.get_rect()	#Get the corresponding properties and treat the image as a rectangle. Subsequent operations can only operate on this rectangle
        self.screen_rect = screen.get_rect()	#In order to put the spaceship in the center of the screen, you also need to pass the screen get_ Rect() treats the entire screen as a rectangle

        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom
		#The above two lines of code indicate that the x coordinate of the spacecraft center is set as the attribute centerx of the screen rectangle; Set the y coordinate of the lower edge of the spaceship to the bottom attribute of the screen rectangle
        
        
    def blitme(self):	#Define method blitme()
        self.screen.blit(self.image,self.rect)
        #. blit() has two parameters, which can be based on self Rect sets the position of self Image is drawn to the screen

At this point, a Ship class is created

In order for the ship to appear on the screen, it needs to be in alien_invasion.py

#alien_invasion.py
import sys
import pygame
from settings import Settings
from ship import Ship  #Import ship class


def run_game():
	pygame.init()
	ai_settings = Settings()
	screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
	pygame.display.set_caption("Alien Invasion")
    
	ship = Ship(screen)		#Create a search ship and put the operation of creating a ship outside of while
    
	# bg_color = (230,230,230)
	while True:
		for event in pygame.event.get():
			if event.type == pygame.QUIT:
				sys.exit()
		screen.fill(ai_settings.bg_color)
        
		ship.blitme()	#Drawing spacecraft
        
		pygame.display.flip()

run_game()

3 refactoring

The previous code structure was cumbersome, such as control event monitoring, and the code for screen update was written directly in alien_ invasion. In the while loop of Py, you can actually extract it and write it separately in a file. You can call it when you need to use it.

So create a new file: game_functions.py

#game_functions.py
import sys
import pygame

def check_events():		#Check the event to exit the game
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

def update_screen(ai_settings,screen,ship):		#Update screen, including drawing screen, background color, spaceship
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    pygame.display.flip()

On this basis, alien can be_ invasion. Py code to simplify

#alien_invasion.py
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf

def run_game():
	pygame.init()
	ai_settings = Settings()
	screen=pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
	pygame.display.set_caption("Alien Invasion")
	ship = Ship(screen)
	# bg_color = (230,230,230)
	while True:		#It is obvious that the number of statements in the while loop is greatly reduced
		gf.check_events()
		gf.update_screen(ai_settings,screen,ship)

run_game()

4 fly the spaceship

4.1 response key

In order to make the spacecraft move, it is usually realized by the up, down, left and right direction keys, because the events are through the method pyGame event. Get (), so in the function check_ In event (), you can add statements to control the movement of the spacecraft

Upper code #game_functions.py

#game_functions.py
import sys
import pygame

def check_events(ship):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                ship.rect.centerx+=1

def update_screen(ai_settings,screen,ship):
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    pygame.display.flip()

The test found that only by constantly pressing the direction key can the spacecraft move continuously. Click to move. You cannot press and hold the arrow key to move all the way.

Stroke the logic. Previously, press the key to move to the right. It is through the if statement to judge when KEYDOWN and K are detected_ Ship when right rect. Centerx + = 1 through this method, it will move every time it is monitored.

4.2 continuous movement

If a logic is changed, when KEYDOWN and K are detected_ When right, make the spacecraft enter a transition state (i.e. the state of moving right all the time).

So consider using a moving_right flag to achieve continuous movement.

Setting, moving_right=True indicates moving_right=False indicates no movement.

At the beginning, the ship's default moving_ Set ringt to False to keep the ship stationary.

KEYDOWN and K are detected_ When right, make the spacecraft get moving_ After ring = true, keep the spacecraft moving to the right continuously.

First, ship Py

#ship.py
#ship.py
import pygame
class Ship():
    def __init__(self,screen):
        self.screen = screen
        self.image = pygame.image.load('images/ship.bmp')	
        self.rect = self.image.get_rect()	
        self.screen_rect = screen.get_rect()	
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom
		
        self.moving_right = False	#The default setting is False
    def update(self):
        if self.moving_right:	#When moving_ When the value of right is true, it shifts one bit to the right
            self.rect.centerx += 1
        
    def blitme(self):	#Define method blitme()
        self.screen.blit(self.image,self.rect)
        #. blit() has two parameters, which can be based on self Rect sets the position of self Image is drawn to the screen

Next on the game_functions.py

#game_functions.py
import sys
import pygame

def check_events(ship):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                ship.moving_right = True
        elif event.type == pygame.KEYUP:
            if event.key ==pygame.K_RIGHT:
                ship.moving_right = False

def update_screen(ai_settings,screen,ship):
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    pygame.display.flip()

Finally in alien_invasion.py

#alien_invasion.py
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf

def run_game():
	pygame.init()
	ai_settings = Settings()
	screen=pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
	pygame.display.set_caption("Alien Invasion")
	ship = Ship(screen)
	while True:		
		gf.check_events()	#1, Monitor and judge the situation
        ship.update()       #2, Update status as appropriate
		gf.update_screen(ai_settings,screen,ship)#3, Refresh the screen according to the updated status

run_game()

4.3 up, down, left and right movement

Similarly, the spacecraft can be moved up, down, left and right. The code is as follows:

#ship.py
import pygame
class Ship():
    def __init__(self,screen):
        self.screen = screen
        self.image = pygame.image.load('images/ship.bmp')
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom

        self.moving_right = False
        self.moving_left = False
        self.moving_up = False
        self.moving_down =False
    def update(self):
        if self.moving_right:
            self.rect.centerx += 1
        if self.moving_left:
            self.rect.centerx -= 1
        if self.moving_up:
            self.rect.centery -= 1
        if self.moving_down:
            self.rect.centery += 1
    def blitme(self):
        self.screen.blit(self.image,self.rect)
#game_functions.py		
import sys
import pygame

def check_events(ship):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            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_UP:
                ship.moving_up = True
            elif event.key == pygame.K_DOWN:
                ship.moving_down = True
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                ship.moving_right = False
            elif event.key == pygame.K_LEFT:
                ship.moving_left = False
            elif event.key == pygame.K_UP:
                ship.moving_up = False
            elif event.key == pygame.K_DOWN:
                ship.moving_down = False

def update_screen(ai_settings,screen,ship):
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    pygame.display.flip()
#alien_invasion.py
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf

def run_game():
	pygame.init()
	ai_settings = Settings()
	screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
	pygame.display.set_caption("Alien Invasion")
	ship = Ship(screen)
	while True:
		gf.check_events(ship)
		ship.update()
		gf.update_screen(ai_settings,screen,ship)

run_game()

4.4 adjust the speed of the spacecraft & control the action range of the spacecraft & set the size of the spacecraft & reconstruct the check_events()

These things are done together, and the process doesn't stop, so write the documents together and put the code directly

#ship.py
import pygame
class Ship():
    def __init__(self,ai_settings,screen):
        self.screen = screen
        self.ai_settings = ai_settings
        self.ship = pygame.image.load('images/ship.bmp')
        image = self.ship	#In order to set the size of the ship image separately, define the uploaded image as ship, then image, and then pyGame transform. The scale (surface, (int, int)) statement defines the size of the picture.
        #self. image = pygame. transform. Scale (image, (200110)) to keep the code clean, rewrite this sentence as follows
        self.image = pygame.transform.scale(image,ai_settings.ship_size)
        #Ship here_ Size is also set in settings In PY
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom

        self.center = float(self.rect.centerx)
        self.middle = float(self.rect.centery)

        self.moving_right = False
        self.moving_left = False
        self.moving_up = False
        self.moving_down = False


    def update(self):
        if self.moving_right and self.rect.right < self.screen_rect.right:
            #Here, by comparing the right side of the rect of the spaceship image with the right side of the rect of the screen, the spaceship can not exceed the right side of the screen, the same below
            self.center += self.ai_settings.ship_speed_factor	
            #The speed of the ship here is self ai_ settings. ship_ speed_ Factor, which is a preset value in settings
        if self.moving_left and self.rect.left > 0:
            self.center -= self.ai_settings.ship_speed_factor
        if self.moving_up and self.rect.top > self.screen_rect.top:
            self.middle -= self.ai_settings.ship_speed_factor
        if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
            self.middle += self.ai_settings.ship_speed_factor

        self.rect.centerx = self.center
        self.rect.centery = self.middle

    def blitme(self):
        self.screen.blit(self.image,self.rect)
#game_functions.py
#Check here_ Events is refactored due to check_events needs to check Keydown and Keyup, and each of them contains a lot of content, so we consider separating them by Keydown and Keyup. Write all operations in Keydown status to check_ keydown_ In events(); Write all operations in Keyup status to check_ keyup_ In events(); Finally, check_ Set the corresponding conditions of these two events in events()
import sys
import pygame
def check_keydown_events(event,ship):
    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_UP:
        ship.moving_up = True
    elif event.key == pygame.K_DOWN:
        ship.moving_down = True
def check_keyup_events(event,ship):
    if event.key == pygame.K_RIGHT:
        ship.moving_right = False
    elif event.key == pygame.K_LEFT:
        ship.moving_left = False
    elif event.key == pygame.K_UP:
        ship.moving_up = False
    elif event.key == pygame.K_DOWN:
        ship.moving_down = False
def check_events(ship):
    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)

def update_screen(ai_settings,screen,ship):
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    pygame.display.flip()
#settings.py
class Settings():
    def __init__(self):

        self.screen_width=1200
        self.screen_height=800
        self.bg_color=(230,230,230)
        self.ship_speed_factor = 1.5	#Spacecraft movement speed
        self.ship_size=(200,110)	#Ship size

#alien_invasion.py
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf

def run_game():
	pygame.init()
	ai_settings = Settings()
	screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
	pygame.display.set_caption("Alien Invasion")
	ship = Ship(ai_settings,screen)
	while True:
		gf.check_events(ship)
		ship.update()
		gf.update_screen(ai_settings,screen,ship)

run_game()

Keywords: Python

Added by Runilo on Mon, 17 Jan 2022 14:14:24 +0200