2024秋软件工程课程个人作业(第二次)

软件工程课程 班级链接
作业要求 作业链接
作业目标 用python开发“羊了个羊”小游戏
学号 102201312

一、《球了个球》介绍

注意:项目已在Github开源,请跳转至链接Github软工个人第二次作业

(1)游戏背景

​ 随着进入大三以来体育课被取缔以及学业课程越来越繁重,同学们很难腾出时间来进行体育锻炼。正所谓“每天锻炼一小时 健康工作五十年 幸福生活一辈子”,体育锻炼是重要的。本游戏旨在用球类消消乐激发同学们进行体育锻炼的热情。

(2)游戏规则介绍

​ 1.游戏设有三个关卡,玩家通过点击选择图案,三个相同图标即可消除,当所有图案被消除时就可进入下一个关卡。若超出选择限制(7个)则游戏失败。

​ 2.每关难度呈指数级上涨,以此分数也会递增。第一关每消掉三个加一分,第二关每消掉三个加两分,第三关则加三分。

(3)实现功能

  • 主菜单,四个按钮交互
  • 三种难度模式,给玩家不同的挑战体验。
  • 分数奖励机制,为玩家提供鼓励。
  • 排行榜,让玩家得到竞赛的快感。
  • 鼠标悬停到选块,出现提示音效

二、我的项目实现过程

我的编程环境:vscode

我的AIGC应用:Github Copilot+ChatGPT

我的AI文生图:Copilot.Microsoft

我的免费可商用图标来源:(icons8.com)

三、游戏展示及过程

1.游戏主界面

2.游戏的三个关卡

难度指数级上升

3.游戏的胜利界面

4.游戏失败界面

5.排行榜界面

递减排序

6.游戏所用图标展示

四、游戏实际测试

第一关

第二关

五、核心算法展示和实现过程

1.主要逻辑

我设置了多种游戏状态game_state,使我流程顺利地在主菜单与其他界面之间切换状态。

2.三种关卡的算法

①第一关

我询问了Github Copilot,它为我生成了简单的算法,以下是它的代码和分析。

# 第一关:只有一个平层,没有覆盖
def initialize_tiles_level1():
    global tiles
    tiles = []
    ts = list(range(1, 13)) * 3  # 根据需要减少牌的数量
    random.shuffle(ts)
    n = 0
    rows = 6  # 控制行数
    cols = 6  # 控制列数

    # 在平面上布局牌,没有层次
    for i in range(rows):
        for j in range(cols):
            if n >= len(ts):
                break
            t = ts[n]
            n += 1
            tile_img = pygame.image.load(f'images/tile{t}.png')
            tile = {
                'image': tile_img,
                'rect': tile_img.get_rect(),  # 牌的位置用于碰撞检测
                'tag': t,  # 牌的标签1-12
                'layer': 0,  # 没有层次
                'status': 1  # 所有牌可点击
            }
            tile['rect'].topleft = (100 + j * tile_img.get_width(),
                                    100 + i * tile_img.get_height() * 0.9)
            tiles.append(tile)

②第二关

# 第二关:金字塔
def initialize_tiles_level2():
    global tiles
    tiles = []
    ts = list(range(1, 13)) * 12
    random.shuffle(ts)
    n = 0
    for k in range(7): # 7层
        for i in range(7 - k): # 行
            for j in range(7 - k): # 列
                t = ts[n]
                n += 1
                tile_img = pygame.image.load(f'images/tile{t}.png')
                tile = {
                    'image': tile_img,
                    'rect': tile_img.get_rect(), # 牌的位置用于碰撞检测
                    'tag': t,   # 牌的标签1-12
                    'layer': k, # 牌的层数
                    'status': 1 if k == 6 else 0  # 只有最上层的牌可点击
                }
                tile['rect'].topleft = (120 + (k * 0.5 + j) * tile_img.get_width(),
                                        100 + (k * 0.5 + i) * tile_img.get_height() * 0.9)
                tiles.append(tile)
    # 将多余的4张牌放到下面
    for i in range(4):
        t = ts[n]
        n += 1
        tile_img = pygame.image.load(f'images/tile{t}.png')
        tile = {
            'image': tile_img,
            'rect': tile_img.get_rect(topleft=(210 + i * tile_img.get_width(), 516)),
            'tag': t,
            'layer': 0,
            'status': 1
        }
        tiles.append(tile)

③第三关

根据前两个的布局,我让Github Copilot为我生成了更有难度的算法。(我自己都无法通关)

# 第三关:更复杂的布局和更多层次
def initialize_tiles_level3():
    global tiles
    tiles = []
    
    # 计算总共需要的牌数
    total_tiles_needed = sum((9 - k) ** 2 for k in range(9)) + 6  # 每层和底部的独立牌
    ts = list(range(1, 13)) * ((total_tiles_needed // 12) + 1)  # 根据需要重复生成牌
    random.shuffle(ts)
    n = 0
    layer_offsets = [0, 0.5, 1.0]  # 控制每层牌的偏移,制造更复杂的布局

    y_offset = -30  # 向上移动 50 像素
    x_offset = -80  # 向左移动 30 像素

    # 9层的复杂布局,每层牌数量不同
    for k in range(9):  # 9层
        offset = layer_offsets[k % len(layer_offsets)]  # 使用偏移
        rows = 9 - k  # 行数随层数减少
        cols = 9 - k  # 列数随层数减少
        for i in range(rows):  # 行
            for j in range(cols):  # 列
                if n >= total_tiles_needed:
                    break
                t = ts[n]
                n += 1
                tile_img = pygame.image.load(f'images/tile{t}.png')
                tile = {
                    'image': tile_img,
                    'rect': tile_img.get_rect(),  # 牌的位置用于碰撞检测
                    'tag': t,  # 牌的标签1-12
                    'layer': k,  # 牌的层数
                    'status': 1 if k == 8 else 0  # 只有最上层的牌可点击
                }
                # 左移和上移 tile 的 X 和 Y 坐标
                tile['rect'].topleft = (120 + (offset + j) * tile_img.get_width() + x_offset,
                                        50 + (offset + i) * tile_img.get_height() * 0.9 + y_offset)
                tiles.append(tile)

    # 在底部随机放一些独立的牌
    for i in range(6):
        t = ts[n]
        n += 1
        tile_img = pygame.image.load(f'images/tile{t}.png')
        tile = {
            'image': tile_img,
            'rect': tile_img.get_rect(topleft=(random.randint(100, 500) + x_offset, random.randint(500, 600) + y_offset)),
            'tag': t,
            'layer': 0,
            'status': 1
        }
        tiles.append(tile)

六、AIGC表格:学习内容及心得体会

AI辅助

子任务 AIGC技术 实现功能 效果如何
界面设计 Copilot 代码参考,基本框架构建 提供了较为简单的基础框架,方便进一步优化,但也存在一些小bug
按钮设计 Copilot 代码参考,基本框架构建 提供了pygame按钮设计的相关函数,经过简单修改可以正常使用
功能参考 ChatGPT 代码参考,基本框架构建 提供了一些函数的相关设计思路,比如图像消除等,要实现个性化的复杂代码还需要进一步调试
素材参考 icons8 提供免费图片素材 告诉了一些网站参考和相关途径,有一定参考价值
图片生成 Copilot 文生图生成简单logo 部分可以使用,需要耐心调试

AI生成表格

项目 内容
作业题目 开发“羊了个羊”小游戏
背景 同学们体育时间减少,需要激发运动热情
主要收获 1. 学习了如何使用Pygame设计游戏界面。 2. 理解了图案生成与消除的基本逻辑。 3. 掌握了如何利用AIGC工具生成代码。
遇到的挑战 1. 实现图案的合理匹配与消除。 2. 设置倒计时机制和难度调整。 3. 确保代码结构清晰且可维护。
改进建议 1. 增强图案消除算法以提高游戏体验。2.添加点击特效,增加绿框。 3. 改进界面设计以提高用户体验。

七、PSP表格:任务分解与时间管理

任务 描述 预估耗时 (小时) 实际耗时 (小时) 差异 (小时) 备注
计划和需求分析 预估项目开发时间,制定整体开发计划 1 2 +1
游戏界面设计 使用Pygame或其他图形库设计主菜单、游戏界面和结束界面。 5 7 +2 界面设计比较简洁轻快,可以增加更多功能
图案生成与摆放 实现图案的生成和分层摆放逻辑。 3 2 -1 图案生成符合预期,较为合理
图案选择与消除逻辑 实现玩家点击选择图案并消除的逻辑。 4 2 -2 消除逻辑顺利实现,功能正常。
排行榜机制 设置分数和排行榜功能,游戏失败后计入前十名。 2 1 -1 排行榜机制实现得比较顺利。
难度设置 随机生成图案摆放顺序或设置不同的关卡增加难度。 3 2.5 -0.5 难度设置效果良好,但关卡设计还有很大提高空间。
使用AIGC工具生成代码 利用OpenAI等工具生成部分代码。 2 3 +1 代码生成较为准确,注释清晰。但仍需要人为调整修正
代码测试与调试 测试游戏功能并修复可能的bug。 5 7 +2 测试过程中发现了一些意外的bug,通过修复得以解决
文档编写与注释 编写代码注释和项目文档。 2 3 +1 文档编写比较顺利,注释完整。
总耗时 27 29.5

八、 项目总结

​ 在这个项目中,我借助 Pygame 学会了从零开始开发一款 小 游戏,特别是在界面布局、音效设计与逻辑处理上有了显著的进步。我更深入地认识到了细节设计的重要性,比如图标的点击反馈和音效的应用如何显著提升游戏体验。此外,通过对 PSP 表格的管理,我的时间管理和项目组织能力也得到了很好的锻炼。

​ 不过时间仓促,有一些功能仍然没有实现,希望以后能将这个项目完善。