Hello, everyone , I'm Xiao Zhang ~
What about today , Will share a story about A small case of game making ; Just use 200 Line of code to achieve a snake game , As Python game The first article in the series , Let's first look at the effect of the program
About the specific implementation of the program , Please see below
Used in the program Python Library has :
sys
pygame
time
collection
time
random
The core library is pygame;
snake Specific implementation , It is roughly divided into three modules to introduce : Game initialization 、 Game running ( Snake moves 、 Eat food )、 Game over
1, Game initialization
First , Need to be aware of The snake 、 food 、 Game boundaries 、 Color attribute of each element 、 Score record 、 Speed record And so on , The initial window size is set to (600,480), The passing width is 1 The black line divides the game window into several small squares ( The size of each small square is (20,20)
)
SCREEN_WIDTH = 600 # Screen length
SCREEN_HEIGHT = 480 # Wide screen
SIZE = 20 # Small square size
LINE_WIDTH = 1 # Grid line width ;
# The coordinate range of the game area
SCOPE_X = (0,SCREEN_WIDTH//SIZE-1)
SCOPE_Y = (0,SCREEN_HEIGHT//SIZE-1)
# Food score and color
FOOD_STYLE_LIST = [(10,(255,100,100)),(20,(100,255,100)),(30,(100,100,255))]
LIGHT = (100,100,100)
DARK = (200,200,200) # The color of the snake
BLACK = (0,0,0) # Grid line color , black
RED = (200,30,30) # Red ,GAME OVER The font color
BGCOLOR = (40,40,60) # Background color
The initialization of the The snake The size is continuous 3 A small square ; Food share 1 A small square 、 Initially, the food is randomly placed at a certain coordinate in the window ( Of course, it needs to be excluded from the snake body area )
# Initialize snake
def init_snake():
snake = deque()
snake.append((2,SCOPE_Y[0]))
snake.append((1,SCOPE_Y[0]))
snake.append((0,SCOPE_Y[0]))
return snake
# Create food
def create_food(snake):
food_x = random.randint(SCOPE_X[0],SCOPE_X[1])
food_y = random.randint(SCOPE_Y[0],SCOPE_Y[1])
while (food_x,food_y) in snake:
# Food appears on snakes , To regenerate the
food_x = random.randint(SCOPE_X[0],SCOPE_X[1])
food_y = random.randint(SCOPE_Y[0],SCOPE_Y[1])
return food_x,food_y
When the game starts, give ** The snake ** The direction of motion is set as an initial parameter , Here, it is stored in the form of two-dimensional tuples , Assign a value to a variable p, There are four situations :
Cooperate with keyboard event response , When the user presses On (w)、 Next (s)、 Left (a)、 Right (d) Key time , The program will perform the corresponding operation
for event in pygame.event.get():# Event refresh
if event.type == QUIT:
sys.exit()# sign out
elif event.type == KEYDOWN:
if event.key == K_RETURN:
if game_over:
start = True
game_over = False
b =True
snake = init_snake()
food = create_food(snake)
food_style = get_food_style()
pos = (1,0)# Direction
score = 0
last_move_time = time.time()# Last move time
elif event.key == K_SPACE:
if not game_over:
pause = not pause
elif event.key in(K_w,K_UP):
# When judging to prevent the snake from moving up, press the down key , Lead to Game Over
if b and not pos[1]:
pos = (0,-1)
b = False
elif event.key in (K_s,K_DOWN):
if b and not pos[1]:
pos =(0,1)
b = False
elif event.key in (K_a,K_LEFT):
if b and not pos[0]:
pos = (-1,0)
b =False
elif event.key in (K_d,K_RIGHT):
if b and not pos[0]:
pos =(1,0)
b = False
The snake moves
Program will The snake All the small grid coordinates occupied are stored in a queue in turn , Move once , The queue completes an in and out operation : Delete an element at the end of the queue , Insert the new grid coordinates of the snake head into the column head ;
if(SCOPE_X[0] < = next_s[0] <= SCOPE_X[1] and SCOPE_Y[0] < = next_s[1] <= SCOPE_Y[1] and next_s not in snake):
# The next coordinate is in the range
# In and out of the elements in turn
snake.appendleft(next_s)
snake.pop()
Eat food
Every time you eat food , Add a small square area to the snake's body , Insert a new element into its queue 、 Length plus one
,
next_s = (snake[0][0] + pos[0],snake[0][1] +pos[1])# Snake moves
if next_s == food:# Eat the food
snake.appendleft(next_s)# Snake grows bigger
speed = orispeed - 0.03*(score//100) # Update speed
food = create_food(snake)
food_style = get_food_style()
There are two kinds of boundary conditions for game termination
1, The moving area exceeds the window boundary ;
2, The head of the snake touches the body of the snake ;
Used in the program Boolean variables game_over To identify whether the game is over (True perhaps False), The default is before each page refresh False, When the above two events do not occur during the normal operation of the game, it is set to True Game running , Otherwise the game is over
if game_over:# Game over
if start:
print_text(screen,font2,(SCREEN_WIDTH-fwidth)//2,(SCREEN_HEIGHT-fheight)//2,'GAME OVER',RED)
pygame.display.update()# Refresh the page
To improve the game experience , Used in the program score Variables represent scores ,speed To express the moving speed , Every time the score increases 100 Update once Dynamic speed , As time goes on, the game becomes more and more difficult
score += food_style[0]
speed = orispeed - 0.03*(score//100) # Update speed
This one made this time snake It just has some basic functions , There is still much room for improvement , For example, with the help of Pygame Of mixer The module adds some trigger sound effects to some specific events in the game , Add an initialization page at the beginning of the game ; in general , This little game is only suitable for learning, not for playing , If you want to play, it is recommended to move to high-end game areas such as king glory
All the source codes involved in this case are posted below , Interested partners can follow the run
'''
@author:zeroing
@wx official account : Xiao Zhang Python
'''
import pygame
import random
import sys
import time
from collections import deque
from pygame.locals import *
SCREEN_WIDTH = 600 # Screen length
SCREEN_HEIGHT = 480 # Wide screen
SIZE = 20 # Small square size
LINE_WIDTH = 1 # Grid line width ;
# The coordinate range of the game area
SCOPE_X = (0,SCREEN_WIDTH//SIZE-1)
SCOPE_Y = (0,SCREEN_HEIGHT//SIZE-1)
# Food score and color
FOOD_STYLE_LIST = [(10,(255,100,100)),(20,(100,255,100)),(30,(100,100,255))]
LIGHT = (100,100,100)
DARK = (200,200,200) # The color of the snake
BLACK = (0,0,0) # Grid line color , black
RED = (200,30,30) # Red ,GAME OVER The font color
BGCOLOR = (40,40,60) # Background color
def print_text(screen,font,x,y,text,fcolor = (255,255,255)):
imgtext = font.render(text,True,fcolor)# Font rendering
screen.blit(imgtext,(x,y))
# Initialize snake
def init_snake():
snake = deque()
snake.append((2,SCOPE_Y[0]))
snake.append((1,SCOPE_Y[0]))
snake.append((0,SCOPE_Y[0]))
return snake
# Create food
def create_food(snake):
food_x = random.randint(SCOPE_X[0],SCOPE_X[1])
food_y = random.randint(SCOPE_Y[0],SCOPE_Y[1])
while (food_x,food_y) in snake:
# Food appears on snakes , To regenerate the
food_x = random.randint(SCOPE_X[0],SCOPE_X[1])
food_y = random.randint(SCOPE_Y[0],SCOPE_Y[1])
return food_x,food_y
def get_food_style():
# Randomly generate food patterns
return FOOD_STYLE_LIST[random.randint(0,2)]
def main():
# The main function
pygame.init()# initialization
screen = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT))
pygame.display.set_caption(" snake ")
font1 = pygame.font.SysFont('SimHei',24)# Score font
font2 = pygame.font.Font(None,72)#GAME OVER typeface
fwidth,fheight = font2.size('GAME OVER')
# The program runs to the right , Suddenly issuing the down to left command will cause the program to refresh less , The downward event is covered to the left, causing the snake to retreat ,GAME OVER
# b Variables prevent this from happening
b = True
# The snake
snake = init_snake()
# food
food = create_food(snake)
food_style = get_food_style()
# Direction
pos = (1,0)
game_over = True
start = False # Do you want to start
score = 0 # score ;
orispeed = 0.5 # Raw speed
speed = orispeed
last_move_time = None # Last move event
pause = True # Pause
while True:
for event in pygame.event.get():# Event refresh
if event.type == QUIT:
sys.exit()# sign out
elif event.type == KEYDOWN:
if event.key == K_RETURN:
if game_over:
start = True
game_over = False
b =True
snake = init_snake()
food = create_food(snake)
food_style = get_food_style()
pos = (1,0)# Direction
score = 0
last_move_time = time.time()# Last move time
elif event.key == K_SPACE:
if not game_over:
pause = not pause
elif event.key in(K_w,K_UP):
# When judging to prevent the snake from moving up, press the down key , Lead to Game Over
if b and not pos[1]:
pos = (0,-1)
b = False
elif event.key in (K_s,K_DOWN):
if b and not pos[1]:
pos =(0,1)
b = False
elif event.key in (K_a,K_LEFT):
if b and not pos[0]:
pos = (-1,0)
b =False
elif event.key in (K_d,K_RIGHT):
if b and not pos[0]:
pos =(1,0)
b = False
# Fill background
screen.fill(BGCOLOR)
# Painted grid lines , A vertical bar
for x in range(SIZE,SCREEN_WIDTH,SIZE):
pygame.draw.line(screen,BLACK,(x,SCOPE_Y[0]*SIZE),(x,SCREEN_HEIGHT),LINE_WIDTH)
# Draw grid lines
for y in range(SCOPE_Y[0]*SIZE,SCREEN_HEIGHT,SIZE):
pygame.draw.line(screen,BLACK,(0,y),(SCREEN_WIDTH,y),LINE_WIDTH)
if not game_over:
curTime = time.time()# Timing
if curTime - last_move_time >speed:
if not pause:
b = True
last_move_time = curTime
next_s = (snake[0][0] + pos[0],snake[0][1] +pos[1])# Snake moves
if next_s == food:# Eat the food
snake.appendleft(next_s)# Snake grows bigger
score += food_style[0]
speed = orispeed - 0.03*(score//100) # Update speed
food = create_food(snake)
food_style = get_food_style()
else:
if(SCOPE_X[0] < = next_s[0] <= SCOPE_X[1] and SCOPE_Y[0] < = next_s[1] <= SCOPE_Y[1] and next_s not in snake):
# The next coordinate is in the range
# In and out of the elements in turn
snake.appendleft(next_s)
snake.pop()
else:
game_over =True
# Painting food
if not game_over:
# Avoid putting GAME OVER The font covers
pygame.draw.rect(screen,food_style[1],(food[0]*SIZE,food[1]*SIZE,SIZE,SIZE),0)
# Draw a snake
for s in snake:
pygame.draw.rect(screen,DARK,(s[0]*SIZE+LINE_WIDTH,s[1]*SIZE+LINE_WIDTH,
SIZE-LINE_WIDTH*2,SIZE-LINE_WIDTH*2),0)
print_text(screen,font1,30,7,f' Speed :{score//100}')
print_text(screen,font1,450,7,f' score :{score}')
if game_over:# Game over
if start:
print_text(screen,font2,(SCREEN_WIDTH-fwidth)//2,(SCREEN_HEIGHT-fheight)//2,'GAME OVER',RED)
pygame.display.update()# Refresh the page
if __name__ =='__main__':
main()
Okay , The above is the whole content of this article , Thank you for reading , See you next time ~
I think the article is good , Please share with more people ~, finger heart ~