python2048游戏
实现了一个完整的2048游戏,并将其展示在一个图形化界面上。具体功能包括:
- 初始化游戏板:创建一个4x4的二维列表,表示游戏板,并在初始状态下随机放置两个数字(通常是2或4)。
- 绘制游戏板:使用
tkinter
库中的Canvas
对象来绘制游戏板,每个单元格根据其值显示不同的颜色和数字。 - 添加新方块:在空闲的单元格中随机添加一个新的数字(2或4)。
- 处理按键事件:监听键盘上的方向键输入,执行相应的移动操作(左、右、上、下)。
- 合并方块:当玩家移动时,相邻且相同的数字会合并成一个更大的数字。
- 旋转矩阵:为了简化上下移动的操作,通过旋转矩阵将上下移动转换为左右移动。
- 判断游戏结束:检查所有可能的移动方向,如果没有任何有效的移动,则游戏结束。
- 重启游戏:当游戏结束后,提示用户并允许重新开始游戏。
使用的技术
- Python:编程语言的核心。
- Tkinter:Python的标准GUI库,用于创建图形用户界面。
Canvas
:用于绘制游戏板和其中的数字。bind
:用于绑定键盘事件到特定的回调函数。messagebox
:用于显示游戏结束的消息框。
- 面向对象编程 (OOP):通过定义
Game2048
类来组织代码,使代码结构清晰且易于维护。 - 列表和字典:用于存储游戏状态和颜色映射。
- 随机数生成:使用
random.choice
和random.random
来决定新方块的位置和值。
代码展示:
import tkinter as tk
from tkinter import messagebox
import random
class Game2048:
def __init__(self, master):
self.master = master
self.master.title("2048")
self.board = [[0] * 4 for _ in range(4)]
self.add_new_tile()
self.add_new_tile()
self.canvas = tk.Canvas(self.master, width=300, height=300, bg="#bbada0")
self.canvas.pack()
self.draw_board()
self.master.bind("<Key>", self.key_press)
def draw_board(self):
self.canvas.delete("all")
for i in range(4):
for j in range(4):
x1 = j * 75
y1 = i * 75
x2 = x1 + 75
y2 = y1 + 75
color = self.get_cell_color(self.board[i][j])
self.canvas.create_rectangle(x1, y1, x2, y2, fill=color)
if self.board[i][j] != 0:
font_size = 36 if self.board[i][j] < 100 else 24 if self.board[i][j] < 1000 else 20
self.canvas.create_text((x1 + x2) / 2, (y1 + y2) / 2, text=str(self.board[i][j]), font=("Arial", font_size), fill="#f9f6f2")
def get_cell_color(self, value):
colors = {
0: "#cdc1b4",
2: "#eee4da",
4: "#ede0c8",
8: "#f2b179",
16: "#f59563",
32: "#f67c5f",
64: "#f65e3b",
128: "#edcf72",
256: "#edcc61",
512: "#edc850",
1024: "#edc53f",
2048: "#edc22e"
}
return colors.get(value, "#ff6347")
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 not empty_cells:
return False
i, j = random.choice(empty_cells)
self.board[i][j] = 2 if random.random() < 0.9 else 4
return True
def key_press(self, event):
moved = False
if event.keysym == "Up":
self.board, moved = self.move_up(self.board)
elif event.keysym == "Down":
self.board, moved = self.move_down(self.board)
elif event.keysym == "Left":
self.board, moved = self.move_left(self.board)
elif event.keysym == "Right":
self.board, moved = self.move_right(self.board)
if moved:
self.add_new_tile()
self.draw_board()
if self.game_over():
messagebox.showinfo("Game Over", "You lost!")
self.restart_game()
def move_left(self, board):
def merge(row):
merged_row = []
last_num = None
for num in row:
if num == 0:
continue
if last_num is None:
last_num = num
elif last_num == num:
merged_row.append(last_num + num)
last_num = None
else:
merged_row.append(last_num)
last_num = num
if last_num is not None:
merged_row.append(last_num)
merged_row.extend([0] * (4 - len(merged_row)))
return merged_row
new_board = [merge(row) for row in board]
return new_board, board != new_board
def rotate_clockwise(self, board):
return [list(reversed(col)) for col in zip(*board)]
def move_right(self, board):
rotated_board, changed = self.move_left(self.rotate_clockwise(board))
return self.rotate_clockwise(self.rotate_clockwise(self.rotate_clockwise(rotated_board))), changed
def move_up(self, board):
rotated_board, changed = self.move_left(self.rotate_clockwise(self.rotate_clockwise(board)))
return self.rotate_clockwise(rotate_clockwise(rotated_board)), changed
def move_down(self, board):
rotated_board, changed = self.move_left(self.rotate_clockwise(board))
return self.rotate_clockwise(self.rotate_clockwise(self.rotate_clockwise(rotate_clockwise(rotated_board)))), changed
def game_over(self):
for direction in [self.move_left, self.move_right, self.move_up, self.move_down]:
_, changed = direction(self.board)
if changed:
return False
return True
def restart_game(self):
self.board = [[0] * 4 for _ in range(4)]
self.add_new_tile()
self.add_new_tile()
self.draw_board()
if __name__ == "__main__":
root = tk.Tk()
game = Game2048(root)
root.mainloop()
效果图