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()