如果觉得本篇教程不错,可以点个免费的赞和关注,感谢大家了😗😘
import pygame
import random
import sys
# 初始化pygame
pygame.init()
# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 700
GRID_SIZE = 30
GRID_WIDTH = 10
GRID_HEIGHT = 20
SIDEBAR_WIDTH = 240 # 加宽侧边栏,提升显示空间
# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (50, 50, 50) # 深灰色,提升侧边栏质感
LIGHT_GRAY = (100, 100, 100)
COLORS = [
(0, 255, 255), # Cyan (I)
(255, 255, 0), # Yellow (O)
(128, 0, 128), # Purple (T)
(255, 165, 0), # Orange (L)
(0, 0, 255), # Blue (J)
(0, 255, 0), # Green (S)
(255, 0, 0) # Red (Z)
]
# 方块形状定义
SHAPES = [
[[1, 1, 1, 1]], # I
[[1, 1], [1, 1]], # O
[[0, 1, 0], [1, 1, 1]], # T
[[0, 0, 1], [1, 1, 1]], # L
[[1, 0, 0], [1, 1, 1]], # J
[[0, 1, 1], [1, 1, 0]], # S
[[1, 1, 0], [0, 1, 1]] # Z
]
# 设置窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("俄罗斯方块")
# 字体设置(选择支持中文的字体,如“SimHei”)
try:
font = pygame.font.SysFont(["SimHei", "Microsoft YaHei", "Arial"], 36)
large_font = pygame.font.SysFont(["SimHei", "Microsoft YaHei", "Arial"], 72)
small_font = pygame.font.SysFont(["SimHei", "Microsoft YaHei", "Arial"], 24)
except:
font = pygame.font.Font(None, 36)
large_font = pygame.font.Font(None, 72)
small_font = pygame.font.Font(None, 24)
class Tetromino:
def __init__(self):
self.shape = random.choice(SHAPES)
self.color = COLORS[SHAPES.index(self.shape)]
self.x = GRID_WIDTH // 2 - len(self.shape[0]) // 2
self.y = 0
def rotate(self):
# 旋转方块(转置矩阵并反转每一行)
rotated = list(zip(*self.shape[::-1]))
self.shape = [list(row) for row in rotated]
class Game:
def __init__(self):
self.grid = [[BLACK for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
self.current_piece = Tetromino()
self.next_piece = Tetromino()
self.game_over = False
self.score = 0
self.speed = 500 # 毫秒
self.last_fall_time = pygame.time.get_ticks()
def new_piece(self):
self.current_piece = self.next_piece
self.next_piece = Tetromino()
# 检查游戏是否结束
if self.check_collision(self.current_piece, 0, 0):
self.game_over = True
def check_collision(self, piece, dx, dy):
for y, row in enumerate(piece.shape):
for x, cell in enumerate(row):
if cell:
new_x = piece.x + x + dx
new_y = piece.y + y + dy
if (new_x < 0 or new_x >= GRID_WIDTH or
new_y >= GRID_HEIGHT or
(new_y >= 0 and self.grid[new_y][new_x] != BLACK)):
return True
return False
def lock_piece(self):
for y, row in enumerate(self.current_piece.shape):
for x, cell in enumerate(row):
if cell:
self.grid[self.current_piece.y + y][self.current_piece.x + x] = self.current_piece.color
self.clear_lines()
self.new_piece()
def clear_lines(self):
lines_cleared = 0
new_grid = []
for row in self.grid:
if BLACK not in row:
lines_cleared += 1
else:
new_grid.append(row)
# 在顶部添加新的空行
for _ in range(lines_cleared):
new_grid.insert(0, [BLACK for _ in range(GRID_WIDTH)])
self.grid = new_grid
# 根据消除的行数加分
if lines_cleared == 1:
self.score += 100
elif lines_cleared == 2:
self.score += 300
elif lines_cleared == 3:
self.score += 500
elif lines_cleared >= 4:
self.score += 800
def move(self, dx):
if not self.game_over and not self.check_collision(self.current_piece, dx, 0):
self.current_piece.x += dx
def rotate_piece(self):
if not self.game_over:
original_shape = self.current_piece.shape
self.current_piece.rotate()
# 如果旋转后碰撞,尝试移动来避免碰撞
if self.check_collision(self.current_piece, 0, 0):
# 尝试向右移动
if not self.check_collision(self.current_piece, 1, 0):
self.current_piece.x += 1
# 尝试向左移动
elif not self.check_collision(self.current_piece, -1, 0):
self.current_piece.x -= 1
# 尝试向上移动
elif not self.check_collision(self.current_piece, 0, -1):
self.current_piece.y -= 1
# 如果都不行,恢复原来的形状
else:
self.current_piece.shape = original_shape
def drop(self):
if not self.game_over and not self.check_collision(self.current_piece, 0, 1):
self.current_piece.y += 1
return True
else:
self.lock_piece()
return False
def hard_drop(self):
if not self.game_over:
while self.drop():
pass
def update(self):
current_time = pygame.time.get_ticks()
if current_time - self.last_fall_time > self.speed and not self.game_over:
self.drop()
self.last_fall_time = current_time
def draw(self, screen):
# 绘制游戏区域背景
pygame.draw.rect(screen, GRAY,
(0, 0, GRID_WIDTH * GRID_SIZE, GRID_HEIGHT * GRID_SIZE), 2)
# 绘制网格
for y in range(GRID_HEIGHT):
for x in range(GRID_WIDTH):
pygame.draw.rect(screen, self.grid[y][x],
(x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE - 1, GRID_SIZE - 1))
# 绘制当前方块
for y, row in enumerate(self.current_piece.shape):
for x, cell in enumerate(row):
if cell:
draw_x = (self.current_piece.x + x) * GRID_SIZE
draw_y = (self.current_piece.y + y) * GRID_SIZE
pygame.draw.rect(screen, self.current_piece.color,
(draw_x, draw_y, GRID_SIZE - 1, GRID_SIZE - 1))
# ---------- 优化右侧边栏绘制 ----------
sidebar_x = GRID_WIDTH * GRID_SIZE
# 绘制侧边栏背景
pygame.draw.rect(screen, LIGHT_GRAY,
(sidebar_x, 0, SIDEBAR_WIDTH, SCREEN_HEIGHT))
# 绘制分数区域
score_text = font.render(f"分数: {self.score}", True, WHITE)
screen.blit(score_text, (sidebar_x + 20, 20))
# 绘制“下一个方块”区域
next_title = font.render("下一个:", True, WHITE)
screen.blit(next_title, (sidebar_x + 20, 100))
# 计算下一个方块的绘制位置(居中显示)
next_shape_height = len(self.next_piece.shape) * GRID_SIZE
next_shape_width = len(self.next_piece.shape[0]) * GRID_SIZE
start_y = 150 + (120 - next_shape_height) // 2 # 增加垂直空间
start_x = sidebar_x + (SIDEBAR_WIDTH - next_shape_width) // 2
for y, row in enumerate(self.next_piece.shape):
for x, cell in enumerate(row):
if cell:
draw_x = start_x + x * GRID_SIZE
draw_y = start_y + y * GRID_SIZE
pygame.draw.rect(screen, self.next_piece.color,
(draw_x, draw_y, GRID_SIZE - 1, GRID_SIZE - 1))
# 绘制控制说明区域
control_title = font.render("操作说明:", True, WHITE)
screen.blit(control_title, (sidebar_x + 20, 300))
controls = [
"← →:移动方块",
"↑:旋转方块",
"↓:加速下落",
"空格:直接落底",
"R:重新开始"
]
for i, text in enumerate(controls):
control_text = small_font.render(text, True, WHITE)
screen.blit(control_text, (sidebar_x + 20, 350 + i * 40))
# 游戏结束时显示文字
if self.game_over:
overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
overlay.fill((0, 0, 0, 180))
screen.blit(overlay, (0, 0))
game_over_text = large_font.render("游戏结束!", True, WHITE)
restart_text = font.render("按 R 重新开始", True, WHITE)
screen.blit(game_over_text,
(SCREEN_WIDTH // 2 - game_over_text.get_width() // 2,
SCREEN_HEIGHT // 2 - 50))
screen.blit(restart_text,
(SCREEN_WIDTH // 2 - restart_text.get_width() // 2,
SCREEN_HEIGHT // 2 + 50))
def main():
clock = pygame.time.Clock()
game = Game()
running = True
while running:
screen.fill(BLACK)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
game.move(-1)
elif event.key == pygame.K_RIGHT:
game.move(1)
elif event.key == pygame.K_DOWN:
game.drop()
elif event.key == pygame.K_UP:
game.rotate_piece()
elif event.key == pygame.K_SPACE:
game.hard_drop()
elif event.key == pygame.K_r:
game = Game()
game.update()
game.draw(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
if __name__ == "__main__":
main()
新建一个项目,然后复制上面的代码,粘贴在.py文件中,
安装运行所需的游戏库

开始运行,就能游玩了
以下为演示视频(玩的比较菜🤣)
有什么问题可以在评论区打出来,可以把自己的得分发在评论区中,看看有没有大神🤗