【游戏制作】使用Python创建一个完整的2048游戏项目

 

目录

项目运行展示

项目概述

项目目标

项目结构

安装依赖

代码实现

1. 导入库

2. 创建 Game2048 类

 3. 设置UI界面

 4. 加载二维码图片

5. 创建菜单 

6. 游戏逻辑和功能 

 7. 运行应用

总结


创建一个完整的2048游戏项目

项目运行展示

项目概述

在这个项目中,我们将创建一个2048游戏的桌面应用程序。这个游戏是一个流行的数学游戏,玩家通过合并相同的数字块来达到2048。我们将使用 ttkbootstrap 库为应用程序添加现代化的外观,并且通过 tkinterPIL 实现游戏的功能和界面。

项目目标
  • 实现2048游戏的逻辑和UI
  • 添加历史记录功能
  • 实现主题和窗口大小的动态修改
  • 加载和显示二维码图片
  • 添加游戏开始和结束的逻辑
项目结构
  1. 主程序文件: game2048.py — 包含游戏逻辑和界面实现。
  2. 资源文件: 1.gif — 二维码图片资源。
安装依赖

确保你已经安装了以下Python库:

  • tkinter (Python的标准库,通常默认安装)
  • ttkbootstrap (用于增强tkinter的UI)
  • Pillow (用于处理图像)

可以通过以下命令安装缺失的依赖:

pip install ttkbootstrap pillow
代码实现
1. 导入库
import tkinter as tk
import ttkbootstrap as ttk
from ttkbootstrap.constants import *
from tkinter import Menu, Toplevel, messagebox, simpledialog
import random
import datetime
from PIL import Image, ImageTk
2. 创建 Game2048
class Game2048(ttk.Window):def __init__(self):super().__init__(title="2048 Game", themename="superhero")self.grid()self.cells = [[None for _ in range(4)] for _ in range(4)]self.history = []self.setup_ui()self.create_menu()self.start_game()
 3. 设置UI界面
    def setup_ui(self):self.title("2048 Game")self.geometry("800x600")self.resizable(False, False)self.main_grid = ttk.Frame(self, style='secondary.TFrame')self.main_grid.grid(row=0, column=0, padx=(10, 10), pady=(10, 10))for i in range(4):row = []for j in range(4):cell_frame = ttk.Frame(self.main_grid, width=100, height=100, style='primary.TFrame')cell_frame.grid(row=i, column=j, padx=5, pady=5)cell_number = ttk.Label(self.main_grid, text="", style='primary.Inverse.TLabel', font=("Helvetica", 24, "bold"))cell_number.grid(row=i, column=j)cell_data = {"frame": cell_frame, "number": cell_number}row.append(cell_data)self.cells[i] = rowself.score_label = ttk.Label(self, text="Score: 0", style='info.TLabel', font=("Helvetica", 16))self.score_label.grid(row=1, column=0, columnspan=4, pady=(0, 10))# 加载二维码图片self.load_qr_code()self.bind_keys()
 4. 加载二维码图片
    def load_qr_code(self):image = Image.open("1.gif")  # 替换为你的二维码图片路径image = image.resize((150, 150), Image.ANTIALIAS)self.qr_code_image = ImageTk.PhotoImage(image)self.qr_code_label = ttk.Label(self, image=self.qr_code_image)self.qr_code_label.grid(row=0, column=1, padx=(10, 10), pady=(10, 10))self.qr_code_text = ttk.Label(self, text="B站优秀稳妥的小光", style='info.TLabel', font=("Helvetica", 16))self.qr_code_text.grid(row=0, column=1, pady=(170, 10))
5. 创建菜单 
    def create_menu(self):menubar = Menu(self)# 历史记录菜单history_menu = Menu(menubar, tearoff=0)history_menu.add_command(label="查看历史分数", command=self.show_history)menubar.add_cascade(label="历史记录", menu=history_menu)# 查看菜单view_menu = Menu(menubar, tearoff=0)view_menu.add_command(label="查看日期", command=self.show_date)view_menu.add_command(label="查看开发者", command=self.show_developer)menubar.add_cascade(label="查看", menu=view_menu)# 修改菜单edit_menu = Menu(menubar, tearoff=0)# 修改主题子菜单theme_menu = Menu(edit_menu, tearoff=0)style = ttk.Style()theme_names = style.theme_names()for theme_name in theme_names:theme_menu.add_command(label=theme_name, command=lambda t=theme_name: self.change_theme(t))edit_menu.add_cascade(label="修改主题", menu=theme_menu)# 修改窗口大小功能edit_menu.add_command(label="修改窗口大小", command=self.change_window_size)menubar.add_cascade(label="修改", menu=edit_menu)self.config(menu=menubar)
6. 游戏逻辑和功能 
    def start_game(self):self.matrix = [[0] * 4 for _ in range(4)]self.score = 0self.add_new_tile()self.add_new_tile()self.update_ui()def add_new_tile(self):empty_cells = [(i, j) for i in range(4) for j in range(4) if self.matrix[i][j] == 0]if empty_cells:i, j = random.choice(empty_cells)self.matrix[i][j] = 2 if random.random() < 0.9 else 4def update_ui(self):for i in range(4):for j in range(4):cell_value = self.matrix[i][j]if cell_value == 0:self.cells[i][j]["frame"].configure(style='primary.TFrame')self.cells[i][j]["number"].configure(text="")else:self.cells[i][j]["frame"].configure(style=f'TFrame')self.cells[i][j]["number"].configure(text=str(cell_value), font=("Helvetica", 24, "bold"))self.score_label.configure(text=f"Score: {self.score}")self.update_idletasks()def move_up(self, event):self.move_tiles(0, -1)self.merge_tiles(0, -1)self.move_tiles(0, -1)self.add_new_tile()self.update_ui()self.check_game_over()def move_down(self, event):self.move_tiles(0, 1)self.merge_tiles(0, 1)self.move_tiles(0, 1)self.add_new_tile()self.update_ui()self.check_game_over()def move_left(self, event):self.move_tiles(-1, 0)self.merge_tiles(-1, 0)self.move_tiles(-1, 0)self.add_new_tile()self.update_ui()self.check_game_over()def move_right(self, event):self.move_tiles(1, 0)self.merge_tiles(1, 0)self.move_tiles(1, 0)self.add_new_tile()self.update_ui()self.check_game_over()def move_tiles(self, x, y):def move(x, y, i, j):if self.matrix[i][j] != 0:ni, nj = i + x, j + ywhile 0 <= ni < 4 and 0 <= nj < 4 and self.matrix[ni][nj] == 0:self.matrix[ni][nj] = self.matrix[i][j]self.matrix[i][j] = 0i, j = ni, njni, nj = i + x, j + yfor i in range(4):for j in range(4):if x == -1:move(x, y, i, j)if x == 1:move(x, y, 3 - i, j)if y == -1:move(x, y, j, i)if y == 1:move(x, y, j, 3 - i)def merge_tiles(self, x, y):def merge(x, y, i, j):ni, nj = i + x, j + yif 0 <= ni < 4 and 0 <= nj < 4 and self.matrix[i][j] == self.matrix[ni][nj] and self.matrix[i][j] != 0:self.matrix[ni][nj] *= 2self.matrix[i][j] = 0self.score += self.matrix[ni][nj]for i in range(4):for j in range(4):if x == -1:merge(x, y, i, j)if x == 1:merge(x, y, 3 - i, j)if y == -1:merge(x, y, j, i)if y == 1:merge(x, y, j, 3 - i)def show_history(self):history_window = Toplevel(self)history_window.title("历史分数")history_window.geometry("320x420")history_text = tk.Text(history_window, wrap="word")history_text.pack(expand=1, fill="both")for record in self.history:history_text.insert("end", record + "\n")def show_date(self):current_date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")messagebox.showinfo("当前日期和时间", current_date)def show_developer(self):messagebox.showinfo("开发者信息", "开发者: B站 优秀稳妥的小光")def check_game_over(self):if not any(0 in row for row in self.matrix) and not self.can_merge():self.history.append(f"Score: {self.score}")messagebox.showinfo("Game Over", f"Game Over! Your Score: {self.score}")self.start_game()def can_merge(self):for i in range(4):for j in range(4):if j < 3 and self.matrix[i][j] == self.matrix[i][j + 1]:return Trueif i < 3 and self.matrix[i][j] == self.matrix[i + 1][j]:return Truereturn False
 7. 运行应用
if __name__ == "__main__":app = Game2048()app.mainloop()
总结

这个2048游戏项目展示了如何使用 tkinterttkbootstrap 创建一个具有现代化外观的桌面游戏应用程序。我们实现了基本的游戏逻辑、动态更新UI、以及附加的功能如历史记录、二维码显示和主题切换。通过这个项目,你可以深入了解如何使用Python创建复杂的图形用户界面,并且扩展到更多的功能和设计。

 交流扩列在主页加WX 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/876047.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql中如何实现两列的值互换?给你提供些思路。

文章目录 Mysql中如何实现两列的值互换1、第一感觉此sql应该能处理问题了2、需要一个地方存要替换的值&#xff0c;不然两列搞不定。2.1 加第三列&#xff1f;&#xff08;能解决&#xff0c;但是看起来呆呆&#xff09;2.2 上临时表&#xff08;搞点弯路走走&#xff09; 示例…

【Python】基础学习技能提升代码样例2:小功能块

配合以前两篇文章使用&#xff1a; python易忘操作和小知识点集锦 常用算法模板与知识点 使用 Python 3.x 一、小功能 # 把数字转换为货币字符串 import locale # Set the locale to United States locale.setlocale(locale.LC_ALL, en_US.UTF-8) # Example number amount …

直线与曲线的交点

直线与曲线的交点 在数学和计算机图形学中&#xff0c;计算直线与曲线的交点通常涉及到解方程组的问题。这里以Python为例&#xff0c;介绍如何求解直线与二次曲线&#xff08;如抛物线&#xff09;的交点。 直线与抛物线的交点 假设我们有一条直线 (y mx b) 和一条抛物线 …

法制史学习笔记(个人向) Part5

法制史学习笔记(个人向) Part5 7. 宋朝法律制度 这里强烈推荐B站up主有点意思研究所和嘉佑生宣&#xff0c;宋史看他们基本齐了。 7.1 立法概况 7.1.1 宋刑统&#x1f338; 宋朝建立后不久&#xff0c;太祖赵匡胤即制定颁布了《宋建隆重详定刑统》&#xff0c;简称《宋刑统…

Jenkins 服务搭建以及自动化编译部署

安装环境&#xff1a;Ubuntu22.04 1.首先安装Jenkins 这是 Jenkins 的 Debian 软件包存储库&#xff0c;用于自动安装和升级。 要使用此存储库&#xff0c;请先将密钥添加到系统中&#xff0c;在服务器执行命令&#xff1a; curl -fsSL https://pkg.jenkins.io/debian-stable…

如何在 SpringBoot 中优雅的做参数校验?

一、故事背景 关于参数合法性验证的重要性就不多说了&#xff0c;即使前端对参数做了基本验证&#xff0c;后端依然也需要进行验证&#xff0c;以防不合规的数据直接进入服务器&#xff0c;如果不对其进行拦截&#xff0c;严重的甚至会造成系统直接崩溃&#xff01; 本文结合…

Windows下编译安装Kratos

Kratos是一款开源跨平台的多物理场有限元框架。本文记录在Windows下编译Kratos的流程。 Ref. from Kratos KRATOS Multiphysics ("Kratos") is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, a…

昇思25天学习打卡营第24天|RNN实现情感分类

RNN实现情感分类学习总结 概述 情感分类是自然语言处理领域的重要任务&#xff0c;主要用于识别文本中表达的情绪。本文使用MindSpore框架实现基于RNN的情感分类模型&#xff0c;示例包括&#xff1a; 输入: “This film is terrible” -> 标签: Negative输入: “This fi…

UE5.4内容示例(1)- 学习笔记

https://www.unrealengine.com/marketplace/zh-CN/product/content-examples 《内容示例》是学习UE5的基础示例&#xff0c;可以用此示例熟悉一遍UE5的功能 模型与材质部分 StaticMeshes FBX_Import_Options Material_Advanced Material_Decals Material_Instances Material_N…

MySQL零散拾遗(八)--- MySQL正则表达式

MySQL 支持使用正则表达式进行模式匹配&#xff0c;这对于复杂的字符串处理非常有用。MySQL 中的正则表达式可以通过 REGEXP 或 RLIKE 运算符来实现。下面详细介绍 MySQL 中正则表达式的语法和一些常用的正则表达式模式。 正则表达式基础 锚点 ^: 匹配字符串开头$: 匹配字符串…

Python 高阶语法

前言&#xff1a; 我们通过上篇文章学习了Python的基础语法&#xff0c;接下来我们来学习Python的高阶语法 1.初识对象 在Python中我们可以做到和生活中那样&#xff0c;设计表格、生产表格、填写表格的组织形式的 面向对象包含 3 大主要特性&#xff1a;  封装  继承 …

Zilliz 推出 Spark Connector:简化非结构化数据处理流程

随着人工智能&#xff08;AI&#xff09;和深度学习&#xff08;Deep Learning&#xff09;技术的高速发展&#xff0c;使用神经网络模型将数据转化为 Embedding 向量 已成为处理非结构化数据并实现语义检索的首选方法&#xff0c;广泛应用于搜索、推荐系统等 AI 业务中。 以生…

架构建模-系统架构师(三十二)

1、DNS配置文件是&#xff08;&#xff09;&#xff0c;它包含了主机的域名搜索顺序和DNS服务器地址。 A /etc/hostname B /dev/host.conf C /etc/resolv.conf D /dev/name.conf 解析&#xff1a; 保存在etc/reolv.conf 2、信息隐蔽式开发整体程序时使用的法则&#xff0c…

C语言 定义结构体变量并计算该日在本年中是第几天

定义一个结构体变量(包括年、月、日)。计算该日在本年中是第几天,注意闰年问题&#xff08;即将闰年情况包含在内&#xff09;。 #include <stdio.h>typedef struct {int year;int month;int day; } Date;int isLeapYear(int year) {if ((year % 4 0 && year %…

力扣202.快乐数

202. 快乐数 - 力扣&#xff08;LeetCode&#xff09; 主要是用到了鸽巢原理&#xff0c;最后他们一定会重合&#xff0c;我们只需要判断类似&#xff0c;链表的成环相遇的时候是不是1就行了 class Solution { public:int bitsum(int n){int sum 0;while (n){int a 0;a n …

用护眼灯还需要开灯吗?护眼灯行业三大套路迷局揭秘

用护眼灯还需要开灯吗&#xff1f;在使用护眼台灯时&#xff0c;同时开启室内的主照明十分必要。如果关闭其他灯具&#xff0c;仅保留护眼台灯&#xff0c;那么只有台灯周围的小片区域能够被照亮&#xff0c;而房间的其他部分则处于相对昏暗的状态。这种明显的光线差异会造成视…

freertos的学习cubemx版

HAL 库的freertos 1 实时 2 任务->线程 3 移植 CMSIS_V2 V1版本 NVIC配置全部是抢占优先级 第四组 抢占级别有 0-15 编码规则&#xff0c; 变量名 &#xff1a;类型前缀&#xff0c; c - char S - int16_t L - int32_t U - unsigned Uc - uint8_t Us - uint…

Java常见的面试二

1、普通类和抽象类有那些区别 普通类中不能有抽象方法&#xff0c;抽象类中可以有抽象方法普通类可以直接实例化&#xff0c;抽象类不能直接实例化 2、抽象类能够使用final修饰吗 不能&#xff0c;抽象类是由子类继承的&#xff0c;但是final修饰的类不能被继承。两者矛盾所以…

《书生大模型实战营第3期》入门岛 学习笔记与作业:Python 基础知识

文章大纲 Python 简介1 安装Python1.1 什么是conda&#xff1f;1.1.1 功能与作用&#xff1a;1.1.2 常用命令&#xff1a;1.1.3 适用性&#xff1a; 1.2 Python安装与学习环境准备1.2.1 下载miniconda1.2.2 安装miniconda1.2.3 创建一个python练习专属的conda虚拟环境 2: Pytho…