基于QT的迷宫与地牢小游戏开发
首先贴出链接:
- 完整Qt源码:点击进入https://download.csdn.net/download/qq_43365825/11852112
- 发布可执行程序:点击进入https://download.csdn.net/download/qq_43365825/11852139
- 视频介绍:点击进入https://www.bilibili.com/video/av70867935/
1. 系统结构及实现
- 游戏中有迷宫模式和地牢模式两种游戏模式,主要由5个类组成。主界面类包含其它4个类。迷宫类maze主要实现迷宫模式中,迷宫地图的随机生成,寻路算法存储的路径;地牢类Dungeon主要实现地牢地图的生成,初始化地图贴图资源字符串,地牢中角色信息的初始化,战斗伤害的计算;开始界面类interface主要实现开始界面的设置;商店类StoreWidget主要实现地牢模式中的商店功能。下面来详细介绍各个类的实现。
1.1 迷宫类maze
迷宫类中的自动寻路算法autoFindPath的实现
- 在生成迷宫时,将可以走的路标记为1,不能走的墙标记为0。自动寻路时,从当前位置开始每次都从4个方向,按照左、下、右、上的顺序来检测前方是路还是墙(标记是1还是0),一旦找到一个方向上的路是可以走的,则将此方向上的路的座标存储到路径栈PathStack中,并且标记已经走过的路,防止走回头路陷入死循环。如果探测后4个方向都找不到可以走的路,则将路径栈中栈顶元素出栈,回退到上一个路径点重新探测,跳过被标记为走过的路,如果4个方向依然找不到可以走的路,则重复上述步骤,将当前路径栈栈顶元素出栈,回退到上一个路径点重新探测,一直重复上述步骤,直到探测到可以走的路才将此方向上的路压入到路径栈中,并继续向前探测。生成的迷宫地图必有一条通路,所以总能找到一条通往出口的路径。
1.2 地牢类Dungeon
- 地牢类中初始化地牢地图initialMap的实现
void Dungeon::initialMap()
{
floor=1;
MAX_HP=100;
isPre=false;
isNext=false;
x=11;
y=8;
initialrole();
int num=1;
while(1)
{
if(num==1)
{
int tempmap[12][16]={
15,1,1,3,3,3,1,1,1,1,1,1,1,1,1,1,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
0,8,1,1,1,3,17,1,17,1,1,22,2,5,0,1,
0,1,1,11,1,1,0,1,0,1,1,23,2,20,0,1,
0,0,0,17,0,0,0,1,0,0,0,0,17,0,0,1,
0,20,1,1,1,1,0,1,0,1,3,2,4,1,0,1,
0,20,1,11,1,1,0,1,17,3,2,4,10,1,0,1,
0,0,0,17,0,0,0,1,0,0,0,0,0,0,0,1,
0,1,1,2,1,1,0,1,1,1,1,1,1,1,1,1,
0,8,2,2,2,5,0,0,17,0,0,0,17,0,0,0,
0,8,2,2,2,5,0,20,2,2,0,1,1,4,1,0,
0,2,2,2,2,2,0,2,1,2,0,1,3,10,3,0
};
for(int i=0;i<12;i++)
{
for(int j=0;j<16;j++)
{
map[num-1][i][j]=tempmap[i][j];
}
}
}
if(num==2)
{
int tempmap[12][16]={
14,1,18,1,1,1,1,1,1,1,1,1,1,1,1,0,
1,1,0,0,0,0,19,4,20,4,21,0,0,0,0,0,
1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
1,0,20,20,5,5,0,1,1,1,0,12,5,2,2,0,
1,0,19,20,5,5,16,1,1,1,16,12,5,2,19,0,
1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,
1,16,5,5,12,5,0,1,1,1,0,12,8,19,2,0,
1,0,5,5,12,19,0,1,1,1,0,12,9,20,22,0,
1,0,0,0,0,0,0,1,1,1,16,12,10,21,23,0,
1,0,19,2,2,2,0,1,1,1,0,0,0,0,0,0,
1,0,5,5,10,10,0,1,1,1,0,2,2,2,2,0,
15,0,5,5,10,12,16,1,1,1,16,2,2,2,2,0
};
for(int i=0;i<12;i++)
{
for(int j=0;j<16;j++)
{
map[num-1][i][j]=tempmap[i][j];
}
}
}
if(num==3)
{
int tempmap[12][16]={
20,1,1,22,0,20,1,1,20,0,1,0,1,1,2,1,
1,1,2,1,0,1,20,20,1,0,1,0,1,2,8,2,
1,2,8,2,0,1,1,21,1,0,1,17,4,4,2,1,
4,1,4,1,0,20,1,1,20,0,1,0,0,0,0,0,
0,0,17,0,0,0,1,1,0,0,1,0,1,1,1,1,
1,1,1,1,1,3,1,1,1,1,3,1,1,1,1,1,
0,0,17,0,0,1,1,1,1,0,1,0,0,0,0,0,
1,1,11,1,0,0,1,1,0,0,1,0,2,2,2,20,
1,4,3,20,0,1,1,1,1,0,1,17,4,4,3,8,
1,1,3,23,0,1,1,1,1,0,1,0,0,0,0,0,
0,0,0,0,0,0,1,1,0,0,3,0,1,1,1,1,
14,1,1,1,1,1,1,1,1,0,1,17,1,1,1,15,
};
for(int i=0;i<12;i++)
{
for(int j=0;j<16;j++)
{
map[num-1][i][j]=tempmap[i][j];
}
}
}
if(num==4)
{
int tempmap[12][16]={
1,21,1,1,0,1,31,32,33,1,0,1,1,1,1,1,
8,2,20,1,0,1,34,35,36,1,0,1,1,1,1,1,
1,3,1,1,0,1,1,1,1,1,0,1,20,1,10,1,
1,1,1,1,0,1,1,1,1,1,0,1,1,11,1,1,
0,0,17,0,0,0,0,18,0,0,0,0,17,0,0,0,
1,1,4,1,17,1,1,3,1,1,1,11,1,1,1,1,
1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
3,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,
17,0,0,0,17,0,0,0,0,17,0,0,0,0,0,17,
1,0,1,20,4,1,0,1,1,4,1,1,1,1,0,1,
1,0,1,3,1,3,0,1,23,2,8,1,1,1,0,1,
15,0,20,1,20,1,0,1,1,3,1,1,1,1,0,14,
};
for(int i=0;i<12;i++)
{
for(int j=0;j<16;j++)
{
map[num-1][i][j]=tempmap[i][j];
}
}
}
if(num==5)
{
int tempmap[12][16]={
15,0,1,1,3,17,1,0,1,4,1,17,1,1,17,1,
1,0,1,1,1,0,20,0,4,2,4,0,1,1,0,1,
1,17,4,1,1,0,1,0,2,4,2,0,3,3,0,3,
0,0,0,0,17,0,3,0,2,2,2,0,20,20,0,1,
20,1,4,1,1,0,1,0,22,23,19,0,20,20,0,1,
20,1,1,1,4,0,4,0,0,0,0,0,0,0,0,1,
0,0,12,0,0,0,1,1,3,1,1,1,1,1,1,1,
1,1,12,1,1,0,3,0,0,0,0,0,0,0,0,3,
1,1,4,1,1,0,1,0,1,1,1,1,1,1,1,1,
22,23,20,8,10,0,1,0,1,1,1,0,0,0,0,0,
0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,1,
14,1,1,1,1,1,1,0,1,1,1,16,1,1,1,24,
};
for(int i=0;i<12;i++)
{
for(int j=0;j<16;j++)
{
map[num-1][i][j]=tempmap[i][j];
}
}
}
if(num==6)
{
int tempmap[12][16]={
14,0,20,20,2,0,1,1,1,1,1,1,1,1,1,1,
1,0,20,20,2,0,1,0,0,0,0,0,0,0,0,17,
1,0,0,0,4,0,1,0,25,8,2,1,2,25,1,25,
1,17,17,1,1,17,1,0,5,1,2,25,1,2,1,1,
1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
1,1,1,11,4,1,20,1,1,1,25,25,1,1,1,1,
0,0,0,0,0,0,1,0,0,0,0,0,0,17,0,1,
2,1,1,4,8,0,1,0,10,2,0,0,1,4,0,1,
2,1,11,23,12,0,1,0,9,2,0,0,5,1,0,1,
4,2,1,4,1,0,1,0,8,2,26,2,4,2,0,1,
17,0,0,0,0,0,1,0,0,0,0,1,2,1,0,1,
1,1,3,1,12,1,1,0,1,1,1,19,1,1,0,15,
};
for(int i=0;i<12;i++)
{
for(int j=0;j<16;j++)
{
map[num-1][i][j]=tempmap[i][j];
}
}
}
if(num==7)
{
int tempmap[12][16]={
15,0,27,29,0,22,0,1,1,1,0,10,0,20,0,3,
1,0,8,27,0,23,0,1,1,1,0,4,0,20,0,3,
1,0,8,27,0,4,0,3,0,26,0,3,0,8,0,3,
1,0,2,8,0,2,0,1,0,1,0,1,0,2,0,1,
1,0,2,10,0,1,0,1,0,1,0,1,0,1,0,1,
17,0,25,25,0,17,0,18,0,17,0,17,0,25,0,17,
1,25,1,1,12,1,1,1,1,1,1,1,1,1,1,1,
17,0,25,25,0,17,0,17,0,17,0,17,0,25,0,17,
1,0,2,2,0,1,0,1,0,1,0,1,0,1,0,1,
3,0,8,10,0,2,0,12,0,4,0,3,0,10,0,1,
3,0,8,27,0,2,0,22,0,20,0,4,0,20,0,1,
3,0,8,28,0,2,0,23,0,20,0,10,0,20,0,14,
};
for(int i=0;i<12;i++)
{
for(int j=0;j<16;j++)
{
map[num-1][i][j]=tempmap[i][j];
}
}
}
num++;
if(num>Total_Floor)
{
break;
}
}
}
-
地牢中每层的地图都不相同,而且每层地图中还有许多游戏角色(物品、怪物、金币等)。而且每层地牢之间是连通的,可以去往下一层地牢,也可以回到上一层地牢,而玩家在地牢中对每层地牢造成的影响都必须保存着,为了实现地牢的这些效果,将地牢抽象为一个3维数组。数组的第3维代表地牢的层数,第1维和第2维表示每层的地牢地图。每层地牢就可以通过第3个维度进行联系,而且每层的地图可以设置为不相同,并且玩家对地牢造成的影响都可以储存在这个3维数组当中。
-
在实现地牢中每层地图的过程当中,为了方便加载地图资源,将二维数组中的元素与地图贴图资源的名称相对应,比如0代表墙,1代表路,2代表金币,3代表小星星,15代表下一层入口,20代表黄钥匙等等。
-
地牢中的英雄与怪物都有自身的属性,如生命值、攻击力、防御力等等,将他们都抽象为一个结构体,结构体中存储英雄与怪物的自身属性,修改起来也较为方便。
1.3 商店类StoreWidget
- 商店类
#ifndef STOREWIDGET_H
#define STOREWIDGET_H
#include <QWidget>
#include <QLabel>
#include <QGraphicsView>
#include <QTimer>
#include <QKeyEvent>
#include <QShowEvent>
class StoreWidget : public QWidget
{
Q_OBJECT
public:
explicit StoreWidget(QWidget *parent = 0);
int chooseOption; //选择了第几项
int BuyTimes;
QTimer *haveBuyTimer;//购买计时器
bool setChooseEnable;//是否可以购买
bool StoreWinisShow;//商店窗口是否显示
int Currstore_price;//当前价格
int Nextstore_price;//下一次价格
private:
int OptionNum; //有多少个选项
int border_color_it;
QString OptionBoxColor[6]= {"FFFFFF", "CCCCCC", "999999", "666666", "999999", "CCCCCC"};
QTimer *OptionBoxTimer;
QGraphicsView *OptionBox;
QWidget *StoreWin;
QLabel *text1;
QLabel *text2;
QLabel *hpOption;
QLabel *mpOption;
QLabel *atkOption;
QLabel *defOption;
QLabel *exitOption;
private:
void initialStoreWin();//初始化商店界面
void keyPressEvent(QKeyEvent *event);//当前类中的键盘事件与mainwindow中的键盘事件互不影响
void showEvent(QShowEvent *);//重写窗口显示事件,为了使当前窗口获得焦点
public slots:
void OptionBoxborderChanged();
};
#endif // STOREWIDGET_H
- 商店类中商店购买功能的实现
void StoreWidget::keyPressEvent(QKeyEvent *event)
{
if(event->key() == Qt::Key_W)
{ //向上
if (chooseOption > 0)
{
chooseOption -= 1;
OptionBox->setGeometry(32, 112 + 48 * chooseOption, 192, 32);
}
else
chooseOption = 0;
}
else if (event->key() == Qt::Key_S)
{ //向下
if (chooseOption <= OptionNum - 2)
{
chooseOption += 1;
OptionBox->setGeometry(32, 112 + 48 * chooseOption, 192, 32);
}
else
chooseOption = OptionNum - 1;
}
else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter || event->key() == Qt::Key_Space)
{
if (chooseOption != OptionNum - 1)//不是选择的离开商店选项
{
Currstore_price=((BuyTimes) * (BuyTimes) - (BuyTimes) + 2) * 10;
Nextstore_price = ((BuyTimes +1 ) * (BuyTimes +1 ) - (BuyTimes +1 ) + 2) * 10;
haveBuyTimer->start(100);//开启购买(计时器开启后不是马上执行,而是在当前函数执行完毕后才开始执行,
//所以,如果在执行计时器后才改变setChooseEnable的值,那么在
//当前函数体内,setChooseEnable的值就还不会改变
if(!setChooseEnable)//金币不够,则不能购买
{
return;
}
text1->setText(QString::fromStdWString(L"你若给我 ") +
QString::number(Nextstore_price) + QString::fromStdWString(L" 个金币"));
text2->setText(QString::fromStdWString(L"我就可以帮你"));
hpOption->setText(QString::fromStdWString(L"提升 ") +
QString::number(100 * (BuyTimes +1 )) + QString::fromStdWString(L" 点生命"));
mpOption->setText(QString::fromStdWString(L"提升 ") +
QString::number(20 * (BuyTimes +1 )) + QString::fromStdWString(L" 点魔法"));
BuyTimes++;
return;
}
else
{
this->hide();
StoreWinisShow=false;
chooseOption=0;//选项框回到起始位置
OptionBox->setGeometry(32,112,192,32);
return;
}
}
}
- 商店是通过键盘操作上移下移选项框来进行选择,再通过Enter或者Space键进行购买。在实现时重写QT键盘事件keyPressEvent来实现商店的购买功能。当检测到输入按键为W,选项框就会上移,但若选项框已停留在第一个选项上则不会上移,检测到输入按键为S时,选项框就会下移,但若选项框已停留在最后一个选项上则不会下移。当检测到输入按键为Enter或者Space时,会做出判断,如果选择的选项不是离开商店,则继续进行判断,否则关闭商店窗口。当选择的不是离开商店时,会先判断当前剩余金币是否大于等于当前购买的花费,如过小于,则不能购买,对按键操作不反应,并提示玩家,金币不足。若满足购买的花费,则执行购买操作,每次购买完成后,都会更新商店选项与购买花费,为了平衡游戏难度,“提升攻击力”与“提升防御力”选项不会更新。
1.4 开始界面类interface
- 开始界面提供游戏模式选择接口,玩家通过点击不同模式的选项框进入到不同的游戏模式。开始界面的背景窗口是重写绘图事件paintEvent来实现的,每当开始界面窗口更新时,都会触发绘图事件,绘制窗口背景图片。当玩家点击进入不同的游戏模式时,也会触发绘图事件,绘制不同游戏模式的窗口背景图片。
- 当玩家选择迷宫模式或者地牢模式按钮后,会出现加载进度条。加载进度条是由QT中的QprogressBar进度条类来实现的。通过Qtimer计时器类对象发出的timeout信号,来触发槽函数loading实现进度条值的变化,当进度条跑满时,使用窗口的update函数强制刷新窗口来执行绘图事件,这样就将玩家的点击与进度条的变化,窗口背景的绘制都联系起来了。
1.5 主界面类mainwindow
主界面的实现
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QGridLayout>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QMainWindow>
#include <QWidget>
#include <QSpinBox>
#include <QPushButton>
#include <QLabel>
#include <QComboBox>
#include <QLineEdit>
#include <QKeyEvent>
#include <QResizeEvent>//QResizeEvent 是主窗口的变化事件
#include <QSequentialAnimationGroup>
#include <QPropertyAnimation>
#include <QTimer>//计时器 QTime 只是用来产生随机数的
#include <QMediaPlayer>//视频、音乐类
#include <QMediaPlaylist>
#include <QPoint>
#include <QProgressBar>
#include "maze.h"
#include "Dungeon.h"
#include "interface.h"
#include "storewidget.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
/********************** 主界面 ***********************/
private:
int BASIC_WIDTH;//地图窗口宽度
int BASIC_HEIGHT;//地图窗口高度
QPoint windowPos;//窗口位置
QPoint mousePos;//鼠标位置
QPoint dPos;//鼠标移动后的位置
private:
interface *surface;//开始界面
QWidget *MainWidget;//中心窗口
QWidget *MazeWidget[60][60];//地图窗口数组
QWidget *People;//角色
QString character[12];//角色图片字符串
QGridLayout *gLayout_Map;//地图网格布局管理器
QHBoxLayout *hLayout;//主界面水平布局管理器
private:
void initialWindow_Layout();//初始化主窗口
void keyPressEvent(QKeyEvent *event);//键盘事件(用于操作)
void mousePressEvent(QMouseEvent *event);//鼠标按下事件(用于移动主界面)
void mouseMoveEvent(QMouseEvent *event);//鼠标移动事件
private slots:
void ShowWidget();//显示界面
/********************** 迷宫模式 ***********************/
private:
int iNum;//自动寻路显示路径辅助变量
int lastheight;//上一次设置的迷宫高度
int lastwidth;//上一次设置的迷宫宫宽度
int StytleNum;//地图风格数字
bool isPlay;//键盘操作标识(用于限制操作时自动寻路和AI)
bool isShow;//显示地图标识(用于刷新迷宫地图时销毁上次生成的窗口)
bool issurface;//开始界面标识(用于标识开始界面已加载完成)
bool isAIAnimationButton;//AI移动标识
bool isAutoMoveButton;//自动寻路标识
private:
maze m;//迷宫类
QWidget *Controlwidget;//控制界面
QGridLayout *gLayout_Control;//控制界面网格布局
QSpinBox *sp_w;//迷宫大小输入
QSpinBox *sp_h;
QLabel *label_Stytle;//地图风格显示
QComboBox *SelectMapStytle;//地图风格选择
QPushButton *AIAnimationButton;//AI操作
QPushButton *AutoMoveButton;//自动寻路
QPushButton *quitButton;//返回主菜单按钮
QSequentialAnimationGroup *group;//AI操作动画组
QTimer *timer;//定时器
private:
void initialControlWidget();//初始化控制界面
void ShowMaze_Layout();//显示迷宫地图
void hideMaze();//隐藏迷宫地图
void resetMaze();//重置迷宫
private slots:
void moveCharacter();//AI移动时人物图片切换
void CreateMaze_Layout();//创建迷宫
void ShowPath();//自动寻路显示路径
void ShowAnimation();//显示动画
void timeStart();//定时器开启
void MapStytleSet();//设置地图风格
void quit();//返回主菜单
/********************** 地牢模式 ***********************/
private:
Dungeon d;//地牢类
QWidget *infoWidget;//状态显示界面
int moveDirection;//移动方向
int moveNum;
QLabel *Floor;//地牢层数
QLabel *level;//人物状态信息
QLabel *exp;
QLabel *hp;
QLabel *mp;
QLabel *atk;
QLabel *def;
QLabel *score;//金币
QLabel *yellowkeyNum;//钥匙信息
QLabel *purplekeyNum;
QLabel *redkeyNum;
QLabel *CharacterName;
private:
void initialinfoWidget();//初始化状态界面
void initialGetitemWin();//初始化获得物品信息界面
void initialFightWin();//初始化战斗界面
void initialSetNameWin();//初始化设置角色名界面
void ShowDungeon();//显示地牢
void hideDungeon();//隐藏地牢
void updateStatusData();//更新状态数据
void Move();//人物移动
void changeHP(int num);
void QuestionBox(int num);//问号箱
void items(int _itemNum, int _moveDirection);//物品
void doors(int _doorNum, int _moveDirection);
void Monsters(int _MonsterNum,int _moveDirection);
void checkPrefloor();//上一层
void checkNextfloor();//下一层
bool isDynamic(int i,int j);
void soundPlay(int CurrentIndex);
private slots:
void GetitemWinshow();//获得物品信息界面显示
void FightWinshow();//战斗界面显示
void ShowdynamicEffect();//展示动态效果
void OpenStore();//打开商店
void ReturnMainMenuPlay();//返回主菜单
void RestartPlay();//重新开始
void soundStop();//音效停止
void CheckBGMstate();//检查音乐状态
void EnterDungeon();//角色名设置完成,进入地牢
private://获得物品信息栏
QLabel *GetitemsShow;
QTimer *GetitemTimer;
int GetitemNum;
int itemNum;
private://设置角色名界面
QLineEdit *NameEdit;
QPushButton *SetDone;
private://战斗界面
QWidget *FightWidget;
QTimer *FightTimer;
bool isFighting;
QLabel *Monster_pic;//怪物信息标签
QLabel *Monster_name;
QLabel *Monster_hpText;
QLabel *Monster_hp;
QLabel *Monster_atkText;
QLabel *Monster_atk;
QLabel *Monster_defText;
QLabel *Monster_def;
QLabel *Character_pic;//人物信息标签
QLabel *Character_name;
QLabel *Character_hpText;
QLabel *Character_hp;
QLabel *Character_atkText;
QLabel *Character_atk;
QLabel *Character_defText;
QLabel *Character_def;
int MonsterNum;//怪物编号
int fight_period_it;//战斗次数
int fight_end_it;//战斗结束标识
private://商店界面
StoreWidget *Store;
private://按钮
QPushButton *ReturnMainMenu;
QPushButton *Restart;
private://动态效果
QTimer *dynamicEffectTimer;//动态效果计时器
int display_it;
private://音效
QMediaPlayer *BGM;
QTimer *BGMTimer;
QMediaPlaylist *soundlist;
QMediaPlayer *sound;
QTimer *soundTimer;
};
#endif // MAINWINDOW_H
-
主界面中的窗口结构与使用的布局管理器结构图以在上图给出。当主窗口构造分配内存时,这些窗口也会被分配内存。在实际的游戏执行过程中,会将除主窗口外的所有其它窗口先隐藏起来,即调用窗口的hide函数,当游戏打开时,最先显示的是开始界面窗口,玩家点击不同的接口按钮后,根据玩家选择的模式按钮,显示对应模式下的窗口,同时隐藏开始界面窗口。
-
玩家选择迷宫模式后,在进度条跑满后,会触发绘图事件,开始界面的背景图片重新绘制为迷宫模式的窗口图片,当玩家输入好迷宫大小点击生成迷宫按钮后,开始界面窗口会隐藏起来,同时地图窗口与迷宫控制界面窗口和主人物窗口会显示,这样就是实现了玩家控制窗口切换的效果。
-
同样的,玩家选择地牢模式后,在进度条跑满后,会触发绘图事件,开始界面的背景图片重新绘制为地牢模式的窗口图片,当玩家输入角色名后,开始界面的窗口会隐藏,同时地图窗口与地牢人物状态显示窗口和主人物窗口会显示出来。当玩家在地牢中碰到怪物后,地牢战斗窗口也会显示出来,战斗完成后隐藏起来。当玩家进入商店,商店界面窗口也会显示出来,玩家购买完成,点击离开商店选项后,商店界面就会隐藏起来,这样就实现了玩家与游戏之间的交互。
-
每种游戏模式下都有返回主界面按钮,因为在游戏设计时隐藏了主界面窗口的边框,只有通过开始界面的“离开游戏”选项才能退出游戏,在玩家点击退出游戏后,会有提示对话框,玩家必须点击“确认”按钮才会真的突出游戏,这种设计是为了防止玩家误点而关闭游戏。
1.6 其它功能的实现
迷宫模式下地图风格切换的实现
- 在迷宫模式下,有3种地图风格可以选择:魔法少女、火影忍者、超级玛丽。玩家选择不同的地图风格后,点击生成迷宫按钮后,就会生成相应风格的迷宫。
- 下拉菜单选项框类QcomboBox存储不同地图风格的名称,当玩家点开下拉菜单,选择不同的地图风格时,QcomboBox类对象会产生一个currentIndexChanged信号,并触发MapStytleSet槽函数,槽函数会使下方的QLabel标签显示相应地图风格的概览图片。点击生成迷宫按钮后,加载相对应地图风格的贴图,就会生成玩家选择的风格的地图。
游戏的BGM以及地牢模式中的音效实现
- QT中的音乐媒体类QmediaPlayer可以加载音乐资源,并播放。而地牢模式中的游戏音效,实现的方法是通过音乐媒体列表类QmediaPlaylist先把各种音效资源加载到列表里,然后需要不同的音效就通过setCurrentIndex函数列表中的不同音效进行播放。
2.游戏安装和使用说明
-
游戏的安装:
本游戏软件为绿色软件,无需安装。双击exe程序“迷宫与地牢”即可运行。
游戏的玩法: