#turtle 绘制樱花树(可能需本地运行)
import turtle as t
import random
t.setup(800, 600)
t.bgcolor("white")
t.colormode(255)
t.speed(0)
t.hideturtle()
def draw_branch(length):
if length < 10:
t.color(255, 192, 203) # 粉色花瓣
t.begin_fill()
t.circle(3)
t.end_fill()
t.color(139, 69, 19) # 还原树枝颜色
return
t.pensize(max(1, length/10))
t.color(139, 69, 19) # 棕色枝干
t.forward(length)
ang = random.randint(15, 30)
dec = random.uniform(0.7, 0.8)
t.right(ang)
draw_branch(length * dec)
t.left(2*ang)
draw_branch(length * dec)
t.right(ang)
t.backward(length)
t.left(90)
t.up()
t.backward(200)
t.down()
draw_branch(100)
t.done()
import pygame
import random
import time
# 初始化pygame
pygame.init()
# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
GRID_SIZE = 30
GRID_WIDTH = 10
GRID_HEIGHT = 20
SIDEBAR_WIDTH = 200
# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 120, 255)
YELLOW = (255, 255, 0)
PURPLE = (180, 0, 255)
CYAN = (0, 255, 255)
ORANGE = (255, 165, 0)
GRAY = (128, 128, 128)
BORDER_COLOR = (50, 50, 50)
# 方块形状定义
SHAPES = [
[[1, 1, 1, 1]], # I
[[1, 1], [1, 1]], # O
[[1, 1, 1], [0, 1, 0]], # T
[[1, 1, 1], [1, 0, 0]], # L
[[1, 1, 1], [0, 0, 1]], # J
[[0, 1, 1], [1, 1, 0]], # S
[[1, 1, 0], [0, 1, 1]] # Z
]
# 方块颜色
SHAPE_COLORS = [CYAN, YELLOW, PURPLE, ORANGE, BLUE, GREEN, RED]
# 创建游戏窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Tetris")
# 游戏时钟
clock = pygame.time.Clock()
# 字体
font = pygame.font.SysFont(None, 36)
small_font = pygame.font.SysFont(None, 24)
class Tetromino:
def __init__(self):
self.shape_index = random.randint(0, len(SHAPES) - 1)
self.shape = SHAPES[self.shape_index]
self.color = SHAPE_COLORS[self.shape_index]
self.x = GRID_WIDTH // 2 - len(self.shape[0]) // 2
self.y = 0
def rotate(self):
# 旋转方块 (转置然后反转每一行)
rotated = [[self.shape[y][x] for y in range(len(self.shape)-1, -1, -1)]
for x in range(len(self.shape[0]))]
return rotated
class TetrisGame:
def __init__(self):
self.board = [[0 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.level = 1
self.lines_cleared = 0
self.paused = False
self.fall_speed = 0.5 # 初始下落速度(秒)
self.last_fall_time = time.time()
def new_piece(self):
self.current_piece = self.next_piece
self.next_piece = Tetromino()
# 检查游戏是否结束
if self.check_collision(self.current_piece.shape, self.current_piece.x, self.current_piece.y):
self.game_over = True
def check_collision(self, shape, x, y):
for i in range(len(shape)):
for j in range(len(shape[0])):
if shape[i][j]:
if (y + i >= GRID_HEIGHT or
x + j < 0 or
x + j >= GRID_WIDTH or
(y + i >= 0 and self.board[y + i][x + j])):
return True
return False
def merge_piece(self):
for i in range(len(self.current_piece.shape)):
for j in range(len(self.current_piece.shape[0])):
if self.current_piece.shape[i][j]:
if self.current_piece.y + i >= 0: # 确保不在顶部之外
self.board[self.current_piece.y + i][self.current_piece.x + j] = self.current_piece.color
def clear_lines(self):
lines_to_clear = []
for i in range(GRID_HEIGHT):
if all(self.board[i]):
lines_to_clear.append(i)
for line in lines_to_clear:
del self.board[line]
self.board.insert(0, [0 for _ in range(GRID_WIDTH)])
# 更新分数
if lines_to_clear:
self.lines_cleared += len(lines_to_clear)
self.score += [100, 300, 500, 800][min(len(lines_to_clear) - 1, 3)] * self.level
# 更新等级和下落速度
self.level = self.lines_cleared // 10 + 1
self.fall_speed = max(0.05, 0.5 - (self.level - 1) * 0.05)
def move(self, dx, dy):
if not self.check_collision(self.current_piece.shape, self.current_piece.x + dx, self.current_piece.y + dy):
self.current_piece.x += dx
self.current_piece.y += dy
return True
return False
def rotate_piece(self):
rotated = self.current_piece.rotate()
if not self.check_collision(rotated, self.current_piece.x, self.current_piece.y):
self.current_piece.shape = rotated
return True
return False
def drop(self):
while self.move(0, 1):
pass
self.merge_piece()
self.clear_lines()
self.new_piece()
def update(self):
if self.paused or self.game_over:
return
current_time = time.time()
if current_time - self.last_fall_time > self.fall_speed:
if not self.move(0, 1):
self.merge_piece()
self.clear_lines()
self.new_piece()
self.last_fall_time = current_time
def draw(self):
screen.fill(BLACK)
# 绘制游戏区域边框
pygame.draw.rect(screen, BORDER_COLOR,
(GRID_SIZE, GRID_SIZE,
GRID_WIDTH * GRID_SIZE,
GRID_HEIGHT * GRID_SIZE), 2)
# 绘制已落下的方块
for i in range(GRID_HEIGHT):
for j in range(GRID_WIDTH):
if self.board[i][j]:
pygame.draw.rect(screen, self.board[i][j],
(j * GRID_SIZE + GRID_SIZE + 1,
i * GRID_SIZE + GRID_SIZE + 1,
GRID_SIZE - 2, GRID_SIZE - 2))
# 绘制当前方块
if not self.game_over:
for i in range(len(self.current_piece.shape)):
for j in range(len(self.current_piece.shape[0])):
if self.current_piece.shape[i][j]:
pygame.draw.rect(screen, self.current_piece.color,
((self.current_piece.x + j) * GRID_SIZE + GRID_SIZE + 1,
(self.current_piece.y + i) * GRID_SIZE + GRID_SIZE + 1,
GRID_SIZE - 2, GRID_SIZE - 2))
# 绘制侧边栏
sidebar_x = GRID_WIDTH * GRID_SIZE + GRID_SIZE * 2
# 绘制下一个方块预览
next_text = font.render("Next:", True, WHITE)
screen.blit(next_text, (sidebar_x, GRID_SIZE))
# 绘制下一个方块
for i in range(len(self.next_piece.shape)):
for j in range(len(self.next_piece.shape[0])):
if self.next_piece.shape[i][j]:
pygame.draw.rect(screen, self.next_piece.color,
(sidebar_x + j * GRID_SIZE,
GRID_SIZE * 3 + i * GRID_SIZE,
GRID_SIZE - 2, GRID_SIZE - 2))
# 绘制分数
score_text = font.render(f"Score: {self.score}", True, WHITE)
screen.blit(score_text, (sidebar_x, GRID_SIZE * 8))
# 绘制等级
level_text = font.render(f"Level: {self.level}", True, WHITE)
screen.blit(level_text, (sidebar_x, GRID_SIZE * 10))
# 绘制已消除行数
lines_text = font.render(f"Lines: {self.lines_cleared}", True, WHITE)
screen.blit(lines_text, (sidebar_x, GRID_SIZE * 12))
# 绘制控制说明
controls_y = GRID_SIZE * 14
controls = [
"Controls:",
"Left/Right: Move",
"Up: Rotate",
"Down: Speed up",
"Space: Drop",
"P: Pause/Resume"
]
for i, text in enumerate(controls):
control_text = small_font.render(text, True, WHITE)
screen.blit(control_text, (sidebar_x, controls_y + i * 25))
# 如果游戏暂停,显示暂停文本
if self.paused:
pause_text = font.render("PAUSED", True, WHITE)
text_rect = pause_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2))
screen.blit(pause_text, text_rect)
# 如果游戏结束,显示游戏结束文本
if self.game_over:
game_over_text = font.render("GAME OVER", True, RED)
restart_text = font.render("Press R to restart", True, WHITE)
text_rect = game_over_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 - 20))
restart_rect = restart_text.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 20))
screen.blit(game_over_text, text_rect)
screen.blit(restart_text, restart_rect)
# 创建游戏实例
game = TetrisGame()
# 游戏主循环
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if not game.game_over:
if event.key == pygame.K_LEFT:
game.move(-1, 0)
elif event.key == pygame.K_RIGHT:
game.move(1, 0)
elif event.key == pygame.K_DOWN:
game.move(0, 1)
elif event.key == pygame.K_UP:
game.rotate_piece()
elif event.key == pygame.K_SPACE:
game.drop()
elif event.key == pygame.K_p:
game.paused = not game.paused
if event.key == pygame.K_r and game.game_over:
# 重新开始游戏
game = TetrisGame()
# 更新游戏状态
game.update()
# 绘制游戏
game.draw()
# 更新显示
pygame.display.flip()
# 控制游戏帧率
clock.tick(60)
# 退出游戏
pygame.quit()
基本功能:
控制方式:
游戏机制:
Tetromino类:表示俄罗斯方块的单个形状,包括形状数据、颜色和位置信息。
TetrisGame类:游戏主逻辑,包含:
游戏主循环:
这个简化版的俄罗斯方块游戏包含了所有基本功能,代码结构清晰,易于理解和扩展。
本章系统讲解了函数(定义/调用/参数/返回值、类型、递归)与高阶函数(map/filter/reduce),并介绍了模块(导入、标准库、自定义、包、__name__)的用法,以及常见错误与排查。最后给出 turtle 与 pygame 的可视化示例提示与代码框架,便于结合大语言模型进行实践。