跳转至

程序设计实践答辩

作者:梁俊斌

目录

1. 项目简介

2. 项目功能

3. 设计思路

4. 模块介绍


项目简介

项目名称: 扫雷小游戏

项目作者: 梁俊斌

实现方式: C++QT

管理形式: qmakeqrc QT产生的文件来管理

该项目是一个经典的扫雷游戏实现,旨在通过编写一个完整的GUI应用程序来展示C++和QT的综合应用。游戏支持多种难度选择,玩家可以自定义地图大小和雷数。游戏界面友好,操作简单,适合各类用户体验。


项目功能

  • 多种难度选择:初级、中级、高级和自定义模式。
  • 游戏计时:记录玩家的游戏时间。
  • 标记功能:玩家可以标记雷的位置。
  • 胜利提示:玩家成功扫雷后会有胜利提示界面。

运行效果如下: 功能介绍运行gif right:40% w:15cm h:7cm


项目结构如下:


MineSweeper
├── .vscode/                    # 开发环境配置文件
│   ├── c_cpp_properties.json
│   └── settings.json
├── build/                      # 编译生成文件夹
├── include/                    # 头文件
│   ├── commons/                # 公共资源和常量
│   ├── cores/                  # 游戏逻辑核心组件
│   └── views/                  # 界面视图
├── res/                        # 资源文件夹
│   ├── images/                 # 图片资源
│   └── sounds/                 # 音频资源
├── src/                        # 源代码
│   ├── commons/                # 公共资源实现
│   ├── cores/                  # 游戏逻辑实现
│   └── views/                  # 界面实现
└── ui/                         # UI 设计文件
    └── dialogs/

采用典型的项目化目录结构有助于提高代码的可维护性、可读性和可扩展性。


核心模块介绍

这个部分介绍了MineBlock类,它用于处理地雷区块的各种状态和操作。MineBlock类包含多个成员变量和方法,用于管理区块的类型、数字、标记状态、覆盖状态等。通过这些方法,游戏可以精确地控制每个区块的行为和显示。



enum class BlockType
{
    EMPTY,
    NUMBER,
    MINE,
};
class MineBlock
{
    private:
        BlockType type;
        int number;
        bool covered;
        bool marked;
        bool mistaken;
        bool touched;
    public:
        void init();
        void setAsMine();
        void addNumber();
        void setMarked(bool marked);
        void setUncovered();
        void setMistaken();
        void setTorched();
        BlockType getType();
        int getNumber();
        bool isCovered();
        bool isMarked();
        bool isMistaken();
        bool isTouched();
};


以上就是block.h的完整的代码,下面我们就拿部分函数的实现出来简单介绍


void MineBlock::init()
{
    this->type = BlockType::EMPTY;  // 设置区块类型为空
    this->number = 0;               // 初始化区块数字为0
    this->covered = true;           // 设置区块为未揭开状态
    this->mistaken = false;         // 初始化错误标记状态为false
    this->marked = false;           // 初始化标记状态为false
    this->touched = false;          // 初始化点击状态为false
}
// 将区块设置为地雷
void MineBlock::setAsMine()
{
    this->type = BlockType::MINE;  // 设置区块类型为地雷
}
从具体函数代码实现可以看到就是MineBlock类是由一个初始化函数和很多的用于变量接口的函数(get函数)组成


在这一部分,我们将详细介绍GameController类的实现。GameController类是整个扫雷游戏的核心控制器,负责管理游戏状态、处理用户输入以及更新游戏界面。

GameController类的主要功能

  • 游戏初始化:设置游戏的初始状态,包括地雷的分布和数字的计算。
  • 游戏状态管理:控制游戏的开始、暂停、失败和成功状态。
  • 用户输入处理:处理用户的左键和右键点击操作。
  • 游戏逻辑更新:根据用户的操作更新游戏界面和状态。

主要函数介绍

Image 1 Image 2

从上述代码可以看出,GameController类通过不同的函数来设置游戏的难度,并调用restart函数来重新初始化游戏。


用户输入处理

bool GameController::leftButtonClick(int x, int y)
{
    // 处理左键点击事件
    if (status != GameStatus::PLAYING) return false;
    MineBlock& block = getBlock(x, y);
    if (block.isCovered() && !block.isMarked())
    {
        block.setUncovered();
        if (block.getType() == BlockType::MINE)
        {
            status = GameStatus::FAILURE;
            return false;
        }
        else if (block.getType() == BlockType::EMPTY)
        {
            uncoverEmptyBlocks();
        }
    }
    return true;
}

bool GameController::rightButtonClick(int x, int y)
{
    // 处理右键点击事件
    if (status != GameStatus::PLAYING) return false;
    MineBlock& block = getBlock(x, y);
    if (block.isCovered())
    {
        block.setMarked(!block.isMarked());
        remainFlagCount += block.isMarked() ? -1 : 1;
    }
    return true;
}

上述代码展示了GameController类如何处理用户的左键和右键点击事件,并根据点击的结果更新游戏状态。 通过GameController类,这些函数和逻辑共同构成了一个完整的游戏控制器,使得游戏能够顺利运行并响应用户的操作。


资源管理模块介绍

资源管理模块主要负责加载和管理游戏中的图片和音频资源,以及提供给其他模块使用。通过资源管理模块,游戏可以方便地访问和使用各种资源,使得游戏正确渲染,提高游戏的可维护性和可扩展性。

下面我们来看一下GameResource类的部分实现

Image 3 Image 4

代码分析

从代码图片中可以看出,GameResource类通过QPixmapQSound类来加载和管理游戏中的图片和音频资源。它还通过指针成员变量和get函数,GameResource类提供了一种简单的方式来访问和使用这些资源。

p5 w:20cm h:10cm


项目的另外资源管理文件

通过.pro文件以及qrc文件来管理项目中的资源文件,这样可以方便的访问和使用这些资源。同时,将图片以及音频资源放在res文件夹中,方便项目整体调用

Image 6 Image 7

界面设计模块介绍

界面设计模块主要负责实现游戏的用户界面,包括游戏主界面、游戏设置界面、游戏胜利界面和游戏失败界面等。通过界面设计模块,游戏可以展示给用户友好的界面,提高用户体验。

下面我们来看一下SceneWidget类的部分实现

SceneWidget类通过QPainter类来绘制游戏界面,包括地雷区块、数字区块、标记区块等各种情况。编写不同情况的函数,然后通过重写paintEvent函数从而调用各情况的函数,SceneWidget类实现了游戏界面的绘制。


代码部分截图

Image 7

通过ui文件设计界面

通过QTui文件来设计界面,这样可以方便的实现界面的布局和设计。通过ui文件,可以直观地看到界面的布局和组件,方便调整和修改。同时,通过ui文件和QT的信号槽机制,可以方便地实现界面和逻辑的交互。

通过ui文件设计主界面,胜利结算,计时界面,可以直观地看到界面的布局和组件,方便调整和修改。同时,通过ui文件和QT的信号槽机制,可以方便地实现界面和逻辑的交互。

主要ui界面有: - mainwindow.ui - aboutdialog.ui - customdialog.ui - successdialog.ui


总结

这个项目使用C++QT来实现一个完整的GUI扫雷游戏。在项目中,通过设计和实现游戏的核心逻辑、资源管理、界面设计等模块,以及如何将这些模块整合在一起,实现一个完整的游戏。


感谢聆听

作者:梁俊斌