Python小游戏实战:实现2048游戏小游戏附源码

发布于:2025-09-02 ⋅ 阅读:(14) ⋅ 点赞:(0)

在这里插入图片描述

在这里插入图片描述

Python小游戏实战:实现2048游戏小游戏附源码

Python小游戏实战:实现2048游戏小游戏附源码,该教程详细介绍用 Python 实现 2048 游戏的全流程,适合初学者和游戏开发爱好者。首先需准备 Python 3.6 + 环境,安装 pygame 库并验证。核心逻辑拆解为五大模块:初始化模块创建 4x4 网格并随机生成 2 个初始数字(2 或 4);键盘事件处理模块通过 “压缩 - 合并 - 压缩” 逻辑实现上下左右滑动;状态检测模块判断胜利(合成 2048 及以上)与游戏结束(无空格且无法合并);界面渲染模块绘制网格、方块及状态提示;主循环模块整合各部分实现完整运行流程。还提供完整代码整合方法、运行步骤,后续可进一步拓展功能。

在这里插入图片描述

前言

    Python作为一门简洁、易读、功能强大的编程语言,其基础语法是入门学习的核心。掌握好基础语法,能为后续的编程实践打下坚实的基础。本文将全面讲解Python3的基础语法知识,适合编程初学者系统学习。Python以其简洁优雅的语法和强大的通用性,成为当今最受欢迎的编程语言。本专栏旨在系统性地带你从零基础入门到精通Python核心。无论你是零基础小白还是希望进阶的专业开发者,都将通过清晰的讲解、丰富的实例和实战项目,逐步掌握语法基础、核心数据结构、函数与模块、面向对象编程、文件处理、主流库应用(如数据分析、Web开发、自动化)以及面向对象高级特性,最终具备独立开发能力和解决复杂问题的思维,高效应对数据分析、人工智能、Web应用、自动化脚本等广泛领域的实际需求。

在这里插入图片描述


在这里插入图片描述

🥇 点击进入Python入门专栏,Python凭借简洁易读的语法,是零基础学习编程的理想选择。本专栏专为初学者设计,系统讲解Python核心基础:变量、数据类型、流程控制、函数、文件操作及常用库入门。通过清晰示例与实用小项目,助你快速掌握编程思维,打下坚实根基,迈出自动化办公、数据分析或Web开发的第一步。

🥇 点击进入Python小游戏实战专栏, 寓教于乐,用Python亲手打造经典小游戏!本专栏通过开发贪吃蛇、飞机大战、猜数字、简易版俄罗斯方块等趣味项目,在实践中掌握Python核心语法、面向对象编程、事件处理、图形界面(如Pygame)等关键技能,将枯燥的代码学习转化为可见的成果,让学习编程充满乐趣与成就感,快速提升实战能力。

🥇 点击进入Python小工具实战专栏,告别重复劳动,用Python打造效率神器!本专栏教你开发文件批量处理、自动邮件通知、简易爬虫、桌面提醒、密码生成器、天气查询等实用小工具。聚焦os、shutil、requests、smtplib、schedule等核心库,通过真实场景案例,快速掌握自动化脚本编写技巧,解放双手,显著提升工作与生活效率,让代码真正服务于你的日常。

🥇 点击进入Python爬虫实战专栏,解锁网络数据宝库!本专栏手把手教你使用Python核心库(如requests、BeautifulSoup、Scrapy)构建高效爬虫。从基础网页解析到动态页面抓取、数据存储(CSV/数据库)、反爬策略应对及IP代理使用,通过实战项目(如电商比价、新闻聚合、图片采集、舆情监控),掌握合法合规获取并利用网络数据的核心技能,让数据成为你的超能力。

🥇 点击进入Python项目实战专栏,告别碎片化学习,挑战真实项目!本专栏精选Web应用开发(Flask/Django)、数据分析可视化、自动化办公系统、简易爬虫框架、API接口开发等综合项目。通过需求分析、架构设计、编码实现、测试部署的全流程,深入掌握工程化开发、代码复用、调试排错与团队协作核心能力,积累高质量作品集,真正具备解决复杂问题的Python实战经验。


✨ 正文开始

2048 游戏是一款经典的数字合并类小游戏,通过上下左右滑动屏幕使相同数字叠加,最终目标是合成 2048(或更高)的数字方块。本文将带大家使用 Python 从零开发一款可运行的 2048 游戏,涵盖环境搭建、核心逻辑实现、界面设计全流程,适合 Python 初学者和小游戏开发爱好者学习。

一、开发环境准备

1.1 核心依赖库

2048 游戏开发需要用到两个核心库:

  • pygame:用于创建游戏窗口、处理键盘事件和渲染图形界面

  • random:Python 内置库,用于随机生成新的数字方块(2 或 4)

1.2 环境安装步骤

步骤 1:检查 Python 环境

确保已安装 Python 3.6 及以上版本,打开终端执行以下命令验证:

python --version  # Windows系统
# 或
python3 --version  # Mac/Linux系统

在这里插入图片描述

步骤 2:安装 pygame 库

通过 pip 工具安装 pygame,终端执行命令:

pip install pygame  # Windows系统
# 或
pip3 install pygame  # Mac/Linux系统
步骤 3:验证安装

安装完成后,在 Python 交互环境中测试 pygame 是否正常导入:

import pygame

print(pygame.ver)  # 输出pygame版本号即表示安装成功

在这里插入图片描述

二、游戏核心逻辑设计

2048 游戏的核心逻辑可拆解为 5 个关键模块,我们将逐一实现:

2.1 游戏初始化模块

初始化包括创建 4x4 游戏网格、随机生成初始数字(2 个方块,值为 2 或 4)。

代码实现:
import pygame

import random

import sys

# 游戏常量定义

CELL_SIZE = 100  # 每个格子的大小(像素)

CELL_GAP = 10    # 格子之间的间距(像素)

GRID_SIZE = 4    # 4x4网格

WINDOW_WIDTH = CELL_SIZE * GRID_SIZE + CELL_GAP * (GRID_SIZE + 1)

WINDOW_HEIGHT = WINDOW_WIDTH  # 正方形窗口

BACKGROUND_COLOR = (187, 173, 160)  # 背景色

CELL_EMPTY_COLOR = (205, 193, 180)  # 空格子颜色

# 数字方块颜色映射(key:数字值,value:(背景色, 文字色))

CELL_COLORS = {

   2: ((238, 228, 218), (119, 110, 101)),

   4: ((237, 224, 200), (119, 110, 101)),

   8: ((242, 177, 121), (255, 248, 240)),

   16: ((245, 149, 99), (255, 248, 240)),

   32: ((246, 124, 95), (255, 248, 240)),

   64: ((246, 94, 59), (255, 248, 240)),

   128: ((237, 207, 114), (255, 248, 240)),

   256: ((237, 204, 97), (255, 248, 240)),

   512: ((237, 200, 80), (255, 248, 240)),

   1024: ((237, 197, 63), (255, 248, 240)),

   2048: ((237, 194, 46), (255, 248, 240)),

   4096: ((60, 58, 50), (255, 248, 240)),

   8192: ((60, 58, 50), (255, 248, 240))

}

def init_grid():

   """初始化4x4游戏网格,所有格子初始为0(空)"""

   grid = [[0 for _ in range(GRID_SIZE)] for _ in range(GRID_SIZE)]

   # 随机生成2个初始数字

   add_random_cell(grid)

   add_random_cell(grid)

   return grid

def add_random_cell(grid):

   """在空格子中随机添加一个2(90%概率)或4(10%概率)"""

   # 获取所有空格子坐标

   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

2.2 键盘事件处理模块

处理上下左右四个方向键的输入,实现格子的滑动逻辑。核心思路是:先压缩(去除空格子)→ 再合并(相同数字叠加)→ 再压缩(合并后可能产生新空格)

代码实现:
def handle_left(grid):

   """处理向左滑动逻辑"""

   new_grid = []

   for row in grid:

       # 步骤1:去除空格子(压缩)

       compressed = [num for num in row if num != 0]

       # 步骤2:合并相同数字

       merged = []

       i = 0

       while i < len(compressed):

           if i + 1 < len(compressed) and compressed[i] == compressed[i + 1]:

               merged.append(compressed[i] * 2)  # 相同数字合并,值翻倍

               i += 2  # 跳过下一个已合并的数字

           else:

               merged.append(compressed[i])

               i += 1

       # 步骤3:补充空格子(确保每行4个元素)

       merged += [0] * (GRID_SIZE - len(merged))

       new_grid.append(merged)

   return new_grid

def handle_right(grid):

   """处理向右滑动逻辑(先反转行,再调用向左逻辑,最后再反转)"""

   new_grid = []

   for row in grid:

       reversed_row = row[::-1]  # 反转行(如[2,0,0,4]→[4,0,0,2])

       processed_row = handle_left([reversed_row])[0]  # 调用向左逻辑

       new_grid.append(processed_row[::-1])  # 再次反转恢复方向

   return new_grid

def handle_up(grid):

   """处理向上滑动逻辑(先转置网格,再调用向左逻辑,最后再转置)"""

   # 转置网格(行变列,如[[1,2],[3,4]]→[[1,3],[2,4]])

   transposed_grid = list(zip(*grid))

   new_transposed = []

   for row in transposed_grid:

       processed_row = handle_left([list(row)])[0]  # 调用向左逻辑

       new_transposed.append(processed_row)

   # 再次转置恢复原方向

   new_grid = list(zip(*new_transposed))

   return [list(row) for row in new_grid]

def handle_down(grid):

   """处理向下滑动逻辑(先转置网格,再调用向右逻辑,最后再转置)"""

   transposed_grid = list(zip(*grid))

   new_transposed = []

   for row in transposed_grid:

       processed_row = handle_right([list(row)])[0]  # 调用向右逻辑

       new_transposed.append(processed_row)

   new_grid = list(zip(*new_transposed))

   return [list(row) for row in new_grid]

2.3 游戏状态检测模块

检测游戏是否结束(无空格子且无法合并)或胜利(合成 2048 及以上数字)。

代码实现:
def check_win(grid):

   """检测是否胜利(存在2048及以上数字)"""

   for row in grid:

       if any(num >= 2048 for num in row):

           return True

   return False

def check_game_over(grid):

   """检测是否游戏结束(无空格子且无法合并)"""

   # 1. 检查是否有空格子

   for row in grid:

       if 0 in row:

           return False

   # 2. 检查水平方向是否可合并

   for i in range(GRID_SIZE):

       for j in range(GRID_SIZE - 1):

           if grid[i][j] == grid[i][j + 1]:

               return False

   # 3. 检查垂直方向是否可合并

   for j in range(GRID_SIZE):

       for i in range(GRID_SIZE - 1):

           if grid[i][j] == grid[i + 1][j]:

               return False

   # 无空格子且无法合并 → 游戏结束

   return True

2.4 界面渲染模块

使用 pygame 绘制游戏窗口、网格、数字方块和游戏状态提示(胜利 / 失败)。

代码实现:
def draw_grid(screen, grid):

   """绘制4x4游戏网格"""

   # 填充背景色

   screen.fill(BACKGROUND_COLOR)

  

   for i in range(GRID_SIZE):

       for j in range(GRID_SIZE):

           # 计算每个格子的坐标(x:列方向,y:行方向)

           x = CELL_GAP + j * (CELL_SIZE + CELL_GAP)

           y = CELL_GAP + i * (CELL_SIZE + CELL_GAP)

          

           # 获取格子颜色(空格子或对应数字颜色)

           cell_value = grid[i][j]

           if cell_value == 0:

               bg_color = CELL_EMPTY_COLOR

               text_color = (0, 0, 0)  # 空格子无文字,颜色不影响

           else:

               bg_color, text_color = CELL_COLORS.get(

                   cell_value, ((60, 58, 50), (255, 248, 240))  # 超过8192的默认颜色

               )

          

           # 绘制格子(圆角矩形,使用rect模拟)

           pygame.draw.rect(screen, bg_color, (x, y, CELL_SIZE, CELL_SIZE), border_radius=4)

          

           # 绘制数字(空格子不绘制)

           if cell_value != 0:

               # 设置字体大小(数字越大,字体越小)

               font_size = 40 if cell_value < 100 else 32 if cell_value < 1000 else 24

               font = pygame.font.Font(None, font_size)

               text_surface = font.render(str(cell_value), True, text_color)

               # 计算文字居中坐标

               text_rect = text_surface.get_rect(center=(x + CELL_SIZE//2, y + CELL_SIZE//2))

               screen.blit(text_surface, text_rect)

def draw_game_status(screen, status):

   """绘制游戏状态提示(胜利/失败)"""

   # 创建半透明遮罩

   overlay = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT), pygame.SRCALPHA)

   overlay.fill((0, 0, 0, 128))  # 黑色半透明(alpha=128)

   screen.blit(overlay, (0, 0))

  

   # 设置提示文字

   font = pygame.font.Font(None, 64)

   text_surface = font.render(status, True, (255, 255, 255))

   text_rect = text_surface.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2 - 50))

   screen.blit(text_surface, text_rect)

  

   # 设置重新开始提示

   font_small = pygame.font.Font(None, 32)

   restart_surface = font_small.render("按R键重新开始", True, (255, 255, 255))

   restart_rect = restart_surface.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2 + 50))

   screen.blit(restart_surface, restart_rect)

2.5 主游戏循环模块

整合所有模块,实现游戏的完整运行流程:初始化→事件监听→逻辑更新→界面渲染→状态检测。

代码实现:
def main():

   # 初始化pygame

   pygame.init()

   pygame.font.init()  # 初始化字体模块

   screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))

   pygame.display.set_caption("Python 2048游戏")

   clock = pygame.time.Clock()  # 控制游戏帧率

  

   # 游戏状态初始化

   grid = init_grid()

   game_win = False

   game_over = False

   last_grid = [row.copy() for row in grid]  # 记录上一帧网格(用于判断是否滑动成功)

  

   while True:

       # 1. 事件监听

       for event in pygame.event.get():

           # 退出游戏

           if event.type == pygame.QUIT:

               pygame.quit()

               sys.exit()

          

           # 键盘事件(仅在游戏未结束/未胜利时响应方向键)

           if event.type == pygame.KEYDOWN:

               # 重新开始游戏(按R键)

               if event.key == pygame.K_r:

                   grid = init_grid()

                   game_win = False

                   game_over = False

                   last_grid = [row.copy() for row in grid]

                   continue

              

               # 方向键控制(仅在游戏未结束时生效)

               if not game_win and not game_over:

                   last_grid = [row.copy() for row in grid]  # 记录滑动前的网格

                   if event.key == pygame.K_LEFT:

                       grid = handle_left(grid)

                   elif event.key == pygame.K_RIGHT:

                       grid = handle_right(grid)

                   elif event.key == pygame.K_UP:

                       grid = handle_up(grid)

                   elif event.key == pygame.K_DOWN:

                       grid = handle_down(grid)

      

       # 2. 逻辑更新(滑动成功后添加新数字)

       if not game_win and not game_over and grid != last_grid:

           add_random_cell(grid)

           # 检测游戏状态

           if check_win(grid):

               game_win = True

           if check_game_over(grid):

               game_over = True

      

       # 3. 界面渲染

       draw_grid(screen, grid)

       # 绘制胜利/失败提示

       if game_win:

           draw_game_status(screen, "恭喜胜利!")

       if game_over:

           draw_game_status(screen, "游戏结束!")

      

       # 4. 更新屏幕

       pygame.display.update()

       clock.tick(30)  # 控制游戏帧率为30 FPS

# 程序入口

if __name__ == "__main__":

   main()

三、完整代码整合与运行

3.1 完整代码

将上述所有模块代码整合到一个文件(如2048_game.py),并优化调整,完整代码如下:

import pygame
import random
import sys
import os

# ------------------------------
# 1. 游戏常量定义(调整字体大小)
# ------------------------------
CELL_SIZE = 100
CELL_GAP = 10
GRID_SIZE = 4
# 窗口尺寸计算
WINDOW_WIDTH = CELL_SIZE * GRID_SIZE + CELL_GAP * (GRID_SIZE + 1)
WINDOW_HEIGHT = WINDOW_WIDTH + 60  # 适度增加高度

# 颜色常量
COLOR_BACKGROUND = (187, 173, 160)
COLOR_EMPTY_CELL = (205, 193, 180)
CELL_COLOR_MAP = {
    2: ((238, 228, 218), (119, 110, 101)),
    4: ((237, 224, 200), (119, 110, 101)),
    8: ((242, 177, 121), (255, 248, 240)),
    16: ((245, 149, 99), (255, 248, 240)),
    32: ((246, 124, 95), (255, 248, 240)),
    64: ((246, 94, 59), (255, 248, 240)),
    128: ((237, 207, 114), (255, 248, 240)),
    256: ((237, 204, 97), (255, 248, 240)),
    512: ((237, 200, 80), (255, 248, 240)),
    1024: ((237, 197, 63), (255, 248, 240)),
    2048: ((237, 194, 46), (255, 248, 240)),
    4096: ((60, 58, 50), (255, 248, 240)),
    8192: ((60, 58, 50), (255, 248, 240))
}

# 调整字体大小,解决溢出问题
FONT_LARGE = 36  # 进一步减小
FONT_MEDIUM = 30  # 进一步减小
FONT_SMALL = 24  # 进一步减小
FONT_TINY = 18  # 进一步减小


# ------------------------------
# 2. 辅助函数
# ------------------------------
def get_chinese_font(size):
    """获取支持中文的字体"""
    font_names = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC", "Microsoft YaHei"]

    for font_name in font_names:
        try:
            return pygame.font.SysFont(font_name, size)
        except:
            continue

    print("警告: 未找到支持中文的字体,可能导致中文显示异常")
    return pygame.font.Font(None, size)


# ------------------------------
# 3. 网格核心操作
# ------------------------------
def init_grid() -> list[list[int]]:
    """初始化4x4网格,添加2个随机单元格"""
    grid = [[0 for _ in range(GRID_SIZE)] for _ in range(GRID_SIZE)]
    add_random_cell(grid)
    add_random_cell(grid)
    return grid


def add_random_cell(grid: list[list[int]]) -> None:
    """在空白单元格中随机添加2(90%概率)或4(10%概率)"""
    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


def compress_and_merge(row: list[int]) -> list[int]:
    """压缩并合并单行"""
    compressed = [num for num in row if num != 0]
    merged = []
    i = 0
    while i < len(compressed):
        if i + 1 < len(compressed) and compressed[i] == compressed[i + 1]:
            merged.append(compressed[i] * 2)
            i += 2
        else:
            merged.append(compressed[i])
            i += 1
    merged += [0] * (GRID_SIZE - len(merged))
    return merged


def handle_left(grid: list[list[int]]) -> list[list[int]]:
    return [compress_and_merge(row) for row in grid]


def handle_right(grid: list[list[int]]) -> list[list[int]]:
    return [compress_and_merge(row[::-1])[::-1] for row in grid]


def handle_up(grid: list[list[int]]) -> list[list[int]]:
    transposed = list(zip(*grid))
    processed = [compress_and_merge(list(row)) for row in transposed]
    return [list(row) for row in zip(*processed)]


def handle_down(grid: list[list[int]]) -> list[list[int]]:
    transposed = list(zip(*grid))
    processed = [compress_and_merge(row[::-1])[::-1] for row in transposed]
    return [list(row) for row in zip(*processed)]


def check_win(grid: list[list[int]]) -> bool:
    return any(num >= 2048 for row in grid for num in row)


def check_game_over(grid: list[list[int]]) -> bool:
    if any(0 in row for row in grid):
        return False
    for i in range(GRID_SIZE):
        for j in range(GRID_SIZE - 1):
            if grid[i][j] == grid[i][j + 1]:
                return False
    for j in range(GRID_SIZE):
        for i in range(GRID_SIZE - 1):
            if grid[i][j] == grid[i + 1][j]:
                return False
    return True


# ------------------------------
# 4. 渲染显示模块(优化布局)
# ------------------------------
def draw_grid(screen: pygame.Surface, grid: list[list[int]]) -> None:
    """绘制游戏网格与单元格"""
    screen.fill(COLOR_BACKGROUND)

    for i in range(GRID_SIZE):
        for j in range(GRID_SIZE):
            # 调整单元格位置,为标题留出空间
            x = CELL_GAP + j * (CELL_SIZE + CELL_GAP)
            y = CELL_GAP + 50 + i * (CELL_SIZE + CELL_GAP)  # 减少顶部留白
            cell_value = grid[i][j]

            if cell_value == 0:
                bg_color = COLOR_EMPTY_CELL
                text_color = (0, 0, 0)
            else:
                bg_color, text_color = CELL_COLOR_MAP.get(
                    cell_value, ((60, 58, 50), (255, 248, 240))
                )

            pygame.draw.rect(
                screen, bg_color,
                (x, y, CELL_SIZE, CELL_SIZE),
                border_radius=4
            )

            if cell_value != 0:
                # 更精细的字体大小调整
                if cell_value < 100:
                    font_size = FONT_MEDIUM
                elif cell_value < 1000:
                    font_size = FONT_SMALL
                else:
                    font_size = FONT_TINY

                font = get_chinese_font(font_size)
                text_surface = font.render(str(cell_value), True, text_color)
                text_rect = text_surface.get_rect(
                    center=(x + CELL_SIZE // 2, y + CELL_SIZE // 2)
                )
                screen.blit(text_surface, text_rect)


def draw_game_status(screen: pygame.Surface, status_text: str) -> None:
    """绘制游戏状态覆盖层,将提示内容放在一行"""
    overlay = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT), pygame.SRCALPHA)
    overlay.fill((0, 0, 0, 128))
    screen.blit(overlay, (0, 0))

    # 状态文字居中显示
    font_large = get_chinese_font(FONT_LARGE)
    text_surface = font_large.render(status_text, True, (255, 255, 255))
    text_rect = text_surface.get_rect(
        center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 - 20)  # 调整垂直位置
    )
    screen.blit(text_surface, text_rect)

    # 提示文字放在一行,缩小字体
    font_tiny = get_chinese_font(FONT_TINY)
    hint_surface = font_tiny.render("按 R 键重新开始 | 按 Q 键退出", True, (255, 255, 255))
    hint_rect = hint_surface.get_rect(
        center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 + 20)
    )
    screen.blit(hint_surface, hint_rect)


def draw_score_and_title(screen: pygame.Surface, grid: list[list[int]]) -> None:
    """绘制标题和当前分数(优化布局,标题在左,分数在右)"""
    # 绘制标题
    title_font = get_chinese_font(FONT_LARGE)
    title_surface = title_font.render("2048 游戏", True, (119, 110, 101))
    title_rect = title_surface.get_rect(topleft=(20, 10))  # 标题居左
    screen.blit(title_surface, title_rect)

    # 绘制分数,居右
    score = sum(sum(row) for row in grid)
    score_font = get_chinese_font(FONT_SMALL)
    score_surface = score_font.render(f"分数: {score}", True, (119, 110, 101))
    score_rect = score_surface.get_rect(topright=(WINDOW_WIDTH - 20, 20))  # 分数居右
    screen.blit(score_surface, score_rect)


# ------------------------------
# 5. 主游戏逻辑
# ------------------------------
def main() -> None:
    """游戏主函数"""
    pygame.init()
    pygame.font.init()

    screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
    pygame.display.set_caption("2048 游戏")
    clock = pygame.time.Clock()

    grid = init_grid()
    game_win = False
    game_over = False
    last_grid = [row.copy() for row in grid]

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r:
                    grid = init_grid()
                    game_win = False
                    game_over = False
                    last_grid = [row.copy() for row in grid]
                    continue

                if event.key == pygame.K_q:
                    pygame.quit()
                    sys.exit()

                if not game_win and not game_over:
                    last_grid = [row.copy() for row in grid]
                    if event.key == pygame.K_LEFT:
                        grid = handle_left(grid)
                    elif event.key == pygame.K_RIGHT:
                        grid = handle_right(grid)
                    elif event.key == pygame.K_UP:
                        grid = handle_up(grid)
                    elif event.key == pygame.K_DOWN:
                        grid = handle_down(grid)

        if not game_win and not game_over and grid != last_grid:
            add_random_cell(grid)
            if check_win(grid):
                game_win = True
            if check_game_over(grid):
                game_over = True

        draw_grid(screen, grid)
        draw_score_and_title(screen, grid)
        if game_win:
            draw_game_status(screen, "恭喜胜利!")
        if game_over:
            draw_game_status(screen, "游戏结束!")

        pygame.display.update()
        clock.tick(30)


if __name__ == "__main__":
    main()

3.2 代码运行步骤

步骤1:创建代码文件

在本地新建一个文本文件,将上述完整代码复制粘贴到文件中,然后将文件后缀名改为`.py`(例如命名为`2048Game.py`)。

在这里插入图片描述

步骤2:运行游戏
  • 方式1:通过终端运行

打开终端,使用`cd`命令切换到代码文件所在的文件夹,然后执行以下命令:

 python 2048Game.py  # Windows系统
 # 或
 python3 2048Game.py  # Mac/Linux系统
  • 方式 2:通过 Python IDE 运行

    若使用 PyCharm、VS Code 等 IDE,直接打开2048Game.py文件,点击运行按钮(通常是绿色三角形图标)即可启动游戏。

运行效果

在这里插入图片描述

步骤 3:游戏操作说明
  • 上、下、左、右方向键控制方块滑动合并;

  • 合成出 2048 方块时,游戏显示 “恭喜胜利!”,可按R键重新开始;

  • 当无法继续滑动合并且无空格子时,游戏显示 “游戏结束!”,按R键可重新开始;

  • 点击游戏窗口右上角的 “关闭” 按钮,可退出游戏。

四、常见问题与解决方案

4.1 运行报错:ModuleNotFoundError: No module named 'pygame'

问题原因:未安装 pygame 库或安装的 pygame 库未被当前 Python 环境识别。

解决方案

  1. 确认当前使用的 Python 环境,在终端执行which python(Mac/Linux)或where python(Windows)查看 Python 路径;

  2. 使用对应环境的 pip 重新安装 pygame,例如:

# 若使用Python 3.8,且路径为C:\Python38\python.exe(Windows)

C:\Python38\Scripts\pip install pygame

# Mac/Linux若使用python3.8

python3.8 -m pip install pygame

4.2 游戏窗口显示异常(如字体模糊、格子错位)

问题原因:屏幕分辨率或 pygame 版本兼容性问题,导致坐标计算或字体渲染异常。

解决方案

  1. 调整CELL_SIZECELL_GAP常量,例如将CELL_SIZE改为 80,CELL_GAP改为 8,重新运行查看效果;

  2. 更新 pygame 到最新版本:

pip install --upgrade pygame

4.3 方向键无响应

问题原因:可能是键盘输入被其他程序占用,或代码中事件监听逻辑异常。

解决方案

  1. 关闭其他可能占用键盘输入的程序(如输入法、快捷键工具),重新运行游戏;

  2. 检查代码中main()函数内的键盘事件监听部分,确认pygame.K_LEFTpygame.K_RIGHT等常量拼写正确。

五、功能拓展建议(进阶学习)

完成基础版 2048 游戏后,可尝试以下拓展功能,提升编程能力:

5.1 增加分数统计功能

  • 在游戏初始化时添加score = 0变量;

  • 当方块合并时(如handle_left函数中merged.append(compressed[i] * 2)处),将合并后的数字值累加到分数中(score += compressed[i] * 2);

  • draw_grid函数中添加分数显示逻辑,例如在窗口顶部绘制 “分数:XXX” 文字。

5.2 支持自定义网格大小

  • GRID_SIZE常量改为可配置参数,例如通过命令行参数传入网格大小(如python ``2048_game.py`` --size 5表示 5x5 网格);

  • 注意:网格大小改变后,需同步调整窗口大小计算逻辑(WINDOW_WIDTH = CELL_SIZE * GRID_SIZE + CELL_GAP * (GRID_SIZE + 1)),避免窗口显示异常。

5.3 添加音效反馈

  • 下载滑动、合并、胜利、失败等音效文件(格式为.wav.ogg);

  • 使用pygame.mixer模块加载音效文件,例如:

# 初始化音效模块
pygame.mixer.init()

# 加载合并音效
merge_sound = pygame.mixer.Sound("merge.wav")
  • 在对应事件触发时播放音效,例如方块合并时调用merge_sound.play()

5.4 实现存档与读档功能

  • 使用 Python 的pickle模块或 JSON 格式,将当前游戏网格、分数等状态保存到本地文件(如save_data.pkl);

  • 添加存档快捷键(如按S键存档)和读档快捷键(如按L键读档),在main()函数的键盘事件监听中处理存档和读档逻辑。

六、总结

本文通过 “环境准备→核心逻辑实现→完整代码运行→问题解决→功能拓展” 的流程,详细讲解了 Python 实现 2048 游戏的全过程。重点掌握了 pygame 的图形渲染、事件处理,以及 2048 游戏的滑动合并逻辑。

对于 Python 初学者而言,通过开发小游戏可以快速提升代码组织能力和逻辑思维能力。如果在学习过程中遇到问题,可通过 pygame 官方文档(https://www.pygame.org/docs/)或 Python 社区(如 Stack Overflow)查找解决方案。希望大家在实践中不断优化代码,开发出更具个性化的 2048 游戏!

附录:扩展学习资源

  1. 官方资源
  2. 本专栏特色资源
    • 代码资源仓库:CSDN专属资源在线获取
    • 海量Python教程:关注公众号:xcLeigh,获取网盘地址
    • 一对一答疑:添加微信与博主在线沟通(备注“Python专栏”

联系博主

    xcLeigh 博主全栈领域优质创作者,博客专家,目前,活跃在CSDN、微信公众号、小红书、知乎、掘金、快手、思否、微博、51CTO、B站、腾讯云开发者社区、阿里云开发者社区等平台,全网拥有几十万的粉丝,全网统一IP为 xcLeigh。希望通过我的分享,让大家能在喜悦的情况下收获到有用的知识。主要分享编程、开发工具、算法、技术学习心得等内容。很多读者评价他的文章简洁易懂,尤其对于一些复杂的技术话题,他能通过通俗的语言来解释,帮助初学者更好地理解。博客通常也会涉及一些实践经验,项目分享以及解决实际开发中遇到的问题。如果你是开发领域的初学者,或者在学习一些新的编程语言或框架,关注他的文章对你有很大帮助。

    亲爱的朋友,无论前路如何漫长与崎岖,都请怀揣梦想的火种,因为在生活的广袤星空中,总有一颗属于你的璀璨星辰在熠熠生辉,静候你抵达。

     愿你在这纷繁世间,能时常收获微小而确定的幸福,如春日微风轻拂面庞,所有的疲惫与烦恼都能被温柔以待,内心永远充盈着安宁与慰藉。

    至此,文章已至尾声,而您的故事仍在续写,不知您对文中所叙有何独特见解?期待您在心中与我对话,开启思想的新交流。


     💞 关注博主 🌀 带你实现畅游前后端!

     🏰 大屏可视化 🌀 带你体验酷炫大屏!

     💯 神秘个人简介 🌀 带你体验不一样得介绍!

     🥇 从零到一学习Python 🌀 带你玩转Python技术流!

     🏆 前沿应用深度测评 🌀 前沿AI产品热门应用在线等你来发掘!

     💦 :本文撰写于CSDN平台,作者:xcLeigh所有权归作者所有)https://xcleigh.blog.csdn.net/,如果相关下载没有跳转,请查看这个地址,相关链接没有跳转,皆是抄袭本文,转载请备注本文原地址。


在这里插入图片描述

     📣 亲,码字不易,动动小手,欢迎 点赞 ➕ 收藏,如 🈶 问题请留言(或者关注下方公众号,看见后第一时间回复,还有海量编程资料等你来领!),博主看见后一定及时给您答复 💌💌💌


网站公告

今日签到

点亮在社区的每一天
去签到