parent
fcbc6d53fe
commit
7f6a6724fb
@ -0,0 +1,225 @@
|
||||
import tkinter as tk
|
||||
import random
|
||||
import json
|
||||
import os
|
||||
|
||||
class Game2048:
|
||||
def __init__(self):
|
||||
self.window = tk.Tk()
|
||||
self.window.title("2048")
|
||||
self.start_screen()
|
||||
|
||||
# 启动画面,包含游戏标题和开始按钮
|
||||
def start_screen(self):
|
||||
self.start_frame = tk.Frame(self.window, bg='azure3')
|
||||
self.start_frame.pack(fill="both", expand=True)
|
||||
title_label = tk.Label(self.start_frame, text="2048", font=("arial", 48, "bold"), bg='azure3')
|
||||
title_label.pack(pady=50)
|
||||
start_button = tk.Button(self.start_frame, text="Start Game", font=("arial", 24, "bold"), command=self.start_game)
|
||||
start_button.pack(pady=20)
|
||||
self.window.mainloop()
|
||||
|
||||
# 开始游戏,初始化游戏界面和变量
|
||||
def start_game(self):
|
||||
self.start_frame.destroy()
|
||||
self.game_area = tk.Frame(self.window, bg='azure3')
|
||||
self.board = []
|
||||
self.grid_cells = []
|
||||
self.score = 0
|
||||
self.high_score = 0
|
||||
self.load_high_score()
|
||||
self.init_grid()
|
||||
self.init_matrix()
|
||||
self.update_grid_cells()
|
||||
self.window.bind("<Key>", self.key_down)
|
||||
self.game_area.pack()
|
||||
|
||||
# 从文件中加载最高分
|
||||
def load_high_score(self):
|
||||
if os.path.exists("high_score.json"):
|
||||
with open("high_score.json", "r") as file:
|
||||
self.high_score = json.load(file)
|
||||
|
||||
# 保存最高分到文件
|
||||
def save_high_score(self):
|
||||
with open("high_score.json", "w") as file:
|
||||
json.dump(self.high_score, file)
|
||||
|
||||
# 初始化游戏网格
|
||||
def init_grid(self):
|
||||
background = tk.Frame(self.game_area, bg='azure3', width=400, height=500)
|
||||
background.grid(padx=(10, 10), pady=(10, 10))
|
||||
self.score_label = tk.Label(self.window, text=f"Score: {self.score}", font=("arial", 24, "bold"))
|
||||
self.score_label.pack()
|
||||
self.high_score_label = tk.Label(self.window, text=f"High Score: {self.high_score}", font=("arial", 24, "bold"))
|
||||
self.high_score_label.pack()
|
||||
for i in range(4):
|
||||
grid_row = []
|
||||
for j in range(4):
|
||||
cell = tk.Frame(
|
||||
background,
|
||||
bg='azure4',
|
||||
width=100,
|
||||
height=100
|
||||
)
|
||||
cell.grid(row=i, column=j, padx=5, pady=5)
|
||||
t = tk.Label(master=cell, text="", bg='azure4', justify=tk.CENTER, font=("arial", 22, "bold"), width=4, height=2)
|
||||
t.grid()
|
||||
grid_row.append(t)
|
||||
self.grid_cells.append(grid_row)
|
||||
|
||||
# 初始化矩阵
|
||||
def init_matrix(self):
|
||||
self.board = [[0] * 4 for _ in range(4)]
|
||||
self.add_new_tile()
|
||||
self.add_new_tile()
|
||||
|
||||
# 在空白位置添加新方块
|
||||
def add_new_tile(self):
|
||||
empty_cells = [(i, j) for i in range(4) for j in range(4) if self.board[i][j] == 0]
|
||||
if empty_cells:
|
||||
i, j = random.choice(empty_cells)
|
||||
self.board[i][j] = 2 if random.random() < 0.9 else 4
|
||||
|
||||
# 更新网格单元格
|
||||
def update_grid_cells(self):
|
||||
for i in range(4):
|
||||
for j in range(4):
|
||||
new_number = self.board[i][j]
|
||||
if new_number == 0:
|
||||
self.grid_cells[i][j].configure(text="", bg='azure4')
|
||||
else:
|
||||
self.grid_cells[i][j].configure(text=str(new_number), bg=self.get_color(new_number))
|
||||
self.score_label.config(text=f"Score: {self.score}")
|
||||
self.high_score_label.config(text=f"High Score: {self.high_score}")
|
||||
self.window.update_idletasks()
|
||||
|
||||
# 获取方块颜色
|
||||
def get_color(self, num):
|
||||
colors = {
|
||||
2: 'azure2',
|
||||
4: 'light blue',
|
||||
8: 'light cyan',
|
||||
16: 'PaleTurquoise',
|
||||
32: 'MediumTurquoise',
|
||||
64: 'DarkTurquoise',
|
||||
128: 'light green',
|
||||
256: 'MediumSpringGreen',
|
||||
512: 'SpringGreen',
|
||||
1024: 'light goldenrod',
|
||||
2048: 'orange',
|
||||
}
|
||||
return colors.get(num, 'azure4')
|
||||
|
||||
# 处理键盘按键事件
|
||||
def key_down(self, event):
|
||||
key = event.keysym
|
||||
if key == 'Up':
|
||||
self.move_up()
|
||||
elif key == 'Down':
|
||||
self.move_down()
|
||||
elif key == 'Left':
|
||||
self.move_left()
|
||||
elif key == 'Right':
|
||||
self.move_right()
|
||||
self.update_grid_cells()
|
||||
if self.check_game_over():
|
||||
self.grid_cells[1][1].configure(text="Game", bg='red')
|
||||
self.grid_cells[1][2].configure(text="Over", bg='red')
|
||||
if self.score > self.high_score:
|
||||
self.high_score = self.score
|
||||
self.save_high_score()
|
||||
|
||||
# 压缩矩阵
|
||||
def compress(self, mat):
|
||||
new_mat = [[0] * 4 for _ in range(4)]
|
||||
for i in range(4):
|
||||
pos = 0
|
||||
for j in range(4):
|
||||
if mat[i][j] != 0:
|
||||
new_mat[i][pos] = mat[i][j]
|
||||
pos += 1
|
||||
return new_mat
|
||||
|
||||
# 合并相同的方块
|
||||
def merge(self, mat):
|
||||
for i in range(4):
|
||||
for j in range(3):
|
||||
if mat[i][j] == mat[i][j + 1] and mat[i][j] != 0:
|
||||
mat[i][j] *= 2
|
||||
mat[i][j + 1] = 0
|
||||
self.score += mat[i][j]
|
||||
return mat
|
||||
|
||||
# 反转矩阵
|
||||
def reverse(self, mat):
|
||||
new_mat = []
|
||||
for i in range(4):
|
||||
new_mat.append([])
|
||||
for j in range(4):
|
||||
new_mat[i].append(mat[i][3 - j])
|
||||
return new_mat
|
||||
|
||||
# 转置矩阵
|
||||
def transpose(self, mat):
|
||||
new_mat = []
|
||||
for i in range(4):
|
||||
new_mat.append([])
|
||||
for j in range(4):
|
||||
new_mat[i].append(mat[j][i])
|
||||
return new_mat
|
||||
|
||||
# 向上移动方块
|
||||
def move_up(self):
|
||||
self.board = self.transpose(self.board)
|
||||
self.board = self.compress(self.board)
|
||||
self.board = self.merge(self.board)
|
||||
self.board = self.compress(self.board)
|
||||
self.board = self.transpose(self.board)
|
||||
self.add_new_tile()
|
||||
|
||||
# 向下移动方块
|
||||
def move_down(self):
|
||||
self.board = self.transpose(self.board)
|
||||
self.board = self.reverse(self.board)
|
||||
self.board = self.compress(self.board)
|
||||
self.board = self.merge(self.board)
|
||||
self.board = self.compress(self.board)
|
||||
self.board = self.reverse(self.board)
|
||||
self.board = self.transpose(self.board)
|
||||
self.add_new_tile()
|
||||
|
||||
# 向左移动方块
|
||||
def move_left(self):
|
||||
self.board = self.compress(self.board)
|
||||
self.board = self.merge(self.board)
|
||||
self.board = self.compress(self.board)
|
||||
self.add_new_tile()
|
||||
|
||||
# 向右移动方块
|
||||
def move_right(self):
|
||||
self.board = self.reverse(self.board)
|
||||
self.board = self.compress(self.board)
|
||||
self.board = self.merge(self.board)
|
||||
self.board = self.compress(self.board)
|
||||
self.board = self.reverse(self.board)
|
||||
self.add_new_tile()
|
||||
|
||||
# 检查游戏是否结束
|
||||
def check_game_over(self):
|
||||
for i in range(4):
|
||||
for j in range(4):
|
||||
if self.board[i][j] == 0:
|
||||
return False
|
||||
for i in range(4):
|
||||
for j in range(3):
|
||||
if self.board[i][j] == self.board[i][j + 1]:
|
||||
return False
|
||||
for i in range(3):
|
||||
for j in range(4):
|
||||
if self.board[i][j] == self.board[i + 1][j]:
|
||||
return False
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
Game2048()
|
Loading…
Reference in new issue