前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【游戏制作】使用Python创建一个完整的2048游戏项目

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

作者头像
命运之光
发布2024-08-02 07:59:48
1100
发布2024-08-02 07:59:48
举报
文章被收录于专栏:我在本科期间写的文章

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

项目运行展示
项目概述

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

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

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

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

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

代码语言:javascript
复制
pip install ttkbootstrap pillow
代码实现
1. 导入库
代码语言:javascript
复制
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
代码语言:javascript
复制
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界面
代码语言:javascript
复制
    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] = row

        self.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. 加载二维码图片
代码语言:javascript
复制
    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. 创建菜单
代码语言:javascript
复制
    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. 游戏逻辑和功能
代码语言:javascript
复制
    def start_game(self):
        self.matrix = [[0] * 4 for _ in range(4)]
        self.score = 0
        self.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 4

    def 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 + y
                while 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] = 0
                    i, j = ni, nj
                    ni, nj = i + x, j + y

        for 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 + y
            if 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] *= 2
                self.matrix[i][j] = 0
                self.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 True
                if i < 3 and self.matrix[i][j] == self.matrix[i + 1][j]:
                    return True
        return False
7. 运行应用
代码语言:javascript
复制
if __name__ == "__main__":
    app = Game2048()
    app.mainloop()
总结

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-07-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 项目运行展示
  • 项目概述
  • 项目目标
  • 项目结构
  • 安装依赖
  • 代码实现
    • 1. 导入库
      • 2. 创建 Game2048 类
        • 3. 设置UI界面
          • 4. 加载二维码图片
            • 5. 创建菜单
              • 6. 游戏逻辑和功能
                • 7. 运行应用
                • 总结
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档