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