|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 pyzyd 于 2025-7-21 12:35 编辑
代码实现:
感觉写了一坨屎山
源代码:
- import tkinter as tk
- from tkinter import messagebox
- import random
- import time
- class Game(tk.Tk):
- def __init__(self):
- tk.Tk.__init__(self)
- self.title('Tetris')
- # 固定边框
- self.resizable(False,False)
- # 设置边长、像素
- self.width = 12
- self.height = 20
- self.px = 30
- # 设置不同形状的格子
- self.shapes = {
- 'O': [(-1, -1), (0, -1), (-1, 0), (0, 0)],
- 'I': [(0, 1), (0, 0), (0, -1), (0, -2)],
- 'T': [(-1, -1), (0, -1), (0, 0), (1, -1)],
- 'Z': [(-1, 0), (0, 0), (0, 1), (1, 1)],
- 'S': [(-1, 1), (0, 1), (0, 0), (1, 0)],
- 'L': [(1, 1), (0, 1), (0, 0), (0, -1)],
- 'J': [(-1, 1), (0, 1), (0, 0), (0, -1)],
- }
- # 设置不同格子的颜色
- self.colors = ['#FF0000', '#FF7F00', "#D4D432", "#00FF00", "#0000FF", '#4B008B', "#D3007F"]
- self.shape_index = random.choice(list(self.shapes.keys()))
- self.shape_color = random.choice(self.colors)
- self.shape = self.shapes[self.shape_index]
- # 表示固定的格子
- self.fixed_shape = {}
- self.fixed_set = set()
- # 创建画布
- self.canvas = tk.Canvas(
- self, width=self.width*self.px,
- height=self.height*self.px)
- self.canvas.grid(row=0,column=0,columnspan=3,rowspan=4, padx=10, pady=10)
- self.btnr = tk.Button(self, text='<', command=lambda:self.move((-1, 0)))
- self.btnr.grid(row=4, column=0, padx=10, pady=10, sticky='nsew')
- self.btn_rotate = tk.Button(self, text='-', command=self.rotate_shape)
- self.btn_rotate.grid(row=4, column=1, padx=10, pady=10, sticky='nsew')
- self.btnd = tk.Button(self, text='v', command=lambda:self.move((0, 1)))
- self.btnd.grid(row=5, column=1, padx=10, pady=10, sticky='nsew')
- self.btnl = tk.Button(self, text='>', command=lambda:self.move((1, 0)))
- self.btnl.grid(row=4, column=2, padx=10, pady=10, sticky='nsew')
- self.score = 0
- self.v = tk.StringVar()
- self.v.set(f'当前分数:{self.score}')
- self.label1 = tk.Label(self, textvariable=self.v,font=('微软雅黑', 24))
- self.label1.grid(row=0, column=3, padx=10, pady=10, sticky='nsew')
- self.best_score = self.read_best_score()
- self.v2 = tk.StringVar()
- self.v2.set(f'最高分:{self.best_score}')
- self.label2 = tk.Label(self, textvariable=self.v2,font=('微软雅黑', 24))
- self.label2.grid(row=1, column=3, padx=10, pady=10, sticky='nsew')
- self.text = tk.Text(self, height=10, width=20, font=('微软雅黑', 18))
- self.text.grid(row=2, column=3, padx=10, pady=10, sticky='nsew')
- self.text.insert(tk.END, '游戏规则:\n')
- self.text.insert(tk.END, '1. 使用方向键控制方块的移动\n')
- self.text.insert(tk.END, '2. 使用方向上键(Up键)旋转方块\n')
- self.text.insert(tk.END, '3. 消除满行即可获得分数\n')
- self.text.insert(tk.END, '4. 超出画布即游戏结束\n')
- self.bind('<Left>', lambda event:self.move((-1, 0)))
- self.bind('<Right>', lambda event:self.move((1, 0)))
- self.bind('<Up>', lambda event:self.rotate_shape())
- self.bind('<Down>', lambda event:self.move((0, 1)))
-
- # 设置画布的点集(范围)
- self.canvas_set = set()
- for i in range(0, self.width):
- for j in range(0, self.height):
- self.canvas_set.add((i,j))
-
- # 运行游戏
- self.run_game()
- # 读取最佳分数
- def read_best_score(self):
- """读取最高分"""
- try:
- # 打开best_score.txt文件,以只读模式
- with open('best_score.txt', 'r') as f:
- # 读取文件内容,并转换为整数
- return int(f.read())
- except:
- # 如果出现异常,返回0
- return 0
-
- # 定义一个方法,用于将最高分写入文件
- def write_best_score(self, score):
- """写入最高分"""
- # 打开文件best_score.txt,以写入模式
- with open('best_score.txt', 'w') as f:
- # 将最高分转换为字符串,并写入文件
- f.write(str(score))
- # 运行游戏
- def run_game(self):
- # 初始化游戏
- self.initialize()
- # 自动下落
- self.auto_down()
- # 进入主循环
- self.mainloop()
- def initialize(self):
- """初始化界面"""
- # 绘制背景
- self.draw_bg()
- # 生成初始格子
- self.generate_shape()
- # 绘制初始
- self.draw_shape(self.shape, self.x, self.y, self.shape_color)
- def generate_shape(self):
- """生成新的格子"""
- self.shape_index = random.choice(list(self.shapes.keys()))
- self.shape_color = random.choice(self.colors)
- self.shape = self.shapes[self.shape_index]
- # 设置初始位置
- self.x = random.randint(self.width//4, self.width//4*3)
- self.y = -4
-
- def auto_down(self):
- """自动下移"""
- # 翻转方块
- self.flip()
- # 移动方块
- self.move()
- # 每隔500毫秒调用一次auto_down方法
- self.after(500, self.auto_down)
-
- def move(self, direction=(0, 1)):
- """移动格子"""
- # 获取移动方向
- dx, dy = direction
-
- # 更新格子的坐标
- self.x += dx
- self.y += dy
-
- # 如果格子超出边界,则回退到原来的位置
- if self.is_out():
- self.x -= dx
- self.y -= dy
- # 如果格子到达底部,则将格子固定在底部,并生成新的格子
- if self.is_bottom():
- # 如果格子颜色已经在固定格子的集合中,则更新该格子的坐标
- if self.shape_color in self.fixed_shape:
- self.fixed_shape[self.shape_color].update([(self.x+dx,self.y+dy) for dx,dy in self.shape])
- # 如果格子颜色不在固定格子的集合中,则将格子添加到固定格子的集合中
- else:
- self.fixed_shape[self.shape_color] = set([(self.x+dx,self.y+dy) for dx,dy in self.shape])
- # 将格子的坐标添加到固定格子的集合中
- for x, y in self.shape:
- self.fixed_set.add((self.x + x, self.y + y))
- # 生成新的格子
- self.generate_shape()
-
-
- def is_over(self):
- """判断游戏是否结束"""
- for x, y in self.fixed_set:
- if y < 0:
- return True
- return False
- def rotate_shape(self):
- """旋转格子"""
- if self.shape != self.shapes['O']:
- temp = [(-dy, dx) for dx, dy in self.shape]
- for dx, dy in temp:
- if self.x + dx < 0:
- self.x += 1
- elif self.x + dx >= self.width:
- self.x -= 1
- # 检查旋转后的形状是否与已经固定的方块重叠
- if not self.is_overlap():
- self.shape = temp
- def is_overlap(self):
- """检查新的格子是否与已经固定的格子重叠"""
- for dx, dy in self.shape:
- if (self.x + dx, self.y + dy) in self.fixed_set:
- return True
- return False
-
- def is_out(self):
- """判断是否越界"""
- for dx, dy in self.shape:
- if self.x + dx < 0 or self.x + dx >= self.width or self.y + dy >= self.height:
- return True
- if self.is_overlap():
- return True
- return False
-
- def is_bottom(self):
- """判断是否到底"""
- for dx, dy in self.shape:
- if self.y + dy == self.height - 1:
- return True
- if (self.x + dx, self.y + dy + 1) in self.fixed_set:
- return True
- return False
-
- def flip(self):
- """更新画布"""
- # 删除画布上所有元素
- self.canvas.delete("all")
- # 重绘元素
- self.draw_bg()
- y_s = self.is_delete()
- if y_s:
- index_y = y_s[0]
- l = len(y_s)
- self.score += l * 10
- self.v.set(f'当前分数:{self.score}')
- if self.score > self.best_score:
- self.best_score = self.score
- self.v2.set(f'最高分:{self.best_score}')
- self.write_best_score(self.best_score)
- for shape_color, _ in self.fixed_shape.items():
- temp_list = list(_)
- for x, y in _:
- if y < index_y:
- temp_list.remove((x, y))
- temp_list.append((x, y + l))
- self.fixed_set.discard((x, y))
- self.fixed_set.add((x, y + l))
- self.fixed_shape[shape_color] = set(temp_list)
- for shape_color, _ in self.fixed_shape.items():
- for x, y in _:
- self.draw_rect(x, y, shape_color)
- self.draw_shape(self.shape, self.x, self.y, self.shape_color)
- # 判断是否结束
- if self.is_over():
- # 游戏结束
- self.game_over()
-
- def draw_bg(self):
- """"绘制像素"""
- # 设置背景像素颜色
- fill = '#CCCCCC'
- outline = 'white'
- px = self.px
- for x, y in list(self.canvas_set):
- self.draw_rect(x, y, fill, outline)
- def draw_rect(self, x, y, color, outline="white"):
- """"绘制像素"""
- px = self.px
- # 绘制像素
- self.canvas.create_rectangle(
- x * px, y * px,
- (x + 1) * px, (y + 1) * px,
- fill=color, outline=outline
- )
- def draw_shape(self, shape, x, y, color):
- """绘制不同的格子"""
- for dx, dy in shape:
- self.draw_rect(x + dx, y + dy, color)
- def is_delete(self):
- """判断是否可以删除"""
- y_s = []
- for y in range(self.height):
- if all((x, y) in self.fixed_set for x in range(self.width)):
- for x in range(self.width):
- self.fixed_set.remove((x, y))
- for _ in self.fixed_shape.values():
- _.discard((x, y))
- y_s.append(y)
- return y_s
- def game_over(self):
- """游戏结束"""
- self.canvas.create_text(
- self.width * self.px / 2,
- self.height * self.px / 2,
- text="Game Over",
- font=("Arial", 36),
- fill="red"
- )
- self.canvas.update()
- time.sleep(1)
- yesno = messagebox.askyesno("提示", "是否重新开始游戏?")
- self.destroy()
- if yesno:
- self.__init__()
- if __name__ == '__main__':
- game = Game()
复制代码
打包好的文件:
https://wwrx.lanzoum.com/iAsuh31hj84d
密码:b5pi
|
评分
-
查看全部评分
|