利用pygame实现简单的俄罗斯方块
__author__ = "那位先生Beer" import pygame from pygame.locals import QUIT, KEYUP, K_ESCAPE, KEYDOWN import sys, time, random SCREEN_WIDTH = 640 SCREEN_HEIGHT = 480 BOARD_WIDTH = 10 BLUE = (0, 0, 125) S_SHAPE_TEMPLATE = [['.....', #S形状的模板 '.....', '..cc.', '.cc..', '.....'], ['.....', #S逆时针变化的形状 '..c..', '..cc.', '...c.', '.....']] Z_SHAPE_TEMPLATE = [['.....', #Z形模板 '.....', '.cc..', '..cc.', '.....'], ['.....', '..c..', '.cc..', '.c...', '.....']] I_SHAPE_TEMPLATE = [['..c..', #I型模板 '..c..', '..c..', '..c..', '.....'], ['.....', '.....', 'cccc.', '.....', '.....']] O_SHAPE_TEMPLATE = [['.....', #O型模板 '.....', '.cc..', '.cc..', '.....']] J_SHAPE_TEMPLATE = [['.....', #J型模板 '.c...', '.ccc.', '.....', '.....'], ['.....', '..cc.', '..c..', '..c..', '.....'], ['.....', '.....', '.ccc.', '...c.', '.....'], ['.....', '..c..', '..c..', '.cc..', '.....']] L_SHAPE_TEMPLATE = [['.....', #L型模板 '...c.', '.ccc.', '.....', '.....'], ['.....', '..c..', '..c..', '..cc.', '.....'], ['.....', '.....', '.ccc.', '.c...', '.....'], ['.....', '.cc..', '..c..', '..c..', '.....']] T_SHAPE_TEMPLATE = [['.....', #T型模板 '..c..', '.ccc.', '.....', '.....'], ['.....', '..c..', '..cc.', '..c..', '.....'], ['.....', '.....', '.ccc.', '..c..', '.....'], ['.....', '..c..', '.cc..', '..c..', '.....']] def available_tetris_pieces(): PIECES = {'S': S_SHAPE_TEMPLATE, #PIECES是一个字典,它储存了所有不同的模板(列表)。每个模板都拥有一个形状所有可能的旋转(列表)。 'Z': Z_SHAPE_TEMPLATE, 'J': J_SHAPE_TEMPLATE, 'L': L_SHAPE_TEMPLATE, 'I': I_SHAPE_TEMPLATE, 'O': O_SHAPE_TEMPLATE, 'T': T_SHAPE_TEMPLATE} return PIECES def run_tetris_game(): score = 0 pygame.init() windows_size = (SCREEN_WIDTH, SCREEN_HEIGHT) screen = pygame.display.set_mode(windows_size) pygame.display.set_caption("MyTetris") game_matrix = create_game_matrix() piece = create_piece() last_time_piece_move = time.time() while True: screen.fill((0, 0, 0)) if (time.time() - last_time_piece_move > 0.3): piece['row'] += 1 last_time_piece_move = time.time() draw_moving_piece( screen, piece ) pygame.draw.rect( screen, BLUE, [100, 50, 10 * 20 + 10, 20 * 20 + 10], 5) draw_broard( screen, game_matrix ) listen_to_user_input(game_matrix, piece) if(not isVaildPosition(game_matrix, piece, adjRow = 1)): game_matrix = update_game_matrix(game_matrix, piece) lines_removed = remove_completed_line(game_matrix) score += lines_removed piece = create_piece() draw_score(screen, score) pygame.display.update() for event in pygame.event.get(QUIT): pygame.quit() sys.exit() def draw_broard(screen, matrix): game_matrix_columns = 10 game_matrix_rows = 20 for row in range(game_matrix_rows): for column in range(game_matrix_columns): if matrix[row][column] != '.': draw_single_tetris_box(screen, row, column, (255, 255, 255), (217, 222, 226)) def draw_single_tetris_box(screen, matrix_cell_row, matrix_cell_column, color, shadow_color): origin_x = 100 + 5 + (matrix_cell_column * 20 + 1) origin_y = 50 + 5 + (matrix_cell_row * 20 + 1) pygame.draw.rect(screen, shadow_color, [origin_x, origin_y, 20, 20]) pygame.draw.rect(screen, color, [origin_x, origin_y, 18, 18]) def create_game_matrix(): game_matrix_columns = 10 game_matrix_rows = 20 matrix = [] for i in range(game_matrix_rows): new_row = [] for j in range(game_matrix_columns): new_row.append('.') matrix.append(new_row) return matrix def update_game_matrix(matrix, piece): for row in range(5): for column in range(5): if available_tetris_pieces()[piece["shape"]][piece["rotation"]][row][column] != '.': matrix[piece["row"] + row][piece["column"] + column] = 'c' return matrix def create_piece(): piece = {} random_shape = random.choice(list(available_tetris_pieces().keys())) piece["shape"] = random_shape piece["rotation"] = 0 piece["column"] = 2 piece["row"] = 0 return piece def draw_moving_piece(screen, piece): white_color = (255, 255, 255) gray_color = (217, 222, 226) shape_to_draw = available_tetris_pieces()[piece["shape"]][piece["rotation"]] for row in range(5): for column in range(5): if shape_to_draw[row][column] != '.': draw_single_tetris_box(screen, piece["row"] + row, piece["column"] + column, white_color, gray_color) def listen_to_user_input(game_matrix, piece): for event in pygame.event.get(): if event.type == KEYDOWN: if (event.key == pygame.K_LEFT) and isVaildPosition(game_matrix, piece, adjColumn = -1): piece['column'] -= 1 if (event.key == pygame.K_RIGHT) and isVaildPosition(game_matrix, piece, adjColumn = 1): piece['column'] += 1 if event.key == pygame.K_UP: piece['rotation'] = (piece['rotation'] + 1) % len(available_tetris_pieces()[piece['shape']]) if not isVaildPosition(game_matrix, piece): piece['rotation'] = (piece['rotation'] - 1) % len(available_tetris_pieces()[piece['shape']]) #检查是否为有效位置 def isVaildPosition(game_matrix, piece, adjColumn = 0, adjRow = 0): # if not (column >= 0 and column < 10 and row < 20 ): # return False # #这里特别巧妙,使用not和返回False,仔细品味一下 # if game_matrix[row][column] != '.': # return False # return True piece_shape = available_tetris_pieces()[piece["shape"]][piece["rotation"]] for row in range(5): for column in range(5): if piece_shape[row][column] == ".": continue if not isOnBoard(piece["row"] + row + adjRow, piece["column"] + column + adjColumn): return False if game_matrix[piece["row"] + row + adjRow][piece["column"] + column + adjColumn] != '.': return False return True def isOnBoard(row, column): if column >= 0 and column < 10 and row < 20: return True return False def is_line_complete(game_matrix, row): for column in range(10): if game_matrix[row][column] == '.': return False return True def remove_completed_line(game_matrix): num_lines_remove = 0 for row in range(20): if is_line_complete(game_matrix, row): for row_to_move_down in range(row, 0, -1): for column in range(10): game_matrix[row_to_move_down ][column] = game_matrix[row_to_move_down - 1][column] for x in range(10): game_matrix[0][x] = '.' num_lines_remove += 1 return num_lines_remove def draw_score(screen, score): font = pygame.font.Font("freesansbold.ttf", 18) scoreSurf = font.render('Score : %s'%score, True, (255, 255, 255)) screen.blit(scoreSurf, (640 - 150, 20)) run_tetris_game()
https://www.bilibili.com/video/av54227194?t=1858 大家可以去看看这个视频连接,一步一步去实现这些小功能。有利于新手可以从零开始,培养一种解决问题的思路。

浙公网安备 33010602011771号