基於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程序“迷宮與地牢”即可運行。
遊戲的玩法: