最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Qt實(shí)現(xiàn)打地鼠游戲的方法詳解

 更新時(shí)間:2022年10月11日 11:20:09   作者:中國(guó)好公民st  
這篇文章主要和大家詳細(xì)介紹了如何利用Qt實(shí)現(xiàn)一個(gè)簡(jiǎn)單的打地鼠游戲,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下

今天與大家分享一個(gè)小游戲的實(shí)現(xiàn):打地鼠

看一下實(shí)現(xiàn)效果吧~

在指定的時(shí)間內(nèi)打中一定數(shù)額的地鼠,否則失敗,就如上述展示效果一樣,自己寫(xiě)的小程序,居然連第二關(guān)也過(guò)不去,還挺尷尬的!

實(shí)現(xiàn)打地鼠小游戲不難,最主要的核心就是依靠定時(shí)器,按照一定間隔觸發(fā)。接下來(lái),我來(lái)講解下是如何實(shí)現(xiàn)的吧!

功能講解

開(kāi)發(fā)環(huán)境:VS2017 + Qt5.14.2 x64

1.確定地鼠數(shù)量

對(duì)于打地鼠這款游戲來(lái)說(shuō),地鼠是從任意的洞口鉆出。

在效果中,一共存在6個(gè)地鼠洞,最容易實(shí)現(xiàn)的方式:創(chuàng)建6個(gè)地鼠,每個(gè)地鼠洞都對(duì)應(yīng)一個(gè)地鼠。

實(shí)現(xiàn)代碼如下:

for (int i = 0; i < num; i++)
{
	QPushButton *btn = new QPushButton(this);
	int nTop = i / 3 == 0 ? 300 : 450;
	int nRemainder = i % 3;
	if (nRemainder == 0)
	{
		btn->setGeometry(190, nTop, 180, 130);
	}
	else if (nRemainder == 1)
	{
		btn->setGeometry(480, nTop, 180, 130);
	}
	else if(nRemainder == 2)
	{
		btn->setGeometry(780, nTop, 180, 130);
	}
	btn->setStyleSheet(qsBtnStyle);
	btn->setProperty("num", i);
	btn->hide();
	connect(btn, &QPushButton::clicked, this, &QGrameWhacAmole::OnBnClickedSusliks); //選中地鼠
	m_vetBtnCtrls.push_back(btn);
}

代碼解析:

num:此刻代表的是6,表明了需要?jiǎng)?chuàng)建6個(gè)地鼠,平均分配到每個(gè)洞中。

對(duì)每個(gè)地鼠按鈕響應(yīng)對(duì)應(yīng)的clicked消息,每當(dāng)打中一個(gè)地鼠,OnBnClickedSusliks消息內(nèi)就對(duì)分?jǐn)?shù)+1。

并且,創(chuàng)建出的地鼠默認(rèn)是隱藏狀態(tài)的。

2.定義游戲難易程序

在程序中定義了四種難度,設(shè)置了枚舉類(lèi)型:

enum ENUM_GameMode
{
	GameMode_difficulty1,
	GameMode_difficulty2,
	GameMode_difficulty3, 
	GameMode_difficulty4, 
	GameMode_OK,
	GameMode_Failed,
};

GameMode_difficulty1:難度1,說(shuō)明有1個(gè)地鼠出沒(méi)

GameMode_difficulty2:難度2,說(shuō)明有2個(gè)地鼠出沒(méi),

GameMode_difficulty3:難度3,說(shuō)明有3個(gè)地鼠出沒(méi),

GameMode_difficulty4:難度4,說(shuō)明有4個(gè)地鼠出沒(méi)

在程序中,如何判斷通過(guò)某一關(guān)呢?

宏定義確定通關(guān)分?jǐn)?shù)

#define  difficulty1Count 10 //難度1個(gè)數(shù)
#define  difficulty2Count 30 
#define  difficulty3Count 60
#define  difficulty4Count 100

當(dāng)?shù)谝魂P(guān)時(shí),只需要打中10個(gè)地鼠;第二關(guān)需要累計(jì)打中30個(gè)地鼠,以此類(lèi)推。

3.難度切換

在OnBnClickedSusliks消息中,根據(jù)當(dāng)前的分?jǐn)?shù)來(lái)確定是否要晉級(jí)。

響應(yīng)消息后,對(duì)分?jǐn)?shù)進(jìn)行+1處理

m_nScore += 1;

m_nScore是當(dāng)前類(lèi)的成員變量,表示:打中的地鼠次數(shù)也就是當(dāng)前分?jǐn)?shù)。

打中后隱藏該地鼠

當(dāng)打中某個(gè)地鼠后,需要立刻隱藏地鼠,此時(shí)就運(yùn)用到了剛剛在創(chuàng)建地鼠時(shí)"setProperty"綁定的變量了。

QPushButton *btn = qobject_cast<QPushButton*>(sender());
int num = btn->property("num").toInt();
m_vetBtnCtrls[num]->hide(); //隱藏對(duì)應(yīng)編號(hào)控件

分?jǐn)?shù)判斷是否晉級(jí)

當(dāng)分?jǐn)?shù)到達(dá)難度1時(shí),晉升成難度2,其它的關(guān)卡都一樣

if (m_nScore == difficulty1Count) //難度1通過(guò)
{
	killTimer(m_nTimerStartId);
	m_nTimerStartId = 0;

	this->HideTotalSucliks();
		
	m_enumMode = GameMode_difficulty2;
	this->SetTipsStyle(m_enumMode);

	m_nTimerStartId = startTimer(difficulty2Time);
	m_dwBeginTime = GetTickCount();
}

當(dāng)通過(guò)第一關(guān)后,停止定時(shí)器,隱藏正在展示的所有地鼠,更改模式狀態(tài),重新設(shè)置提示文本,開(kāi)始定時(shí)器,重新記錄開(kāi)始通關(guān)時(shí)間。

m_dwBeginTime:是記錄每次開(kāi)始游戲時(shí)的時(shí)間,主要作用于挑戰(zhàn)失敗的判斷,也就是說(shuō),每次觸發(fā)定時(shí)器時(shí),當(dāng)前最新時(shí)間與最開(kāi)始通關(guān)時(shí)間的差值 大于 通關(guān)時(shí)間時(shí),說(shuō)明當(dāng)前關(guān)卡挑戰(zhàn)失敗!

4.定時(shí)器處理

這也是當(dāng)前小游戲中最核心的處理部分了~

為了方便起見(jiàn),直接使用QWidget自帶的定時(shí)器,而不是使用new QTimer的方式

virtual void timerEvent(QTimerEvent *event);

在定時(shí)器的處理中,分成了4部分,我們分別講述~

獲取定時(shí)器Id的觸發(fā)消息

if (event->timerId() == m_nTimerStartId)
{
    //消息處理
}

只有當(dāng)定時(shí)器的觸發(fā)id與我們?cè)O(shè)定的id一致時(shí),才可以。

關(guān)閉提示頁(yè)面

在進(jìn)行難度切換時(shí),設(shè)置了提示文本,也就是效果圖中的“開(kāi)始”、“開(kāi)始第二關(guān)”等文字提示信息,在進(jìn)入到定時(shí)器事件中,首先判斷,該控件是否隱藏?如果未隱藏,先進(jìn)行隱藏。

if (ui.labTips->isHidden() == false)
{
	ui.labTips->hide();
}

在這里需要我走過(guò)一個(gè)坑:使用isVisible()不一定獲取出控件的顯示狀態(tài),但是isHidden()始終是有效的。

判斷當(dāng)前關(guān)卡是否超時(shí)?

這也就是上文說(shuō)到的m_dwBeginTime與最新觸發(fā)時(shí)間的差值

DWORD dwTime = GetTickCount() - m_dwBeginTime;
if (dwTime > difficultyTimeout)
{
	this->RunningFailed();
}

根據(jù)關(guān)卡不同,顯示不同的地鼠

這里,就是對(duì)地鼠顯示的邏輯處理了,根據(jù)枚舉模式不同,分別處理

switch (m_enumMode)
{
case QGrameWhacAmole::GameMode_difficulty1:
	this->RunningGamedifficulty(1);
break;
case QGrameWhacAmole::GameMode_difficulty2:
	this->RunningGamedifficulty(2);
break;
case QGrameWhacAmole::GameMode_difficulty3:
	this->RunningGamedifficulty(3);
break;
case QGrameWhacAmole::GameMode_difficulty4:
	this->RunningGamedifficulty(4);
break;
default:
break;
}

核心函數(shù)是:RunningGamedifficulty

如何讓地鼠進(jìn)行隨機(jī)顯示呢?

在當(dāng)前例子中,獲取隨機(jī)數(shù)[0,6)之間的值,隨機(jī)到哪個(gè)數(shù),哪個(gè)下標(biāo)下對(duì)應(yīng)的地鼠被顯示,其余的地鼠處于隱藏狀態(tài)。

隨機(jī)數(shù)生成方法:

int QGrameWhacAmole::GetRandomNumber()
{
	QTime time = QTime::currentTime();
	qsrand(time.msec() + time.second() * 1000);
	int n = qrand() % 6;
	return n;
}

有人說(shuō)使用這種方法可以在短時(shí)間內(nèi)生成的隨機(jī)數(shù)不相同,這個(gè)方法我已經(jīng)驗(yàn)證過(guò)了,不行!

還有的人說(shuō)可以添加sleep,我也嘗試過(guò)了,不行!

那么,該如何獲取不重復(fù)的隨機(jī)數(shù)呢?

在這里,采用了std::set<int>容器的方式,RunningGamedifficulty中的部分代碼如下:

void QGrameWhacAmole::RunningGamedifficulty(int nCount)
{
    1:隨機(jī)數(shù)生成
    std::set<int> setRandom; //存儲(chǔ)隨機(jī)數(shù)
    for (int i = 0; setRandom.size() < nCount; i++)
    {
	//獲取隨機(jī)數(shù)
	int num = this->GetRandomNumber();
	//如果隨機(jī)數(shù)在容器中從未出現(xiàn)過(guò),存儲(chǔ)并應(yīng)用
	if (setRandom.size() != 0)
	{
		std::set<int>::iterator itFind = setRandom.find(num);
		if (itFind != setRandom.end())
		{
			continue; //存在重復(fù)值,后續(xù)不進(jìn)行處理
		}
	}
	//容器中存在數(shù)據(jù),存儲(chǔ)之前進(jìn)行判斷
	setRandom.insert(num);
     }
        
        
}

根據(jù)上述代碼也可以看出,每生成一個(gè)隨機(jī)數(shù),就進(jìn)行存儲(chǔ),當(dāng)容器中出現(xiàn)相同的隨機(jī)數(shù)時(shí),重新生成。

nCount:就是需要展示的地鼠個(gè)數(shù),在for循環(huán)中,中間的判斷條件與以往不同,當(dāng)有效地地鼠編號(hào)大于地鼠個(gè)數(shù)后,就不再獲取隨機(jī)數(shù)了。

這種方式,無(wú)論是獲取多少個(gè)地鼠個(gè)數(shù)都是適用的。

其次,根據(jù)獲取的顯示的地鼠下標(biāo)數(shù)就可以對(duì)所有的地鼠進(jìn)行做顯示、隱藏操作了,代碼如下:

for (int m = 0; m < m_vetBtnCtrls.size(); m++)
{
	std::set<int>::iterator itNum = setRandom.find(m);
	if (itNum != setRandom.end())
	{
		m_vetBtnCtrls[m]->show();
	}
	else
	{
		m_vetBtnCtrls[m]->hide();
	}
}

總結(jié)

到這里,核心的實(shí)現(xiàn)功能就已經(jīng)講解完了,功能難點(diǎn):

1:根據(jù)地鼠個(gè)數(shù)隨機(jī)顯示地鼠位置(RunningGamedifficulty處理邏輯)。

2:關(guān)卡晉級(jí)。

3:挑戰(zhàn)失敗處理。

到此這篇關(guān)于Qt實(shí)現(xiàn)打地鼠游戲的方法詳解的文章就介紹到這了,更多相關(guān)Qt打地鼠游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文帶你學(xué)習(xí)C++析構(gòu)函數(shù)

    一文帶你學(xué)習(xí)C++析構(gòu)函數(shù)

    在C++中,析構(gòu)函數(shù)是一種特殊類(lèi)型的成員函數(shù),用于在對(duì)象生命周期結(jié)束時(shí)被自動(dòng)調(diào)用,本文我們將介紹C++析構(gòu)函數(shù)的一些重要知識(shí)點(diǎn),并提供相應(yīng)代碼示例,需要的朋友可以參考下
    2023-05-05
  • C++中constexpr與函數(shù)參數(shù)轉(zhuǎn)發(fā)的操作方法

    C++中constexpr與函數(shù)參數(shù)轉(zhuǎn)發(fā)的操作方法

    constexpr是c++11引入的關(guān)鍵字,c++11的constexpr的函數(shù)中只是支持單句代碼,c++14限制放寬,可以在里邊寫(xiě)循環(huán)及邏輯判斷等語(yǔ)句,本文探討關(guān)于constexpr的函數(shù)中參數(shù)的現(xiàn)象,以及如果參數(shù)是constexpr如何做轉(zhuǎn)發(fā),感興趣的朋友一起看看吧
    2024-02-02
  • 用C/C++代碼檢測(cè)ip能否ping通(配合awk和system可以做到批量檢測(cè))

    用C/C++代碼檢測(cè)ip能否ping通(配合awk和system可以做到批量檢測(cè))

    今天小編就為大家分享一篇關(guān)于用C/C++代碼檢測(cè)ip能否ping通(配合awk和system可以做到批量檢測(cè)),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04
  • C語(yǔ)言鏈表實(shí)現(xiàn)簡(jiǎn)易通訊錄

    C語(yǔ)言鏈表實(shí)現(xiàn)簡(jiǎn)易通訊錄

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言鏈表實(shí)現(xiàn)簡(jiǎn)易通訊錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • C語(yǔ)言變量和全局變量能否重名問(wèn)題

    C語(yǔ)言變量和全局變量能否重名問(wèn)題

    這篇文章主要介紹了C語(yǔ)言變量和全局變量能否重名問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • C語(yǔ)言時(shí)間函數(shù)之mktime和difftime詳解

    C語(yǔ)言時(shí)間函數(shù)之mktime和difftime詳解

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言時(shí)間函數(shù)之mktime和difftime,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一,希望能夠給你帶來(lái)幫助
    2022-02-02
  • 利用Matlab制作一款3D版2048小游戲

    利用Matlab制作一款3D版2048小游戲

    2048作為一款經(jīng)典的小游戲,相信很多人都玩過(guò)吧?但是3D版的2048不知道有沒(méi)有人玩過(guò)呢?本文將用Matlab制作一個(gè)3D版的2048小游戲,快跟隨小編一起動(dòng)手試一試吧
    2022-02-02
  • C++ 情懷游戲掃雷的實(shí)現(xiàn)流程詳解

    C++ 情懷游戲掃雷的實(shí)現(xiàn)流程詳解

    掃雷是電腦上很經(jīng)典很經(jīng)典的傳統(tǒng)老游戲,從小編第一次摸到計(jì)算機(jī)開(kāi)始就玩過(guò)掃雷,雖然當(dāng)時(shí)并不理解玩法原理,但終是第一次玩電腦游戲,下面來(lái)從掃雷的前世今生講起
    2021-11-11
  • C語(yǔ)言冷知識(shí)之預(yù)處理字符串操作符詳解

    C語(yǔ)言冷知識(shí)之預(yù)處理字符串操作符詳解

    當(dāng)年學(xué)習(xí)C語(yǔ)言的第一門(mén)課就提到過(guò)標(biāo)記(Token)的概念,不過(guò),相信在多年之后你再次聽(tīng)到這個(gè)術(shù)語(yǔ)時(shí)會(huì)一臉懵逼,比如我。因此特地翻了翻資料,整理下來(lái)這些筆記,希望對(duì)大家有所幫助
    2022-11-11
  • C++實(shí)現(xiàn)病人就醫(yī)管理系統(tǒng)

    C++實(shí)現(xiàn)病人就醫(yī)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++語(yǔ)言實(shí)現(xiàn)病人就醫(yī)管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01

最新評(píng)論

陕西省| 曲周县| 泗阳县| 安溪县| 贵南县| 毕节市| 泽州县| 孟津县| 石柱| 武宁县| 伊金霍洛旗| 上犹县| 唐海县| 定州市| 滦南县| 明星| 吉木萨尔县| 蓬溪县| 银川市| 台东市| 龙陵县| 嘉峪关市| 信阳市| 舒城县| 娄烦县| 内丘县| 河西区| 雷山县| 当雄县| 雅江县| 苍山县| 通州市| 保德县| 城口县| 蚌埠市| 大兴区| 盐亭县| 乌鲁木齐县| 华坪县| 蒙阴县| 墨脱县|