首页 > Python资料 博客日记
用 Python 实现经典的 2048 游戏:一步步带你打造属于你的小游戏!
2025-01-05 21:00:05Python资料围观11次
文章用 Python 实现经典的 2048 游戏:一步步带你打造属于你的小游戏!分享给大家,欢迎收藏Python资料网,专注分享技术知识
用 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 = master
self.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, bg=BACKGROUND_COLOR, bd=0, highlightthickness=0)
self.canvas.pack(fill=tk.BOTH, expand=True)
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_SIZE
y2 = y1 + TILE_SIZE
rect = self.canvas.create_rectangle(x1, y1, x2, y2, fill=TILE_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):
"""将行向左压缩,去掉 0"""
new_row = [num for num in row if num != 0]
new_row += [0] * (GRID_SIZE - len(new_row))
return new_row
def merge(row):
"""合并相邻相同的数字"""
for i in range(len(row) - 1):
if row[i] == row[i + 1] and row[i] != 0:
row[i] *= 2
row[i + 1] = 0
return 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 或 4)"""
empty_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 4
3. 绑定键盘事件
为了让游戏动起来,我们需要捕获用户的按键(上下左右方向键),并根据按键更新网格状态。
def key_press(event):
"""处理键盘输入"""
key = event.keysym
if 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 False
if j + 1 < GRID_SIZE and grid[i][j] == grid[i][j + 1]: # 横向可合并
return False
if i + 1 < GRID_SIZE and grid[i][j] == grid[i + 1][j]: # 纵向可合并
return False
return True
5. 完整代码
将上述代码整合的完整代码如下:运行后即可得到完整的 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 = master
self.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, bg=BACKGROUND_COLOR, bd=0, highlightthickness=0)
self.canvas.pack(fill=tk.BOTH, expand=True)
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_SIZE
y2 = y1 + TILE_SIZE
rect = self.canvas.create_rectangle(x1, y1, x2, y2, fill=TILE_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 或 4)"""
empty_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 4
def 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, fill=TILE_COLORS.get(value, TILE_COLORS[2048]))
self.canvas.itemconfig(text, text=str(value) if value != 0 else "")
def compress(row):
"""将行向左压缩,去掉 0"""
new_row = [num for num in row if num != 0]
new_row += [0] * (GRID_SIZE - len(new_row))
return new_row
def merge(row):
"""合并相邻相同的数字"""
for i in range(len(row) - 1):
if row[i] == row[i + 1] and row[i] != 0:
row[i] *= 2
row[i + 1] = 0
return 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
def 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 False
if j + 1 < GRID_SIZE and grid[i][j] == grid[i][j + 1]: # 横向可合并
return False
if i + 1 < GRID_SIZE and grid[i][j] == grid[i + 1][j]: # 纵向可合并
return False
return True
def key_press(event):
"""处理键盘输入"""
key = event.keysym
if 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 爱好者吧!
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签:
相关文章
最新发布
- 小波变换算法详解(附Python和C++代码)
- WxPython跨平台开发框架之使用PyInstaller 进行打包处理
- 【Python】正则表达式
- manim边做边学--动画组合
- Outlook不支持账号密码改OAuth2.0认证方式获取outlook邮箱收件箱以及附件(python)
- Python毕业设计选题:基于Python的社区爱心养老管理系统设计与实现_django
- 华为OD机试E卷 --最左侧冗余覆盖子串--24年OD统一考试(Java & JS & Python & C & C++)
- python graphviz 中文乱码
- 华为OD机试E卷 --贪心歌手--24年OD统一考试(Java & JS & Python & C & C++)
- 【Python】装饰器、正则表达式
点击排行
- 版本匹配指南:Numpy版本和Python版本的对应关系
- 版本匹配指南:PyTorch版本、torchvision 版本和Python版本的对应关系
- Python 可视化 web 神器:streamlit、Gradio、dash、nicegui;低代码 Python Web 框架:PyWebIO
- 相关性分析——Pearson相关系数+热力图(附data和Python完整代码)
- Anaconda版本和Python版本对应关系(持续更新...)
- Python与PyTorch的版本对应
- Windows上安装 Python 环境并配置环境变量 (超详细教程)
- Python pyinstaller打包exe最完整教程