在 Python 中构建 2048 游戏2025 年 4 月 16 日 | 31 分钟阅读 2048 是一款著名而简单的数学滑块益智游戏,由单人玩家进行。2048 是一款非常容易上瘾的游戏;这款游戏主要进行的是数字相加和合并方块。因此,让我们使用 Python 中的 Tkinter 库来构建这款游戏。 但在我们开始之前,让我们先澄清一些基本概念。 什么是 2048 游戏?2048 是一款单人游戏,玩家通过组合数字方块来获得更高数字的方块。玩家以两个方块开始游戏;最小的数字是 2。然后,玩家将通过组合相同数字的方块来获得一个数字是这两个方块数字之和的方块。人们已经开发了许多策略来达到 2048 这个数字并在游戏中获胜。然而,有些人追求更高的目标,即得分超过 2048。一旦玩家获得数字为 2048 的方块,系统会询问他们是否还想继续游戏。有些人就此止步,有些人则决定继续。 2048 游戏不涉及任何复杂的操作。我们将使用的操作是向上、向下和横向。游戏的规则也很简单。我们必须移动方块,每移动一次,一个新的方块就会随机出现在盒子里的任何位置。当我们移动两个相同数字的方块时,它们会合并成一个方块,其上印有的数字是它们最初数字的总和。 Python 2048 游戏项目的前置条件本项目的主要目标是为 Python 中的 2048 游戏设计一个图形用户界面(GUI)。我们将开发一个简单的 2048 游戏,其中我们将利用 Tkinter 包创建其图形用户界面,并使用 random 模块随机显示一个方块。我们还将为不同数字的方块使用不同的颜色代码。 本项目需要对 Python 中的循环和函数及其 Tkinter 包有扎实的了解。Tkinter 是 Tk 工具包的 Python 绑定,Tk 工具包被许多编程语言用于构建图形用户界面(GUI)。此外,还需要对 Python random 模块的方法和属性有很好的理解,该模块用于生成随机数或对象。 现在让我们开始构建项目。 Python 中构建 2048 游戏的实现我们将首先创建一个名为 '2048' 的新文件夹。在这个文件夹里,我们将创建一个名为 'main.py' 的 Python 程序文件,在那里我们将编写项目的源代码。 现在我们已经为应用程序设置了结构,是时候打开 'main.py' 文件并开始编码部分了。为了使概念清晰易懂,我们将完整的项目代码分为不同的部分。 以下是我们选择的项目分步方法: 步骤 1:导入所需的模块。 步骤 2:创建一个类来构建游戏。 步骤 3:定义应用程序的颜色和字体样式。 步骤 4:定义一个方法来创建图形用户界面(GUI)。 步骤 5:为游戏创建一个记分板。 步骤 6:创建一个方法来开始游戏。 步骤 7:定义操作矩阵的方法。 步骤 8:定义一个方法来随机插入新方块。 步骤 9:定义一个方法来更新 GUI。 步骤 10:定义用于按箭头键玩游戏的方法。 步骤 11:定义检查是否有任何移动可能的方法。 步骤 12:定义一个游戏结束的方法。 步骤 13:定义运行应用程序的主函数。 让我们详细了解上述步骤的实现。 导入必要的模块我们将首先导入项目所需的模块,如 random 和 tkinter。
让我们考虑以下说明相同内容的代码片段。 文件:main.py 说明 在上面的代码片段中,我们导入了 random 模块。我们还使用 import 语句后的星号 '*' 导入了 tkinter 模块中的所有内容。 创建类来构建游戏现在我们将定义一个类,它将为游戏创建结构。这个类将包含游戏所需的所有方法和属性。 因此,让我们开始定义一个类和应用程序的初始化方法。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 GameApplication 的类,它继承自 Tkinter 的 Frame 控件。这个类将维护图形用户界面(GUI)的结构。此外,整个应用程序将使用这个类运行。 在这个类中,我们定义了一个构造函数,称为 Frame 构造函数,用于将应用程序构造为一个框架控件。然后我们调用了 grid() 方法为游戏创建一个网格。然后我们使用 title() 方法设置了应用程序的标题。然后我们使用 Frame() 类创建了一个框架控件,并将其背景颜色设置为 color_scheme,边框宽度设置为 3px,大小设置为 600x600。然后我们再次使用 grid() 方法设置了框架在窗口上的位置,并将顶部填充设置为 120px。然后我们调用了 app_GUI() 和 start() 方法,并将箭头键绑定到各自的功能。最后,我们调用了 mainloop() 方法。 定义应用程序的颜色和字体样式现在我们将定义应用程序不同控件所需的颜色。我们还将定义一些将在整个应用程序中使用的字体样式。 让我们考虑以下说明相同内容的代码片段。 文件:main.py 说明 在上面的代码片段中,我们定义了应用程序不同控件所需的颜色和字体样式。我们定义了网格、空单元格、消息、带数字的单元格和单元格数字的颜色。然后我们定义了记分板、消息和单元格中显示的数字的字体样式。 定义创建图形用户界面(GUI)的方法现在我们将定义一个方法来创建图形用户界面(GUI),即创建一个包含空单元格的 4x4 网格。 让我们考虑以下说明相同内容的代码片段。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 app_GUI() 的方法。在这个方法中,我们创建了一个空的单元格列表。然后我们使用一个 嵌套 for 循环 创建一个 4x4 矩阵。我们在第一个循环中创建了一个空的行列表,每次内循环迭代后,单元格数据都会被追加到这个列表中。我们在第二个循环中使用 Frame() 类创建了一个框架,并将其 master 参数设置为 main_frame。我们还将框架的背景颜色设置为之前定义的空单元格颜色,并将框架的宽度和高度都设置为 150px。然后我们使用 grid() 方法以网格格式设置框架的位置。然后我们使用 Label() 类创建了一个标签来显示单元格上的数字。我们将其 master 参数设置为 main_frame,背景颜色设置为空单元格颜色。之后,我们创建了一个字典来存储单元格数据,并使用 grid() 方法设置标签在单元格中的位置。然后我们使用 append() 方法将单元格数据追加到行列表中。最后,我们使用 append() 方法将行追加到单元格列表中。 为游戏创建记分板让我们考虑以下代码片段,说明如何为游戏创建一个记分板,其中将显示玩家的分数。 文件:main.py 说明 在上面的代码片段中,我们使用 Frame() 类创建了一个框架。然后我们使用 place() 方法设置了它在窗口上的位置。然后我们使用 Label() 类创建了用于显示分数的标签。然后我们使用 grid() 方法设置了这些标签在框架中的位置。 定义启动游戏的方法现在我们将定义一个启动游戏的方法。此方法将生成两个随机单元格,其中包含 2,并将分数的初始值设置为 0。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 start() 的方法。在这个方法中,我们创建了一个 4x4 矩阵 或一个 二维列表。我们首先将矩阵初始化为全零。然后我们使用 random.randint() 方法随机选择范围在 0 到 3 之间的行号和列号,并将所选单元格的值设置为 2。我们还配置了单元格的背景、前景和文本颜色以及字体样式,以及其上显示的数字。然后我们使用 while-loop 再次随机选择行号和列号,如果任何单元格不为 0。然后我们再次将所选单元格的值设置为 2,并配置了单元格的背景、前景和文本颜色以及字体样式,以及其上显示的数字。最后,我们将分数的初始值设置为 0。 定义操作矩阵的方法现在我们将定义一些操作矩阵的方法。这些方法将允许我们将矩阵中所有非零数字压缩到板的一侧,将矩阵中所有水平相邻的相同值的非零数字合并到单个位置,反转矩阵中每一行的顺序,以及转置矩阵。 让我们考虑以下代码片段,说明实现第一个方法来压缩所有非零数字。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 compress_cells() 的方法,它将矩阵中所有非零数字堆叠到板的一端,删除它们之间的所有空单元格间隙。在这个方法中,我们创建了一个名为 MatrixOne 的矩阵,它由 嵌套 for 循环 中矩阵的每一行中的所有零组成。然后我们创建了一个名为 positionFill 的变量,并记录了由非零数字组成的单元格的数量。如果单元格值非零,新矩阵中 i 处的值将填充该位置。然后,我们将填充位置增加一,并将矩阵设置为 MatrixOne。 让我们定义另一个方法,将所有水平相邻的相同值的非零数字相加并合并到单个位置。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 combine_cells() 的方法,它将矩阵中所有水平相邻的相同值的非零数字相加,并将它们合并到左侧位置。在这个方法中,我们创建了一个 嵌套 for 循环,并使用索引 j+1 迭代到第二列。之后,我们检查矩阵索引 (i, j) 处的值是否不为零且等于索引 (i, j+1) 处的值。我们将索引 (i, j) 处的值乘以 二,并将索引 (i, j+1) 处的值设置为 零。然后我们通过添加新合并的值来更新分数。 现在让我们定义另一个方法来反转矩阵中每一行的顺序。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 reverse_order() 的方法,它将反转矩阵中每一行的顺序。在这个方法中,我们创建了一个名为 MatrixOne 的空列表。然后我们创建了一个 嵌套 for 循环,并在外层循环中将一个空列表追加到 MatrixOne 中。在内层循环中,我们反转了值,并将主矩阵设置为 MatrixOne。 现在让我们定义一个方法来翻转矩阵,使其对角线翻转。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 transpose_matrix() 的方法,它将矩阵沿其对角线翻转。在这个方法中,我们创建了一个 4x4 矩阵 名为 MatrixOne,其所有元素都为 零。然后,我们创建了一个嵌套 for 循环,并将 MatrixOne 中索引 (i, j) 处的每个值设置为当前矩阵中索引 (j, i) 处的值。然后我们将主矩阵设置为 MatrixOne。 定义随机插入新方块的方法现在让我们考虑以下代码片段,以定义一个方法,将新的 2 或 4 数字方块随机插入到一个空单元格中。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 insert_tile() 的方法。在这个方法中,我们使用 random.randint() 方法从矩阵中随机选择行和列。然后我们运行 while 循环,再次从矩阵中随机选择行和列。最后,我们使用 random.choice() 将所选单元格的值设置为 2 或 4。 定义更新图形用户界面 (GUI) 的方法现在我们将定义一个方法来更新图形用户界面(GUI),使其与新操作的矩阵相似。 让我们考虑以下代码片段,演示相同的实现。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 update_GUI() 的方法。在这个方法中,我们创建了一个 嵌套 for 循环,并检查是否有任何单元格值等于 0,然后根据颜色和字体图表中指定的背景和前景颜色以及该单元格中的文本进行配置。然后我们更新并显示分数。最后,我们调用了 Tkinter Frame 的 update_idletasks() 方法以立即显示控件。 定义用于按箭头键玩游戏的方法现在我们将定义方法来绑定箭头键(左、右、上和下)以玩游戏。 左箭头键绑定 让我们首先考虑以下代码片段,演示左箭头键方法的实现。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 left_key() 的方法。在这个方法中,我们调用了 compress_cells() 方法将非零数字压缩到矩阵的左侧。然后我们调用了 combine_cells() 方法来组合水平相邻的数字。我们再次调用了 compress_cells() 方法来消除 combine_cells() 方法新创建的零单元格。然后我们使用 insert_tile() 方法添加了一个新方块,并通过调用 update_GUI() 方法更新了图形用户界面(GUI)。最后,我们调用了 gameover() 方法来结束游戏。 右箭头键绑定 现在我们将定义另一个右箭头键的方法。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 right_key() 的方法。在这个方法中,我们调用了 reverse_order() 方法将右滑转换为左滑。然后我们调用了 compress_cells() 方法将非零数字压缩到矩阵的左侧,并调用了 combine_cells() 方法来组合水平相邻的数字。我们再次调用了 compress_cells() 方法来消除 combine_cells() 方法新创建的零单元格。之后,我们再次调用了 reverse_order() 方法将矩阵的顺序反转回其原始方向。然后我们使用 insert_tile() 方法添加了一个新方块,并通过调用 update_GUI() 方法更新了图形用户界面(GUI)。最后,我们调用了 gameover() 方法来结束游戏。 上箭头键绑定让我们定义一个上箭头键的方法。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 up_key() 的方法。在这个方法中,我们调用了 transpose_matrix() 方法来翻转矩阵的对角线,使其功能类似于向左移动。然后我们调用了 compress_cells() 方法将非零数字压缩到矩阵的左侧,并调用了 combine_cells() 方法来组合水平相邻的数字。我们再次调用了 compress_cells() 方法来消除 combine_cells() 方法新创建的零单元格。之后,我们再次调用了 transpose_matrix() 方法将矩阵转置回其原始方向。然后我们使用 insert_tile() 方法添加了一个新方块,并通过调用 update_GUI() 方法更新了图形用户界面(GUI)。最后,我们调用了 gameover() 方法来结束游戏。 下箭头键绑定让我们定义一个下箭头键的方法。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 up_key() 的方法。在这个方法中,我们调用了 transpose_matrix() 和 reverse_order() 方法来转置和反转矩阵,以便向下移动将变为向左移动。然后我们调用了 compress_cells() 方法将非零数字压缩到矩阵的左侧,并调用了 combine_cells() 方法来组合水平相邻的数字。我们再次调用了 compress_cells() 方法来消除 combine_cells() 方法新创建的零单元格。之后,我们再次调用了 reverse_order() 和 transpose_matrix() 方法来反转矩阵的顺序并将其转置回其原始方向。然后我们使用 insert_tile() 方法添加了一个新方块,并通过调用 update_GUI() 方法更新了图形用户界面(GUI)。最后,我们调用了 gameover() 方法来结束游戏。 定义检查是否有任何移动可能的方法现在我们将定义方法来检查是否存在可能的水平和垂直移动。 检查水平移动 让我们首先考虑以下代码片段来理解检查水平移动方法的实现。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 horizontal_move_exists() 的方法。在这个方法中,我们使用 嵌套 for 循环 遍历矩阵,如果两个水平相邻的方块相同,则返回 True。 检查垂直移动 让我们首先考虑以下代码片段来理解检查垂直移动方法的实现。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 vertical_move_exists() 的方法。在这个方法中,我们使用 嵌套 for 循环 遍历矩阵,如果两个垂直相邻的方块相同,则返回 True。 定义游戏结束的方法现在我们将定义一个游戏结束的方法。此方法将检查玩家是否已创建 2048 方块或已无移动可继续游戏,并相应地显示 'WIN' 或 'LOSE' 消息。 让我们考虑以下说明相同内容的代码片段。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 gameover() 的方法。在这个方法中,我们使用条件语句检查玩家是否已经创建了一个 2048 的方块,或者游戏中是否不再有任何可用的移动。对于这些条件,我们创建了一个单独的框架以及一个标签,以相应地显示 'WIN' 或 'LOSE' 消息。 定义运行应用程序的主函数现在我们将定义一个函数来调用 GameApplication() 类,并定义一个主函数来运行应用程序。 文件:main.py 说明 在上面的代码片段中,我们定义了一个名为 game() 的函数。在这个函数内部,我们调用了 GameApplication() 类。 最后,我们定义了一个主函数并调用 game() 函数来运行应用程序。 因此,我们已成功编写了 Python 2048 游戏项目 的代码。我们现在可以保存并运行项目文件以查看结果。 完整的项目代码以下是 Python 2048 游戏 的完整代码以供参考 文件:main.py 输出 $ python main.py ![]() 下一主题Python 中的快速排序 |
我们请求您订阅我们的新闻通讯以获取最新更新。