4网站免费建站,网站建设岗位工作职责,页面设计结构的特色,网站建设大型企业用 Python 实现经典的 2048 游戏#xff1a;一步步带你打造属于你的小游戏#xff01;#xff08;结尾附完整代码#xff09; 简介 2048 是一个简单而又令人上瘾的数字拼图游戏。玩家通过滑动方块使相同数字的方块合并#xff0c;目标是创造出数字 2048#xff01;在这篇…用 Python 实现经典的 2048 游戏一步步带你打造属于你的小游戏结尾附完整代码 简介 2048 是一个简单而又令人上瘾的数字拼图游戏。玩家通过滑动方块使相同数字的方块合并目标是创造出数字 2048在这篇博客中我们将用 Python 的 Tkinter 库 从零开始实现这款游戏涵盖从界面设计到逻辑实现的每一个细节帮助你全面了解背后的开发思路。 游戏特点
经典玩法滑动合并相同数字尽可能达到 2048。随机生成新数字每次滑动后随机生成 2 或 4。直观的图形界面使用 Tkinter 绘制游戏网格与方块带来清晰的视觉效果。
开发环境准备
在开始之前确保你的环境已安装 Python并包含以下必要库 pip install tk Tkinter 是 Python 内置的 GUI 工具包因此大多数环境无需额外安装。
项目实现步骤
我们将按照以下步骤构建游戏
设计网格界面实现核心逻辑绑定键盘事件添加游戏结束检测优化用户体验
1. 设计网格界面
首先我们定义游戏的基本参数包括网格大小、方块的尺寸、间距和颜色等。随后通过 Tkinter 创建一个网格界面每个格子将用矩形和文本元素表示。
import tkinter as tk
from tkinter import messagebox
import random# 常量定义
GRID_SIZE 4 # 网格为 4x4
TILE_SIZE 100 # 每个方块的像素大小
PADDING 10 # 方块之间的间距
BACKGROUND_COLOR #92877d
TILE_COLORS {0: #9e948a, 2: #eee4da, 4: #ede0c8,8: #f2b179, 16: #f59563, 32: #f67c5f,64: #f65e3b, 128: #edcf72, 256: #edcc61,512: #edc850, 1024: #edc53f, 2048: #edc22e,
}# 初始化游戏界面
class Game2048:def __init__(self, master):self.master masterself.master.title(2048)self.master.geometry(f{GRID_SIZE * TILE_SIZE PADDING * (GRID_SIZE 1)}x{GRID_SIZE * TILE_SIZE PADDING * (GRID_SIZE 1)})self.master.resizable(False, False)self.init_grid()self.reset_game()def init_grid(self):创建 4x4 网格self.canvas tk.Canvas(self.master, bgBACKGROUND_COLOR, bd0, highlightthickness0)self.canvas.pack(filltk.BOTH, expandTrue)self.tiles []for i in range(GRID_SIZE):row []for j in range(GRID_SIZE):x1 PADDING j * (TILE_SIZE PADDING)y1 PADDING i * (TILE_SIZE PADDING)x2 x1 TILE_SIZEy2 y1 TILE_SIZErect self.canvas.create_rectangle(x1, y1, x2, y2, fillTILE_COLORS[0], outline)text self.canvas.create_text(x1 TILE_SIZE // 2, y1 TILE_SIZE // 2, text, font(Helvetica, 30), fill#776e65)row.append((rect, text))self.tiles.append(row)运行效果运行后你会看到一个 4x4 的灰色网格每个格子代表一个方块。 2. 实现核心逻辑
游戏的逻辑主要包括
压缩和合并数字将相邻的数字合并。滑动方向操作实现上下左右滑动功能。随机生成新数字在空格中随机生成 2 或 4。
压缩与合并
每次滑动操作可以拆分为两部分压缩去掉空格 和 合并合并相邻的相同数字。
def compress(row):将行向左压缩去掉 0new_row [num for num in row if num ! 0]new_row [0] * (GRID_SIZE - len(new_row))return new_rowdef merge(row):合并相邻相同的数字for i in range(len(row) - 1):if row[i] row[i 1] and row[i] ! 0:row[i] * 2row[i 1] 0return row滑动操作
根据方向执行不同操作上下左右。
def move_left(grid):左移操作new_grid []for row in grid:compressed_row compress(row)merged_row merge(compressed_row)new_grid.append(compress(merged_row))return new_grid随机生成数字
每次滑动后随机选择一个空格填入 2 或 4。
def spawn_new_tile(grid):随机生成一个新的数字方块2 或 4empty_cells [(i, j) for i in range(GRID_SIZE) for j in range(GRID_SIZE) if grid[i][j] 0]if empty_cells:i, j random.choice(empty_cells)grid[i][j] 2 if random.random() 0.9 else 43. 绑定键盘事件
为了让游戏动起来我们需要捕获用户的按键上下左右方向键并根据按键更新网格状态。
def key_press(event):处理键盘输入key event.keysymif key in [Up, Down, Left, Right]:if key Up:game.grid move_left(rotate_left(game.grid))game.grid rotate_right(game.grid)elif key Down:game.grid move_left(rotate_right(game.grid))game.grid rotate_left(game.grid)elif key Left:game.grid move_left(game.grid)elif key Right:game.grid move_left(reverse_rows(game.grid))game.grid reverse_rows(game.grid)spawn_new_tile(game.grid)game.update_ui()if is_game_over(game.grid):messagebox.showinfo(Game Over, No more moves left!)4. 添加游戏结束检测
当所有格子都被填满且没有可合并的数字时游戏结束。
def is_game_over(grid):判断是否还有有效操作for i in range(GRID_SIZE):for j in range(GRID_SIZE):if grid[i][j] 0: # 空格存在return Falseif j 1 GRID_SIZE and grid[i][j] grid[i][j 1]: # 横向可合并return Falseif i 1 GRID_SIZE and grid[i][j] grid[i 1][j]: # 纵向可合并return Falsereturn True5. 完整代码
将上述代码整合的完整代码如下运行后即可得到完整的 2048 游戏
import tkinter as tk
from tkinter import messagebox
import random# 常量定义
GRID_SIZE 4
TILE_SIZE 100
PADDING 10
BACKGROUND_COLOR #92877d
TILE_COLORS {0: #9e948a, 2: #eee4da, 4: #ede0c8,8: #f2b179, 16: #f59563, 32: #f67c5f,64: #f65e3b, 128: #edcf72, 256: #edcc61,512: #edc850, 1024: #edc53f, 2048: #edc22e,
}class Game2048:def __init__(self, master):self.master masterself.master.title(2048)self.master.geometry(f{GRID_SIZE * TILE_SIZE PADDING * (GRID_SIZE 1)}x{GRID_SIZE * TILE_SIZE PADDING * (GRID_SIZE 1)})self.master.resizable(False, False)self.init_grid()self.reset_game()def init_grid(self):初始化网格界面self.canvas tk.Canvas(self.master, bgBACKGROUND_COLOR, bd0, highlightthickness0)self.canvas.pack(filltk.BOTH, expandTrue)self.tiles []for i in range(GRID_SIZE):row []for j in range(GRID_SIZE):x1 PADDING j * (TILE_SIZE PADDING)y1 PADDING i * (TILE_SIZE PADDING)x2 x1 TILE_SIZEy2 y1 TILE_SIZErect self.canvas.create_rectangle(x1, y1, x2, y2, fillTILE_COLORS[0], outline)text self.canvas.create_text(x1 TILE_SIZE // 2, y1 TILE_SIZE // 2, text, font(Helvetica, 30), fill#776e65)row.append((rect, text))self.tiles.append(row)def reset_game(self):重置游戏状态self.grid [[0] * GRID_SIZE for _ in range(GRID_SIZE)]self.spawn_new_tile()self.spawn_new_tile()self.update_ui()def spawn_new_tile(self):随机生成一个新的数字方块2 或 4empty_cells [(i, j) for i in range(GRID_SIZE) for j in range(GRID_SIZE) if self.grid[i][j] 0]if empty_cells:i, j random.choice(empty_cells)self.grid[i][j] 2 if random.random() 0.9 else 4def update_ui(self):更新界面显示for i in range(GRID_SIZE):for j in range(GRID_SIZE):value self.grid[i][j]rect, text self.tiles[i][j]self.canvas.itemconfig(rect, fillTILE_COLORS.get(value, TILE_COLORS[2048]))self.canvas.itemconfig(text, textstr(value) if value ! 0 else )def compress(row):将行向左压缩去掉 0new_row [num for num in row if num ! 0]new_row [0] * (GRID_SIZE - len(new_row))return new_rowdef merge(row):合并相邻相同的数字for i in range(len(row) - 1):if row[i] row[i 1] and row[i] ! 0:row[i] * 2row[i 1] 0return rowdef move_left(grid):左移操作new_grid []for row in grid:compressed_row compress(row)merged_row merge(compressed_row)new_grid.append(compress(merged_row))return new_griddef rotate_right(grid):矩阵顺时针旋转 90°return [list(row) for row in zip(*grid[::-1])]def rotate_left(grid):矩阵逆时针旋转 90°return [list(row) for row in zip(*grid)][::-1]def reverse_rows(grid):矩阵水平翻转return [row[::-1] for row in grid]def is_game_over(grid):判断是否还有有效操作for i in range(GRID_SIZE):for j in range(GRID_SIZE):if grid[i][j] 0: # 空格存在return Falseif j 1 GRID_SIZE and grid[i][j] grid[i][j 1]: # 横向可合并return Falseif i 1 GRID_SIZE and grid[i][j] grid[i 1][j]: # 纵向可合并return Falsereturn Truedef key_press(event):处理键盘输入key event.keysymif key in [Up, Down, Left, Right]:if key Up:game.grid move_left(rotate_left(game.grid))game.grid rotate_right(game.grid)elif key Down:game.grid move_left(rotate_right(game.grid))game.grid rotate_left(game.grid)elif key Left:game.grid move_left(game.grid)elif key Right:game.grid move_left(reverse_rows(game.grid))game.grid reverse_rows(game.grid)game.spawn_new_tile()game.update_ui()if is_game_over(game.grid):messagebox.showinfo(Game Over, No more moves left!)root tk.Tk()
game Game2048(root)
root.bind(Key, key_press)
root.mainloop()
通过本篇博客我们从头实现了经典的 2048 游戏。不仅让你掌握了 Tkinter 界面开发还深入理解了游戏逻辑的实现过程。如果你喜欢这篇博客请分享给更多的 Python 爱好者吧