欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Qt實現打地鼠游戲的方法詳解

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

今天與大家分享一個小游戲的實現:打地鼠

看一下實現效果吧~

在指定的時間內打中一定數額的地鼠,否則失敗,就如上述展示效果一樣,自己寫的小程序,居然連第二關也過不去,還挺尷尬的!

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

功能講解

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

1.確定地鼠數量

對于打地鼠這款游戲來說,地鼠是從任意的洞口鉆出。

在效果中,一共存在6個地鼠洞,最容易實現的方式:創(chuàng)建6個地鼠,每個地鼠洞都對應一個地鼠。

實現代碼如下:

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,表明了需要創(chuàng)建6個地鼠,平均分配到每個洞中。

對每個地鼠按鈕響應對應的clicked消息,每當打中一個地鼠,OnBnClickedSusliks消息內就對分數+1。

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

2.定義游戲難易程序

在程序中定義了四種難度,設置了枚舉類型:

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

GameMode_difficulty1:難度1,說明有1個地鼠出沒

GameMode_difficulty2:難度2,說明有2個地鼠出沒,

GameMode_difficulty3:難度3,說明有3個地鼠出沒,

GameMode_difficulty4:難度4,說明有4個地鼠出沒

在程序中,如何判斷通過某一關呢?

宏定義確定通關分數

#define  difficulty1Count 10 //難度1個數
#define  difficulty2Count 30 
#define  difficulty3Count 60
#define  difficulty4Count 100

當第一關時,只需要打中10個地鼠;第二關需要累計打中30個地鼠,以此類推。

3.難度切換

在OnBnClickedSusliks消息中,根據當前的分數來確定是否要晉級。

響應消息后,對分數進行+1處理

m_nScore += 1;

m_nScore是當前類的成員變量,表示:打中的地鼠次數也就是當前分數。

打中后隱藏該地鼠

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

QPushButton *btn = qobject_cast<QPushButton*>(sender());
int num = btn->property("num").toInt();
m_vetBtnCtrls[num]->hide(); //隱藏對應編號控件

分數判斷是否晉級

當分數到達難度1時,晉升成難度2,其它的關卡都一樣

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

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

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

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

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

4.定時器處理

這也是當前小游戲中最核心的處理部分了~

為了方便起見,直接使用QWidget自帶的定時器,而不是使用new QTimer的方式

virtual void timerEvent(QTimerEvent *event);

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

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

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

只有當定時器的觸發(fā)id與我們設定的id一致時,才可以。

關閉提示頁面

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

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

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

判斷當前關卡是否超時?

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

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

根據關卡不同,顯示不同的地鼠

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

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;
}

核心函數是:RunningGamedifficulty

如何讓地鼠進行隨機顯示呢?

在當前例子中,獲取隨機數[0,6)之間的值,隨機到哪個數,哪個下標下對應的地鼠被顯示,其余的地鼠處于隱藏狀態(tài)。

隨機數生成方法:

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

有人說使用這種方法可以在短時間內生成的隨機數不相同,這個方法我已經驗證過了,不行!

還有的人說可以添加sleep,我也嘗試過了,不行!

那么,該如何獲取不重復的隨機數呢?

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

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

根據上述代碼也可以看出,每生成一個隨機數,就進行存儲,當容器中出現相同的隨機數時,重新生成。

nCount:就是需要展示的地鼠個數,在for循環(huá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();
	}
}

總結

到這里,核心的實現功能就已經講解完了,功能難點:

1:根據地鼠個數隨機顯示地鼠位置(RunningGamedifficulty處理邏輯)。

2:關卡晉級。

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

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

相關文章

  • C++預定義的流對象基本示例詳解

    C++預定義的流對象基本示例詳解

    這篇文章主要為大家介紹了C++預定義的流對象基本示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • C語言實現軍旗游戲的示例代碼

    C語言實現軍旗游戲的示例代碼

    這篇文章主要為大家詳細介紹了如何利用C語言實現軍旗游戲,文中的示例代碼講解詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-11-11
  • C語言實現簡單的五子棋游戲

    C語言實現簡單的五子棋游戲

    這篇文章主要為大家詳細介紹了c語言實現簡單的五子棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • MATLAB中subplot函數的語法與使用實例

    MATLAB中subplot函數的語法與使用實例

    subplot()是將多個圖畫到一個平面上的工具,下面這篇文章主要給大家介紹了關于MATLAB中subplot函數的語法與使用的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • C 語言基礎教程(我的C之旅開始了)[四]

    C 語言基礎教程(我的C之旅開始了)[四]

    C 語言基礎教程(我的C之旅開始了)[四]...
    2007-02-02
  • C++ Boost Flyweight庫使用介紹

    C++ Boost Flyweight庫使用介紹

    Boost是為C++語言標準庫提供擴展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標準庫的后備,是C++標準化進程的開發(fā)引擎之一,是為C++語言標準庫提供擴展的一些C++程序庫的總稱
    2022-12-12
  • C語言數組超詳細講解上

    C語言數組超詳細講解上

    數組是一組有序的數據的集合,數組中元素類型相同,由數組名和下標唯一地確定,數組中數據不僅數據類型相同,而且在計算機內存里連續(xù)存放,地址編號最低的存儲單元存放數組的起始元素,地址編號最高的存儲單元存放數組的最后一個元素
    2022-04-04
  • C語言數組快速入門詳細講解

    C語言數組快速入門詳細講解

    數組是一組有序的數據的集合,數組中元素類型相同,由數組名和下標唯一地確定,數組中數據不僅數據類型相同,而且在計算機內存里連續(xù)存放,地址編號最低的存儲單元存放數組的起始元素,地址編號最高的存儲單元存放數組的最后一個元素
    2022-05-05
  • C++中cout輸出中文信息亂碼問題及解決

    C++中cout輸出中文信息亂碼問題及解決

    這篇文章主要介紹了C++中cout輸出中文信息亂碼問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C++實現選擇性排序(SelectionSort)

    C++實現選擇性排序(SelectionSort)

    這篇文章主要為大家詳細介紹了C++實現選擇性排序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04

最新評論