软件工程课程第二次个人作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/SE2024/
这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13253
这个作业的目标 借助AIGC软件开发一个类似“羊了个羊”风格的消消乐小游戏
学号 102202123

一、项目展示

项目连接

清凉一夏🔗

  • 注:闲时二编重构了部分代码
描述

项目简介

该游戏名为《清凉一夏》,是一款轻松向的消消乐小游戏。

玩家进入游戏前,需要输入自己的用户名,每个用户名将拥有一个游戏积分。
注:用户名只能由小写字母或数字组成

游戏设有三个关卡,每个关卡现时60秒,难度递增,玩法与得分机制如下:
第一关需要点击两个相同的“水果冰”进行消除,每消除一对获得10分;
第二、三关需要连续点击三个相同的“水果冰”进行消除,每消除一对获得15分。

如果在某一局超时仍未完成“水果冰”消除,则游戏失败:
将清空该关卡得分并倒扣100分;
玩家需要重新挑战该关卡,直到胜利进入下一关卡。

游戏过程中提供了两个道具“加料”和“洗牌”:
加料:点击“加料”键将会增加五对“水果冰”,在时间充裕的情况下,是加分的好道具;
洗牌:点击“洗牌”键将会将剩余的“水果冰”重置,以便玩家转换消除思路。

项目准备

1.Pygame的安装

cmd:pip install pygame

2.AIGC工具

chatgpt4.0————项目逻辑辅助
文心一言————图像生成

3.图片材料

描述

项目实操

1.游戏开始时,需要输入用户名:

描述

2.游戏失败界面展示:

描述

3.“加料”功能展示:

描述

4.“洗牌”功能展示:

描述

5.积分排行展示:

描述

6.游戏说明书展示:

描述

7.完整游戏进行展示:

描述

二、项目设计

本项目是一个基于Pygame的游戏,名为“清凉一夏”🍉

前端设计与特色功能

强调用户友好的界面和互动体验🖇️

界面

  • 主菜单
  • 游戏区域
  • 积分榜
  • 游戏结束界面

特色功能

  • 多关卡设计:游戏分为三局,逐步增加难度。
  • 动态计时和得分:玩家在规定时间内匹配图案以获取分数。
  • 加料和洗牌按钮:提供了增加方块和重置方块顺序的选项,以提升游戏乐趣。
  • 中文支持:通过加载中文字体,增强本地化体验。

技术与算法

技术栈

使用Python和Pygame库进行游戏开发
图像处理通过Pygame的图像加载和变换功能实现

算法

1.界面设计:

  • 结算画面:draw_end_screen()
  • 按钮设计:加料/洗牌 功能按钮draw_blue_button(),主界面按钮draw_button()
  • 主界面:show_main_menu(),三个按钮点击handle_main_menu_click

2.游戏设计:

  • 得分:结算得分draw_final_scores(),排行榜显示draw_scores()
  • 游戏界面:draw_board()(包含得分、倒计时、方块点击、道具键)
  • 功能按钮:加料add_tiles(),洗牌shuffle_tiles()
  • 游戏机制:三局回合制generate_board(),消除规则check_match()
  • 创建用户:prompt_for_name()
  • 游戏结束:check_game_over()
  • 游戏失败机制:reset_game()

3.音乐添加:
(全部音乐源于免费音效网站:爱给网🔗

  • 初始化:pygame.mixer.init()
  • 主界面音乐导入:pygame.mixer.music.load(bgm)
  • 播放设置:pygame.mixer.music.play(-1)-1表示循环
  • 音效添加:pygame.mixer.Sound(bgm)
  • 音效播放:.play()
  • 停止:pygame.mixer.music.stop()

实现思路

界面绘制:通过Pygame的绘制功能,构建各种界面元素(按钮、方块等)。

游戏逻辑:
维护游戏状态(如当前局数、得分、方块状态)。
监听用户输入并响应(点击方块、按钮等)。

计时与得分:使用系统时间来控制游戏时间和计算剩余时间。

流程图

描述

三、项目测试

难度更改

一共经历了三次难度更改:

1.先是平铺6x6棋盘式难度,两两相消即可,觉得难度偏低,所以思考将图案位置随机分布,并允许重叠

2.设置一局给出24对图案对,两两相消,一般在20-30s即可完成,进一步更改:
需要三个相同的图案才能相消

3.为了丰富游玩体验,设计了由易到难三个关卡,采用图案种类和图案对数目递增的方式加强难度
具体详情在项目简介已说明
由于重叠度不好控制,有的时候是难以完成的。
这样的难度,加之两个功能的辅助,对于轻松向小游戏来说应该是刚刚好的

难度核心设计代码:

三层关卡难度递增
def generate_board(current_game):
    if current_game == 1:
        num_pairs = 6  # 第一局生成 6 对 (12 个方块,2 的倍数)
    elif current_game == 2:
        num_pairs = 12  # 第二局生成 12 对 (36 个方块,3 的倍数)
    else:  # 第三局
        num_pairs = 15  # 第三局生成 15 对 (45 个方块,3 的倍数)

    if num_pairs > len(patterns):
        patterns_expanded = patterns * (num_pairs // len(patterns) + 1)
    else:
        patterns_expanded = patterns

    # 根据当前局数决定倍数
    multiplier = 2 if current_game == 1 else 3
    pattern_list = random.sample(patterns_expanded, num_pairs) * multiplier
    random.shuffle(pattern_list)

    tiles = []
    for _ in range(num_pairs * multiplier):
        image = pattern_list.pop()
        x = random.randint(0, WIDTH - TILE_SIZE)
        y = random.randint(0, HEIGHT - TILE_SIZE)
        rect = pygame.Rect(x, y, TILE_SIZE, TILE_SIZE)
        layer = random.randint(0, 1000)
        tiles.append({'image': image, 'rect': rect, 'layer': layer})

    return tiles
匹配机制
def check_match():
    global score
    if current_game == 1 and len(selected) == 2:  # 第一局,检查两个方块
        t1, t2 = selected
        if t1['image'] == t2['image']:  # 检查两个方块是否相同
            if t1 in tiles and t2 in tiles:  # 确保两个方块都在 tiles 中
                tiles.remove(t1)
                tiles.remove(t2)
                score += 10  # 每消除一对得 10 分
                match_sound.play()  # 播放匹配成功的音效
    elif current_game > 1 and len(selected) == 3:  # 第二局和第三局,检查三个方块
        t1, t2, t3 = selected
        if t1['image'] == t2['image'] == t3['image']:  # 检查三个方块是否相同
            if t1 in tiles and t2 in tiles and t3 in tiles:  # 确保三个方块都在 tiles 中
                tiles.remove(t1)
                tiles.remove(t2)
                tiles.remove(t3)
                score += 15  # 每消除三块得 15 分
                match_sound.play()  # 播放匹配成功的音效
    else:
        # 如果不匹配,稍后恢复图案(可选)
        pygame.time.wait(500)  # 等待 500 毫秒
    selected.clear()

四、游戏功能

本游戏四大特色功能🪄
用于增加游戏趣味性与竞争性
打开一键查看相关代码!

用户创建

开设用户,用于比拼
def prompt_for_name():
    global player_name
    input_box = pygame.Rect(WIDTH // 2 - 100, HEIGHT // 2 - 50, 200, 40)
    color_inactive = pygame.Color('lightskyblue3')
    color_active = pygame.Color('dodgerblue2')
    color = color_inactive
    active = False
    text = ''
    font = pygame.font.Font(pygame.font.match_font('simhei'), 36)
    base_surface = pygame.Surface((WIDTH, HEIGHT))

    while True:
        base_surface.fill(BG_COLOR)
        txt_surface = font.render(text, True, color)
        width = max(200, txt_surface.get_width() + 10)
        input_box.w = width
        base_surface.blit(txt_surface, (input_box.x + 5, input_box.y + 5))
        pygame.draw.rect(base_surface, color, input_box, 2)
        screen.blit(base_surface, (0, 0))
        pygame.display.flip()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()
            if event.type == pygame.KEYDOWN:
                if active:
                    if event.key == pygame.K_RETURN:
                        return text
                    elif event.key == pygame.K_BACKSPACE:
                        text = text[:-1]
                    else:
                        text += event.unicode
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if input_box.collidepoint(event.pos):
                    active = not active
                    color = color_active if active else color_inactive
                else:
                    active = False
                    color = color_active if active else color_inactive

竞赛排行榜设计

增加了“查看积分排行”的按钮,点击即可查看不同用户间的积分排名
def draw_scores(scores):
    screen.fill(BG_COLOR)
    title_font = pygame.font.Font(pygame.font.match_font('simhei'), 48)
    title_surface = title_font.render("积分榜单", True, BLACK)
    title_rect = title_surface.get_rect(center=(WIDTH // 2, 50))
    screen.blit(title_surface, title_rect)

    scores_font = pygame.font.Font(pygame.font.match_font('simhei'), 36)
    y_offset = 100
    sorted_scores = sorted(scores.items(), key=lambda x: x[1], reverse=True)
    for idx, (player, score) in enumerate(sorted_scores):
        score_surface = scores_font.render(f"{idx + 1}. {player}: {score}", True, BLACK)
        score_rect = score_surface.get_rect(center=(WIDTH // 2, y_offset))
        screen.blit(score_surface, score_rect)
        y_offset += 50

    back_message = button_font.render("点击任意处返回主菜单", True, BLACK)
    back_rect = back_message.get_rect(center=(WIDTH // 2, HEIGHT - 60))
    screen.blit(back_message, back_rect)

“洗牌”功能

由于重叠度影响游戏用时,适度洗牌可以提速并转换思路
def shuffle_tiles():
    global tiles
    remaining_tiles = len(tiles)  # 当前剩余方块数量

    if remaining_tiles > 0:
        # 清空当前方块
        tiles.clear()

        # 计算要生成的新对数
        if current_game == 1:
            num_pairs = (remaining_tiles // 2)  # 第一局生成 2 的倍数
            new_pairs = num_pairs  # 直接使用剩余方块数的对数
        else:
            num_pairs = (remaining_tiles // 3)  # 第二局和第三局生成 3 的倍数
            new_pairs = num_pairs * 3  # 每对生成三个

        if new_pairs > 0:
            # 生成新的方块
            patterns_to_use = random.sample(patterns, num_pairs)  # 随机选择图案
            for image in patterns_to_use:
                for _ in range(2 if current_game == 1 else 3):  # 第一局两块,其他局三块
                    x = random.randint(0, WIDTH - TILE_SIZE)
                    y = random.randint(0, HEIGHT - TILE_SIZE)
                    rect = pygame.Rect(x, y, TILE_SIZE, TILE_SIZE)
                    layer = random.randint(0, 1000)
                    tiles.append({'image': image, 'rect': rect, 'layer': layer})

        random.shuffle(tiles)  # 打乱方块顺序

“加料”功能

在相同总分的前提下,竞争比拼即靠在充裕时间下的“加料”功能赢取积分获得上限
def add_tiles(current_game):
    global tiles
    num_pairs_to_add = 5  # 增加 5 对方块
    if current_game == 1:
        tiles += generate_additional_tiles(num_pairs_to_add, 2)  # 每对 2 块
    else:
        tiles += generate_additional_tiles(num_pairs_to_add, 3)  # 每对 3 块

五、AIGC表格

子任务 借助何种AIGC技术 实现了什么功能 效果如何
生成游戏图像 文心一言 生成游戏中使用的背景和图案素材 AI未能完全理解需求,素材不够满意
按钮设计 ChatGPT 开始游戏、积分查看 、说明书查看、两个道具 提高游戏功能性与使得游戏模块化
界面设计 ChatGPT 主界面设计、结算界面设计 使游戏有了精致包装,同时引导玩家游戏
功能按钮设计 ChatGPT 加料、洗牌 增加游戏竞争趣味性
游戏用户注册 ChatGPT 以用户为单位查看积分 可以进行玩家间的积分比拼
积分榜设计 ChatGPT 玩家可查看游戏积分 游戏竞争模式的具象化
添加游戏说明书 ChatGPT 使玩家进一步了解游戏 游戏介绍更清晰
倒计时 ChatGPT 查看游戏过程剩余时间 丰富玩家游戏情绪,增加紧张感
得分机制设计 ChatGPT 玩家游玩过程实时更新得分,匹配游戏失败机制 增添游戏趣味性与比拼意义
游戏机制设计 ChatGPT 消除机制、出牌模式 设计了三段难度递增的关卡,丰富可玩性
游戏失败特殊设计 ChatGPT 重玩该局并扣除相应积分 奖惩平衡,增加竞争性
游戏bgm插入设计 ChatGPT 界面bgm、点击/消除音效 增加游戏趣味性

六、PSP表格

任务 预估耗时 实际耗时 评价
需求分析 2小时 1.5小时 在与AI交涉过程中,它给了我很多灵感,因此加快了该进程
界面设计 3小时 4小时 设计复杂度高,稍超出预期:例如在各种插件、按钮的添加上消耗了很多时间
功能开发 6小时 5.5小时 有chatgpt的帮助,该过程相对顺利,但帮助的同时,也启发提示我进行新的尝试
测试与修复 4小时 5小时 测试全面,修复及时

七、项目评价

整体性点评

使用工具:

1.cursor和copilot都因为账户与会员问题,没有使用到。查了资料是很方便的工具,有点可惜

2.文图生成方面我还是认为AI太难理解我的需求,也可能是我表达不够清晰,ui设计十分粗糙请见谅

3.chatgpt也很好地支持辅助我进行游戏设计和开发,开始与AI交流自己的想法,很意外它提供给我很多点子,一定程度使得这个项目拥有更多调式细节

项目设计:

1.本意是想设计夏日主题,所以呈现出来的作品富有水果、冰沙、海浪等元素;且操作过程的设计意图为:消除(采摘)水果以制作冰沙,换取贝壳(每个关卡结算界面体现)

2.添加用户信息(用户名)键入,增加了玩家体验感

3.两个特色功能————洗牌和加料很好地增色了积分比拼过程,使得休闲的小游戏多了一丝紧张刺激的竞争意味

4.增加了轻松愉快的bgm,以及点击音效和匹配成功音效,增加游戏趣味性

可改进的地方

1.没有制作好pause键:原本希望制作空格键入的暂停键,但是加上之后会改变所有点击效果,调试多次都失败了

2.上面也提到了图案的重叠率,方块重叠率过高会使玩家点击锁定不理想,如果进一步试着更改代码,可以避免图像高度重叠鼠标难以键入,增加游玩体验感

posted @ 2024-09-18 21:15  okiqiiii  阅读(19)  评论(0编辑  收藏  举报