import tkinter as tk
from tkinter import messagebox
import random
import math
class Game2048:
def __init__(self):
self.window = tk.Tk()
self.window.title("2048 游戏")
self.window.geometry("500x600")
self.window.resizable(False, False)
self.window.configure(bg='#FAF8EF')
# 游戏状态
self.grid_size = 4
self.cell_size = 100
self.padding = 10
self.grid = [[0 for _ in range(self.grid_size)] for _ in range(self.grid_size)]
self.score = 0
self.high_score = 0
self.game_over = False
self.won = False
# 颜色配置
self.colors = {
0: ("#CDC1B4", "#776E65", ""),
2: ("#EEE4DA", "#776E65", "2"),
4: ("#EDE0C8", "#776E65", "4"),
8: ("#F2B179", "#F9F6F2", "8"),
16: ("#F59563", "#F9F6F2", "16"),
32: ("#F67C5F", "#F9F6F2", "32"),
64: ("#F65E3B", "#F9F6F2", "64"),
128: ("#EDCF72", "#F9F6F2", "128"),
256: ("#EDCC61", "#F9F6F2", "256"),
512: ("#EDC850", "#F9F6F2", "512"),
1024: ("#EDC53F", "#F9F6F2", "1024"),
2048: ("#EDC22E", "#F9F6F2", "2048"),
4096: ("#3C3A32", "#F9F6F2", "4096"),
8192: ("#3C3A32", "#F9F6F2", "8192")
}
self.setup_ui()
self.start_game()
def setup_ui(self):
"""设置游戏界面"""
# 标题
title_frame = tk.Frame(self.window, bg='#FAF8EF')
title_frame.pack(pady=10)
title_label = tk.Label(
title_frame,
text="2048",
font=("Arial", 40, "bold"),
fg="#776E65",
bg='#FAF8EF'
)
title_label.pack(side=tk.LEFT, padx=20)
# 分数显示
score_frame = tk.Frame(title_frame, bg='#FAF8EF')
score_frame.pack(side=tk.RIGHT, padx=20)
self.score_label = tk.Label(
score_frame,
text=f"分数: {self.score}",
font=("Arial", 14, "bold"),
fg="white",
bg="#BBADA0",
padx=10,
pady=5
)
self.score_label.pack(pady=2)
self.high_score_label = tk.Label(
score_frame,
text=f"最高分: {self.high_score}",
font=("Arial", 14, "bold"),
fg="white",
bg="#BBADA0",
padx=10,
pady=5
)
self.high_score_label.pack(pady=2)
# 游戏说明
instruction_label = tk.Label(
self.window,
text="使用方向键移动方块,相同数字合并加倍!",
font=("Arial", 12),
fg="#776E65",
bg='#FAF8EF'
)
instruction_label.pack(pady=5)
# 游戏画布
self.canvas = tk.Canvas(
self.window,
width=self.grid_size * self.cell_size + (self.grid_size + 1) * self.padding,
height=self.grid_size * self.cell_size + (self.grid_size + 1) * self.padding,
bg='#FAF8EF',
highlightthickness=0
)
self.canvas.pack(pady=20)
# 控制按钮框架
button_frame = tk.Frame(self.window, bg='#FAF8EF')
button_frame.pack(pady=10)
restart_btn = tk.Button(
button_frame,
text="重新开始",
font=("Arial", 12, "bold"),
command=self.restart_game,
bg="#8F7A66",
fg="white",
padx=20,
pady=10
)
restart_btn.pack(side=tk.LEFT, padx=10)
exit_btn = tk.Button(
button_frame,
text="退出游戏",
font=("Arial", 12, "bold"),
command=self.window.quit,
bg="#8F7A66",
fg="white",
padx=20,
pady=10
)
exit_btn.pack(side=tk.LEFT, padx=10)
# 绑定键盘事件
self.window.bind('<Key>', self.handle_keypress)
self.window.focus_set()
def start_game(self):
"""开始新游戏"""
self.grid = [[0 for _ in range(self.grid_size)] for _ in range(self.grid_size)]
self.score = 0
self.game_over = False
self.won = False
self.add_random_tile()
self.add_random_tile()
self.draw_grid()
def add_random_tile(self):
"""在随机空白位置添加新方块"""
empty_cells = [
(i, j)
for i in range(self.grid_size)
for j in range(self.grid_size)
if self.grid[i][j] == 0
]
if empty_cells:
i, j = random.choice(empty_cells)
# 90% 概率生成 2,10% 概率生成 4
self.grid[i][j] = 2 if random.random() < 0.9 else 4
def draw_grid(self):
"""绘制游戏网格"""
self.canvas.delete("all")
# 绘制背景网格
for i in range(self.grid_size):
for j in range(self.grid_size):
x = j * (self.cell_size + self.padding) + self.padding
y = i * (self.cell_size + self.padding) + self.padding
# 获取颜色
value = self.grid[i][j]
bg_color, text_color, text = self.colors.get(
value,
("#3C3A32", "#F9F6F2", str(value))
)
# 绘制方块
self.canvas.create_rectangle(
x, y, x + self.cell_size, y + self.cell_size,
fill=bg_color, outline="", width=0,
tags=f"cell_{i}_{j}"
)
# 绘制数字
if value != 0:
font_size = 40 if value < 100 else 36 if value < 1000 else 30
self.canvas.create_text(
x + self.cell_size // 2,
y + self.cell_size // 2,
text=text,
font=("Arial", font_size, "bold"),
fill=text_color,
tags=f"text_{i}_{j}"
)
# 更新分数显示
self.score_label.config(text=f"分数: {self.score}")
self.high_score_label.config(text=f"最高分: {max(self.score, self.high_score)}")
def handle_keypress(self, event):
"""处理键盘输入"""
if self.game_over:
return
moved = False
if event.keysym in ['Up', 'w', 'W']:
moved = self.move_up()
elif event.keysym in ['Down', 's', 'S']:
moved = self.move_down()
elif event.keysym in ['Left', 'a', 'A']:
moved = self.move_left()
elif event.keysym in ['Right', 'd', 'D']:
moved = self.move_right()
if moved:
self.add_random_tile()
self.draw_grid()
self.check_game_state()
def move_left(self):
"""向左移动"""
moved = False
for i in range(self.grid_size):
# 压缩行
row = [num for num in self.grid[i] if num != 0]
# 合并相同数字
for j in range(len(row) - 1):
if row[j] == row[j + 1]:
row[j] *= 2
self.score += row[j]
row[j + 1] = 0
moved = True
# 再次压缩
row = [num for num in row if num != 0]
# 填充0
row.extend([0] * (self.grid_size - len(row)))
if self.grid[i] != row:
moved = True
self.grid[i] = row
return moved
def move_right(self):
"""向右移动"""
moved = False
for i in range(self.grid_size):
# 压缩行
row = [num for num in self.grid[i] if num != 0]
# 合并相同数字
for j in range(len(row) - 1, 0, -1):
if row[j] == row[j - 1]:
row[j] *= 2
self.score += row[j]
row[j - 1] = 0
moved = True
# 再次压缩
row = [num for num in row if num != 0]
# 填充0
row = [0] * (self.grid_size - len(row)) + row
if self.grid[i] != row:
moved = True
self.grid[i] = row
return moved
def move_up(self):
"""向上移动"""
moved = False
for j in range(self.grid_size):
# 获取列
column = [self.grid[i][j] for i in range(self.grid_size)]
# 压缩列
column = [num for num in column if num != 0]
# 合并相同数字
for i in range(len(column) - 1):
if column[i] == column[i + 1]:
column[i] *= 2
self.score += column[i]
column[i + 1] = 0
moved = True
# 再次压缩
column = [num for num in column if num != 0]
# 填充0
column.extend([0] * (self.grid_size - len(column)))
# 更新列
for i in range(self.grid_size):
if self.grid[i][j] != column[i]:
moved = True
self.grid[i][j] = column[i]
return moved
def move_down(self):
"""向下移动"""
moved = False
for j in range(self.grid_size):
# 获取列
column = [self.grid[i][j] for i in range(self.grid_size)]
# 压缩列
column = [num for num in column if num != 0]
# 合并相同数字
for i in range(len(column) - 1, 0, -1):
if column[i] == column[i - 1]:
column[i] *= 2
self.score += column[i]
column[i - 1] = 0
moved = True
# 再次压缩
column = [num for num in column if num != 0]
# 填充0
column = [0] * (self.grid_size - len(column)) + column
# 更新列
for i in range(self.grid_size):
if self.grid[i][j] != column[i]:
moved = True
self.grid[i][j] = column[i]
return moved
def check_game_state(self):
"""检查游戏状态"""
# 检查是否获胜
if any(2048 in row for row in self.grid) and not self.won:
self.won = True
if messagebox.askyesno("恭喜!", "你达到了2048!是否继续游戏?"):
return
else:
self.restart_game()
return
# 检查游戏是否结束
if not any(0 in row for row in self.grid):
# 检查是否还能移动
can_move = False
for i in range(self.grid_size):
for j in range(self.grid_size):
if j < self.grid_size - 1 and self.grid[i][j] == self.grid[i][j + 1]:
can_move = True
if i < self.grid_size - 1 and self.grid[i][j] == self.grid[i + 1][j]:
can_move = True
if not can_move:
self.game_over = True
if messagebox.askyesno("游戏结束", f"游戏结束!最终分数: {self.score}\n是否重新开始?"):
self.restart_game()
else:
self.window.quit()
def restart_game(self):
"""重新开始游戏"""
self.high_score = max(self.score, self.high_score)
self.start_game()
def run(self):
"""运行游戏"""
self.window.mainloop()
if __name__ == "__main__":
game = Game2048()
game.run()
4899

被折叠的 条评论
为什么被折叠?



