【qt小游戏】小老鼠闯迷宫小游戏(附源码)

在这里插入图片描述

摘要:本文主要使用QT5,实现了一个走迷宫的小游戏,本文采用:非递归深度优先搜索算法(DFS)解决迷宫寻路问题,深度优先搜索是一种用于遍历或搜索图形结构的算法,优先访问尽可能深入的节点。非递归实现通过显式使用栈来模拟递归调用栈,避免了递归的函数调用开销。
除此外,本小游戏还可以自定义游戏地图。
文中源码文件【获取方式】:关注公众号:利哥AI实例探险,
给公众号发送 “小老鼠闯迷宫”
获取下载方式,关注发送关键字即可获取下载方式,无套路。由于本人能力有限,难免有疏漏之处。

【qt小游戏】小老鼠闯迷宫小游戏(附源码)

1. 小游戏演示

小老鼠闯迷宫

2. 逻辑实现

2.1 主界面

在这里插入图片描述

  1. 使用QT Design拖拽窗口及按钮,并通过CSS设置界面效果。
  2. 封装按钮类,增加动画效果,通过按钮按下及抬起事件设置音效及动画等。
  3. Design中涉及到的按钮,需要右键提升为 封装的按钮类
//初始化选关窗口
chooseWindow = new ChooseLevelWindow;
//初始化编辑迷宫地图窗口
editWindow = new MapEditWindow;

//监听编辑地图窗口的返回按钮点击事件
connect(editWindow, &MapEditWindow::backBtnClicked, [=](){
   editWindow->hide();
   setGeometry(editWindow->geometry());
   this->show();
});

//监听选关窗口的返回按钮点击事件
connect(chooseWindow, &ChooseLevelWindow::backBtnClicked, [=](){
   chooseWindow->hide();
   setGeometry(chooseWindow->geometry());
   this->show();
});

void MainWindow::on_btnStart_clicked()
{
    // 按钮弹跳效果
    ui->btnStart->jumpDown();
    ui->btnStart->jumpUp();
    // 0.3秒后打开选择关卡页面
    QTimer::singleShot(300, this, [=](){
        this->hide();
        chooseWindow->setGeometry(this->geometry());
        chooseWindow->show();
    });
}

2.2 选关界面

在这里插入图片描述

  1. 生成16关的关卡,并绑定各个关卡的地图,链接每个关卡按钮的信号和槽函数,点击关卡时匹配对应的地图。
  2. 提升按钮为自定义按钮类,加载动画效果。
    选关界面的实际效果如下:
    在这里插入图片描述
for (int i = 0; i < 16; i++) {
        QPushButton *tmpBtn = new QPushButton(this);
        tmpBtn->setText(QString::number(i+1));
        tmpBtn->setFixedSize(60, 60);
        tmpBtn->setObjectName("img_button");
        tmpBtn->setStyleSheet("#img_button{border-image:url(:/res/chooseBtn_1.png); color:rgb(20,20,20); font-size:20px;}"
                              "#img_button:pressed{border-image: url(:/res/chooseBtn_2.png);}");
        tmpBtn->move(145+(i%4)*150, 90+(i/4)*100);
        tmpBtn->show();

        //绑定按钮点击事件
        connect(tmpBtn, &ImgButton::clicked, [=](){
            QTimer::singleShot(100, [=](){
                this->hide();
                playWindow = new PlayWindow(QString(":/mazedata/").append(QString::number(i+1)).append(".mazedata"));
                playWindow->setGeometry(this->geometry());
                playWindow->show();

                //监听游戏窗口的返回按钮点击事件
                connect(playWindow, &PlayWindow::backBtnClicked, [=](){
                   playWindow->hide();
                   setGeometry(playWindow->geometry());
                   delete playWindow;
                   playWindow = NULL;
                   this->show();
                });
            });
        });
    }

2.3. 闯关界面

在这里插入图片描述

  1. 拦截WASD为上下左右,并做出相应处理。
  2. 使用非递归深度优先搜索实现寻路逻辑。
  3. 提供游戏成功、失败的界面及音效等。
    在这里插入图片描述
// 非递归深度优先搜索实现寻路
bool PlayWindow::findPossibleWay(bool drawPath)
{
    //探索路径策略
    int MOVE_STRATEGY[4][2] = {
        {1, 0},  // down
        {0, 1},  // right
        {-1, 0}, // up
        {0, -1}  // left
    };

    //是否走过的标记
    bool gone_mark[31][31];
    for (int i = 0; i < 31; i++)
    {
        for (int j = 0; j < 31; j++)
        {
            gone_mark[i][j] = false;
        }
    }

    QStack<QPair<int, int>> possible_path; // 储存路线的栈
    QStack<QPair<int, int>> pos_stack; // 储存待遍历位置的栈,位置的最后一个总是最先遍历
    pos_stack.push(QPair<int, int>(startX, startY)); // 加入起点

    while(!pos_stack.empty())
    {
            int pos_x = pos_stack.top().first;
            int pos_y = pos_stack.top().second;
            possible_path.push(pos_stack.top());

            // 终点出口
            if(pos_x == endX && pos_y == endY)
            {
                if(drawPath)
                {
                    for(QPair<int, int> p: possible_path)
                    {
                        int tx = p.first, ty = p.second;
                        if(tx!=posX || ty!=posY)
                            tiles[tx][ty]->changeStatus(Tile::ENDING);
                    }
                }
                return true;
                //return possible_path
            }

            //如果不是出口则标记走过
            gone_mark[pos_x][pos_y] = true;

            int wall_count=0 , gone_count=0;

            // 探索顺序与MOVE_STRATEGY相反,因为最后入栈的最先遍历
            for(int i=0; i<4; i++)
            {
                int next_pos_x = pos_x + MOVE_STRATEGY[i][0];
                int next_pos_y = pos_y + MOVE_STRATEGY[i][1];
                // 是否撞墙或已走过
                if(next_pos_x<0 || next_pos_x>=mazeData->mazeSize || next_pos_y<0 || next_pos_y>=mazeData->mazeSize || mazeData->mazeData[next_pos_x][next_pos_y] == Tile::WALL)
                {
                    wall_count++;
                    continue;
                }
                if(gone_mark[next_pos_x][next_pos_y])
                {
                    gone_count++;
                    continue;
                }
                pos_stack.push(QPair<int, int>(next_pos_x, next_pos_y));
            }
            if(wall_count + gone_count == 4)
            {
                pos_stack.pop();
                possible_path.pop();
                if(gone_count != 1)
                    possible_path.pop();
            }
    }
    if(drawPath) {
        QMessageBox::information(this,"提示","该迷宫没有通路");
    }
    return false;
}

在这里插入图片描述

  1. 提供初始界面,提供随机生成地图逻辑
  2. 提供保存地图功能,自定义或随机生成的地图可以在首界面进行加载。

往期文章回顾

【深度学习】物体检测/实例分割/物体追踪/姿态估计/定向边框/图像分类检测演示系统【含源码】【深度学习】YOLOV8数据标注及模型训练方法整体流程介绍及演示
【深度学习】行人跌倒行为检测软件系统【深度学习】火灾检测软件系统
【深度学习】吸烟行为检测软件系统【深度学习】数竹签演示软件系统
【深度学习】菜品目标检测软件系统QT5集成FTP实现文件及文件夹的下载
QT集成开源日志库示例python源码加密之Cython方案简单示例
【python源码加密】Cython针对python工程多层级目录处理办法http服务网络请求如何确保数据安全(含python示例源码)
http请求数据传输时确保完整性和保密性方案(含源码)QT集成百度在线地图JS API实现交互及特定效果
【qt小游戏】小老鼠闯迷宫小游戏(附源码)
  • 13
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值