16,598
社区成员
发帖
与我相关
我的任务
分享
import tkinter as tk
import random
from time import sleep
class Tetris:
def __init__(self, master):
self.master = master
self.master.title("俄罗斯方块")
self.score = 0
self.level = 1
self.delay = 500
self.board = [[0] * 10 for _ in range(20)]
self.colors = ['black', 'cyan', 'blue', 'orange', 'yellow', 'green', 'purple', 'red']
# 游戏区域
self.canvas = tk.Canvas(master, width=300, height=600, bg='white')
self.canvas.pack(side= tk.LEFT)
# 信息面板
self.info_canvas = tk.Canvas(master, width=150, height=600)
self.info_canvas.pack(side= tk.RIGHT)
# 初始化游戏
self.current_piece = None
self.next_piece = self.create_new_piece()
self.game_over = False
self.master.bind("<Key>", self.key_pressed)
self.update_display()
self.new_piece()
self.fall()
def create_new_piece(self):
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型
[[1, 1, 0], [0, 1, 1]], # S型
[[0, 1, 1], [1, 1, 0]] # Z型
]
return random.choice(shapes)
def new_piece(self):
self.current_piece = {
'shape': self.next_piece,
'color': random.randint(1, 7),
'x': 4,
'y': 0
}
self.next_piece = self.create_new_piece()
def draw_block(self, x, y, color):
self.canvas.create_rectangle(
x * 30, y * 30, (x + 1) * 30, (y + 1) * 30,
fill=self.colors[color], outline="white"
)
def update_display(self):
self.canvas.delete("all")
# 绘制当前棋盘
for y in range(20):
for x in range(10):
if self.board[y][x]:
self.draw_block(x, y, self.board[y][x])
# 绘制当前方块
if self.current_piece:
for y, row in enumerate(self.current_piece['shape']):
for x, cell in enumerate(row):
if cell:
self.draw_block(
self.current_piece['x'] + x,
self.current_piece['y'] + y,
self.current_piece['color']
)
def valid_move(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 >= 10 or
new_y >= 20 or
(new_y >= 0 and self.board[new_y][new_x])):
return False
return True
def rotate_piece(self):
rotated = list(zip(*self.current_piece['shape'][::-1]))
if self.valid_move({'shape': rotated,
'x': self.current_piece['x'],
'y': self.current_piece['y']}, 0, 0):
self.current_piece['shape'] = rotated
def merge_piece(self):
for y, row in enumerate(self.current_piece['shape']):
for x, cell in enumerate(row):
if cell:
self.board[self.current_piece['y'] + y][self.current_piece['x'] + x] = self.current_piece['color']
def clear_lines(self):
lines_to_clear = []
for y in range(20):
if all(self.board[y]):
lines_to_clear.append(y)
for y in lines_to_clear:
del self.board[y]
self.board.insert(0, [0] * 10)
self.score += 100
if self.score // 1000 > self.level - 1:
self.level += 1
self.delay = max(100, 500 - (self.level - 1) * 50)
def key_pressed(self, event):
if self.game_over:
return
if event.keysym == 'Left':
if self.valid_move(self.current_piece, -1, 0):
self.current_piece['x'] -= 1
elif event.keysym == 'Right':
if self.valid_move(self.current_piece, 1, 0):
self.current_piece['x'] += 1
elif event.keysym == 'Down':
if self.valid_move(self.current_piece, 0, 1):
self.current_piece['y'] += 1
elif event.keysym == 'Up':
self.rotate_piece()
elif event.keysym == 'space':
while self.valid_move(self.current_piece, 0, 1):
self.current_piece['y'] += 1
self.update_display()
def fall(self):
if not self.game_over:
if self.valid_move(self.current_piece, 0, 1):
self.current_piece['y'] += 1
else:
self.merge_piece()
self.clear_lines()
if any(self.board[0]):
self.game_over = True
self.canvas.create_text(150, 300, text="游戏结束!", font=('Arial', 32), fill='red')
return
self.new_piece()
self.update_display()
self.master.after(self.delay, self.fall)
root = tk.Tk()
game = Tetris(root)
root.mainloop()