Review our way of making small games in python, a few very wonderful articles
We implemented the tank battle in python
python make tank battle
We implemented the spaceship war in python
python make spaceship war
We have implemented two different snake games in python
200 Line python code to realize the snake game
150 Line code to realize the snake game
We implemented the minesweeper game with python
Python implements minesweeper game
We implemented the Gobang game in python
Python implements Gobang game
Today we use python to implement the Tetris game that we played when we were young.
The specific code and files can be obtained from my GitHub address
The first step-build various blocks
import random
from collections import namedtuple
Point =namedtuple('Point','X Y')
Shape =namedtuple('Shape','X Y Width Height')
Block =namedtuple('Block','template start_pos end_pos name next')
# The square shape design, I originally made it 4 × 4, because the longest length and width are 4, so when you rotate, you don’t think about how to turn it, just replace one shape with another
# In fact, to achieve this function, you only need to fix the coordinates of the upper left corner.
# S shaped square
S_BLOCK =[Block(['.OO','OO.','...'],Point(0,0),Point(2,1),'S',1),Block(['O..','OO.','.O.'],Point(0,0),Point(1,2),'S',0)]
# Z-shaped square
Z_BLOCK =[Block(['OO.','.OO','...'],Point(0,0),Point(2,1),'Z',1),Block(['.O.','OO.','O..'],Point(0,0),Point(1,2),'Z',0)]
# I block
I_BLOCK =[Block(['.O..','.O..','.O..','.O..'],Point(1,0),Point(1,3),'I',1),Block(['....','....','OOOO','....'],Point(0,2),Point(3,2),'I',0)]
# O-shaped box
O_BLOCK =[Block(['OO','OO'],Point(0,0),Point(1,1),'O',0)]
# J square
J_BLOCK =[Block(['O..','OOO','...'],Point(0,0),Point(2,1),'J',1),Block(['.OO','.O.','.O.'],Point(1,0),Point(2,2),'J',2),Block(['...','OOO','..O'],Point(0,1),Point(2,2),'J',3),Block(['.O.','.O.','OO.'],Point(0,0),Point(1,2),'J',0)]
# L-shaped block
L_BLOCK =[Block(['..O','OOO','...'],Point(0,0),Point(2,1),'L',1),Block(['.O.','.O.','.OO'],Point(1,0),Point(2,2),'L',2),Block(['...','OOO','O..'],Point(0,1),Point(2,2),'L',3),Block(['OO.','.O.','.O.'],Point(0,0),Point(1,2),'L',0)]
# T block
T_BLOCK =[Block(['.O.','OOO','...'],Point(0,0),Point(2,1),'T',1),Block(['.O.','.OO','.O.'],Point(1,0),Point(2,2),'T',2),Block(['...','OOO','.O.'],Point(0,1),Point(2,2),'T',3),Block(['.O.','OO.','.O.'],Point(0,0),Point(1,2),'T',0)]
BLOCKS ={'O': O_BLOCK,'I': I_BLOCK,'Z': Z_BLOCK,'T': T_BLOCK,'L': L_BLOCK,'S': S_BLOCK,'J': J_BLOCK}
def get_block():
block_name = random.choice('OIZTLSJ')
b = BLOCKS[block_name]
idx = random.randint(0,len(b)-1)return b[idx]
def get_next_block(block):
b = BLOCKS[block.name]return b[block.next]
The second part-build the main function
import sys
import time
import pygame
from pygame.locals import*import blocks
SIZE =30 #Size of each small square
BLOCK_HEIGHT =25 #Game area height
BLOCK_WIDTH =10 #Game area width
BORDER_WIDTH =4 #Game area border width
BORDER_COLOR =(40,40,200) #Game area border color
SCREEN_WIDTH = SIZE *(BLOCK_WIDTH +5) #The width of the game screen
SCREEN_HEIGHT = SIZE * BLOCK_HEIGHT #The height of the game screen
BG_COLOR =(40,40,60) #Background color
BLOCK_COLOR =(20,128,200) #
BLACK =(0,0,0)
RED =(200,30,30) #GAME OVER font color
def print_text(screen, font, x, y, text, fcolor=(255,255,255)):
imgText = font.render(text, True, fcolor)
screen.blit(imgText,(x, y))
def main():
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Tetris')
font1 = pygame.font.SysFont('SimHei',24) #Heibody 24
font2 = pygame.font.Font(None,72) #GAME OVER font
font_pos_x = BLOCK_WIDTH * SIZE + BORDER_WIDTH +10 #X coordinate of the font position of the information display area on the right
gameover_size = font2.size('GAME OVER')
font1_height =int(font1.size('Score')[1])
cur_block = None #Current falling block
next_block = None #Next square
cur_pos_x, cur_pos_y =0,0
game_area = None #Entire game area
game_over = True
start = False #Whether to start, when start= True,game_over =GAME OVER is displayed when True
score =0 #Score
orispeed =0.5 #Original speed
speed = orispeed #Current speed
pause = False #time out
last_drop_time = None #Last fall time
last_press_time = None #Last key press time
def _dock():
nonlocal cur_block, next_block, game_area, cur_pos_x, cur_pos_y, game_over, score, speed
for _i inrange(cur_block.start_pos.Y, cur_block.end_pos.Y +1):for _j inrange(cur_block.start_pos.X, cur_block.end_pos.X +1):if cur_block.template[_i][_j]!='.':
game_area[cur_pos_y + _i][cur_pos_x + _j]='0'if cur_pos_y + cur_block.start_pos.Y <=0:
game_over = True
else:
# Calculation elimination
remove_idxs =[]for _i inrange(cur_block.start_pos.Y, cur_block.end_pos.Y +1):ifall(_x =='0'for _x in game_area[cur_pos_y + _i]):
remove_idxs.append(cur_pos_y + _i)if remove_idxs:
# Calculate the score
remove_count =len(remove_idxs)if remove_count ==1:
score +=100
elif remove_count ==2:
score +=300
elif remove_count ==3:
score +=700
elif remove_count ==4:
score +=1500
speed = orispeed -0.03*(score // 10000)
# eliminate
_ i = _j = remove_idxs[-1]while _i =0:while _j in remove_idxs:
_ j -=1if _j <0:
game_area[_i]=['.']* BLOCK_WIDTH
else:
game_area[_i]= game_area[_j]
_ i -=1
_ j -=1
cur_block = next_block
next_block = blocks.get_block()
cur_pos_x, cur_pos_y =(BLOCK_WIDTH - cur_block.end_pos.X -1)// 2, -1 - cur_block.end_pos.Y
def _judge(pos_x, pos_y, block):
nonlocal game_area
for _i inrange(block.start_pos.Y, block.end_pos.Y +1):if pos_y + block.end_pos.Y = BLOCK_HEIGHT:return False
for _j inrange(block.start_pos.X, block.end_pos.X +1):if pos_y + _i =0 and block.template[_i][_j]!='.' and game_area[pos_y + _i][pos_x + _j]!='.':return False
return True
while True:for event in pygame.event.get():if event.type == QUIT:
sys.exit()
elif event.type == KEYDOWN:if event.key == K_RETURN:if game_over:
start = True
game_over = False
score =0
last_drop_time = time.time()
last_press_time = time.time()
game_area =[['.']* BLOCK_WIDTH for _ inrange(BLOCK_HEIGHT)]
cur_block = blocks.get_block()
next_block = blocks.get_block()
cur_pos_x, cur_pos_y =(BLOCK_WIDTH - cur_block.end_pos.X -1)// 2, -1 - cur_block.end_pos.Y
elif event.key == K_SPACE:if not game_over:
pause = not pause
elif event.key in(K_w, K_UP):
# Spin
# In fact, I don’t remember very clearly, such as
# .0.
# .00
# ..0
# Can this be rotated when it is on the far right side? I tried the Tetris on the Internet, but it can’t be rotated. Here we will do it as “Can’t rotate”
# We made a lot of blanks when designing the shape, so we only need to specify that the entire shape, including the blank part, is in the game area before it can be rotated.
if0<= cur_pos_x <= BLOCK_WIDTH -len(cur_block.template[0]):
_ next_block = blocks.get_next_block(cur_block)if_judge(cur_pos_x, cur_pos_y, _next_block):
cur_block = _next_block
if event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:if not game_over and not pause:if time.time()- last_press_time 0.1:
last_press_time = time.time()if cur_pos_x - cur_block.start_pos.X:if_judge(cur_pos_x -1, cur_pos_y, cur_block):
cur_pos_x -=1if event.key == pygame.K_RIGHT:if not game_over and not pause:if time.time()- last_press_time 0.1:
last_press_time = time.time()
# Cannot remove right border
if cur_pos_x + cur_block.end_pos.X +1< BLOCK_WIDTH:if_judge(cur_pos_x +1, cur_pos_y, cur_block):
cur_pos_x +=1if event.key == pygame.K_DOWN:if not game_over and not pause:if time.time()- last_press_time 0.1:
last_press_time = time.time()if not _judge(cur_pos_x, cur_pos_y +1, cur_block):_dock()else:
last_drop_time = time.time()
cur_pos_y +=1_draw_background(screen)_draw_game_area(screen, game_area)_draw_gridlines(screen)_draw_info(screen, font1, font_pos_x, font1_height, score)
# Draw the next box in the display information
_ draw_block(screen, next_block, font_pos_x,30+(font1_height +6)*5,0,0)if not game_over:
cur_drop_time = time.time()if cur_drop_time - last_drop_time speed:if not pause:
# It should not be judged when it is falling. When we play Tetris, we can move left and right when the cube falls to the bottom.
if not _judge(cur_pos_x, cur_pos_y +1, cur_block):_dock()else:
last_drop_time = cur_drop_time
cur_pos_y +=1else:if start:print_text(screen, font2,(SCREEN_WIDTH - gameover_size[0])// 2, (SCREEN_HEIGHT - gameover_size[1]) // 2,'GAME OVER', RED)
# Draw the current falling square
_ draw_block(screen, cur_block,0,0, cur_pos_x, cur_pos_y)
pygame.display.flip()
# Draw background
def _draw_background(screen):
# Fill background color
screen.fill(BG_COLOR)
# Draw the game area divider
pygame.draw.line(screen, BORDER_COLOR,(SIZE * BLOCK_WIDTH + BORDER_WIDTH // 2, 0),(SIZE * BLOCK_WIDTH + BORDER_WIDTH // 2, SCREEN_HEIGHT), BORDER_WIDTH)
# Draw grid lines
def _draw_gridlines(screen):
# Draw grid lines and vertical lines
for x inrange(BLOCK_WIDTH):
pygame.draw.line(screen, BLACK,(x * SIZE,0),(x * SIZE, SCREEN_HEIGHT),1)
# Draw grid lines
for y inrange(BLOCK_HEIGHT):
pygame.draw.line(screen, BLACK,(0, y * SIZE),(BLOCK_WIDTH * SIZE, y * SIZE),1)
# Draw the fallen square
def _draw_game_area(screen, game_area):if game_area:for i, row inenumerate(game_area):for j, cell inenumerate(row):if cell !='.':
pygame.draw.rect(screen, BLOCK_COLOR,(j * SIZE, i * SIZE, SIZE, SIZE),0)
# Draw a single square
def _draw_block(screen, block, offset_x, offset_y, pos_x, pos_y):if block:for i inrange(block.start_pos.Y, block.end_pos.Y +1):for j inrange(block.start_pos.X, block.end_pos.X +1):if block.template[i][j]!='.':
pygame.draw.rect(screen, BLOCK_COLOR,(offset_x +(pos_x + j)* SIZE, offset_y +(pos_y + i)* SIZE, SIZE, SIZE),0)
# Draw score and other information
def _draw_info(screen, font, pos_x, font_height, score):print_text(screen, font, pos_x,10, f'Score: ')print_text(screen, font, pos_x,10+ font_height +6, f'{score}')print_text(screen, font, pos_x,20+(font_height +6)*2, f'speed: ')print_text(screen, font, pos_x,20+(font_height +6)*3, f'{score // 10000}')print_text(screen, font, pos_x,30+(font_height +6)*4, f'next:')if __name__ =='__main__':main()
Game screenshot
running result
For more exciting articles on Tetris, please click on the topic: Tetris Game Collection to learn.
More interesting classic mini game implementation topics, also share with you:
C++ classic games summary
Python classic games summary
python tetris game collection
JavaScript classic games are constantly playing
Summary of classic java games
JavaScript classic games summary
The above is the whole content of this article, I hope it will be helpful to everyone's study.
Recommended Posts