《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 設(shè)計(jì)應(yīng)用 > 基于Qt4的掃雷游戲的設(shè)計(jì)與實(shí)現(xiàn)
基于Qt4的掃雷游戲的設(shè)計(jì)與實(shí)現(xiàn)
來源:微型機(jī)與應(yīng)用2012年第16期
柯 勝1, 孫 進(jìn)1, 鄧志良2
(1.江蘇科技大學(xué),江蘇 鎮(zhèn)江 2120031; 2.常州信息職業(yè)技術(shù)學(xué)院,江蘇 常州 213164
摘要: 在簡要介紹掃雷游戲主界面設(shè)計(jì)的基礎(chǔ)上,給出了一種基于Qt的掃雷游戲的設(shè)計(jì)與實(shí)現(xiàn)方法,并在Qt4.3.2和Red Hat Enterprise Linux 4操作系統(tǒng)下成功實(shí)現(xiàn)。經(jīng)過實(shí)驗(yàn)測(cè)試,結(jié)果正確,各項(xiàng)功能達(dá)到游戲要求。該實(shí)現(xiàn)方法對(duì)其他基于Qt的游戲開發(fā)起到拋磚引玉的作用,同時(shí)對(duì)各專業(yè)人員借助Qt快速開發(fā)具備強(qiáng)大計(jì)算功能的專業(yè)應(yīng)用軟件具有重要的意義。
Abstract:
Key words :

摘  要: 在簡要介紹掃雷游戲主界面設(shè)計(jì)的基礎(chǔ)上,給出了一種基于Qt的掃雷游戲的設(shè)計(jì)與實(shí)現(xiàn)方法,并在Qt4.3.2和Red Hat Enterprise Linux 4操作系統(tǒng)下成功實(shí)現(xiàn)。經(jīng)過實(shí)驗(yàn)測(cè)試,結(jié)果正確,各項(xiàng)功能達(dá)到游戲要求。該實(shí)現(xiàn)方法對(duì)其他基于Qt的游戲開發(fā)起到拋磚引玉的作用,同時(shí)對(duì)各專業(yè)人員借助Qt快速開發(fā)具備強(qiáng)大計(jì)算功能的專業(yè)應(yīng)用軟件具有重要的意義。
關(guān)鍵詞: Qt;掃雷游戲;事件;信號(hào)與槽

    最初以訓(xùn)練鼠標(biāo)操作為目的而設(shè)計(jì)的掃雷游戲是一款經(jīng)久不衰的Windows平臺(tái)休閑游戲。盡管Windows操作系統(tǒng)經(jīng)歷數(shù)次換代,變得越來越龐大、復(fù)雜,但這個(gè)可愛的小游戲在任何版本的Windows操作系統(tǒng)里卻依然保持著原貌,幾乎每個(gè)電腦使用者都接觸過[1]。
    Qt是諾基亞開發(fā)的一個(gè)跨平臺(tái)的C++圖形用戶界面應(yīng)用程序框架。它為應(yīng)用程序開發(fā)者提供建立藝術(shù)級(jí)的圖形用戶界面所需的所有功能。Qt是完全面向?qū)ο蟮模苋菀讛U(kuò)展,并且允許真正地組件編程。自1996年,Qt進(jìn)入商業(yè)領(lǐng)域,它已經(jīng)成為全世界范圍內(nèi)數(shù)千種成功的應(yīng)用程序的基礎(chǔ)。Qt也是流行的Linux桌面環(huán)境KDE 的基礎(chǔ)。基本上,Qt與X Window上的Motif、Openwin、GTK等圖形界面庫和Windows平臺(tái)上的MFC、OWL、VCL、ATL屬同類型,但Qt具有優(yōu)良的跨平臺(tái)特性、面向?qū)ο蟆⒇S富的API、大量的開發(fā)文檔等優(yōu)點(diǎn)[2]。
    本課題是在Linux系統(tǒng)下設(shè)計(jì)并開發(fā)的,設(shè)計(jì)了一款基于Qt環(huán)境的掃雷游戲,使用了C++語言程序。
1 掃雷游戲主界面的設(shè)計(jì)
  游戲主界面由菜單、游戲區(qū)、按鈕區(qū)、信息顯示區(qū)等幾部分構(gòu)成,如圖1所示。Qt提供了一套完整的GUI模塊,能夠完成基本的Windows窗體應(yīng)用程序,因此可以簡單地為掃雷程序制作出界面[3]。圖1主要通過子類化QmainWindow創(chuàng)建掃雷游戲應(yīng)用程序用戶界面。Qt還提供了定時(shí)器,能夠完成游戲的計(jì)時(shí)。

2 鼠標(biāo)事件的處理
    當(dāng)點(diǎn)擊鼠標(biāo)左鍵時(shí),設(shè)置ok_flag_為true,說明此方塊進(jìn)行了翻開操作。如果方塊是地雷,發(fā)出一個(gè)explode()信號(hào);如果不是地雷,發(fā)出一個(gè)safe()信號(hào),同時(shí)顯示數(shù)字。這動(dòng)作應(yīng)當(dāng)在ok_flag_無效且mark_flag_也無效的前提下進(jìn)行,因?yàn)槿绻鹢k_flag_有效,則說明此方塊已經(jīng)翻開了,沒有必要重做;如果mark_flag_有效,則說明玩家標(biāo)志此方塊有雷,不應(yīng)該去翻開,否則即為自取滅亡。
    點(diǎn)擊鼠標(biāo)右鍵進(jìn)行旗幟安插或者移除操作應(yīng)該在ok_flag_無效的前提下進(jìn)行,因?yàn)閷?duì)于一個(gè)已經(jīng)翻開的方塊,安插毫無意義。
 類的定義如下:
 class BlockArea:public Qwidget
  {
  Q_OBJECT
  public:
   BlockArea(QWidget* parent=0);
   private slots:
     void slotSafe();
     void slotExplode();
  private:
     int calculateMines(int x,int y)const; //計(jì)算以(x,y)為中心的九宮格內(nèi)的雷數(shù)
     private:
        QGridLayout* mainLayout;
             int row_;
             int column_;
             int total_block_number_;
             int total_mine_number_;
             int ok_block_number_;
     };
     下面是代碼實(shí)現(xiàn)部分:
  void
Block::mousePressEvent(QMouseEvent* event)
     {
       if(event->button()==Qt::LeftButton)
     {
       if(ok_flag_==false&&mark_flag_==false)
     {
       ok_flag_=true;
       if(mine_flag_==true)
          {
      setPixmap(QPixmap(":/images/mine.png"));
             update();
             emit explode();
          }else{
            setPixmap(QPixmap(":/images/mine_"+QString("%1").
             arg
        (number_)+".png"));
                 update();
                 emit safe();
          }
          }
         }else
    if(event->button()==Qt::RightButton){
       if(ok_flag_==false){
       if(mark_flag_==false){
       mark_flag_=true;
      setPixmap(QPixmap(":/images/flag.png"));
          }else{
             mark_flag_=false;
      setPixmap(QPixmap(":/images/normal.png"));
         }
                 update();
          }
          }
         }
    設(shè)計(jì)的實(shí)現(xiàn)比較簡單,需要說明的是本文模擬的鼠標(biāo)事件并不是單擊而是按下,這對(duì)于掃雷已經(jīng)足夠了。同時(shí),會(huì)發(fā)現(xiàn)兩個(gè)信號(hào)函數(shù)沒有實(shí)現(xiàn),這個(gè)工作會(huì)由moc自動(dòng)完成,因此不必在.cpp中實(shí)現(xiàn),并且它們永遠(yuǎn)不會(huì)有返回值(即void)。
3 初始化
3.1 雷區(qū)/非雷區(qū)的產(chǎn)生

     下面是BlockArea的構(gòu)造函數(shù):
  BlockArea::BlockArea(QWidget* parent)
      :QWidget(parent)
      {
      //下面5行來初始化BlockArea的信息,自定義行數(shù)為10、列數(shù)為10、總格數(shù)為100、雷數(shù)為10。
      row_=10;
      column_=10;
      total_block_number_=row_*column_;
      total_mine_number_=10;
      ok_block_number_=0;

  //下面6行生成一個(gè)具有 total_block_number_個(gè)元素的bool類型的隨機(jī)序列,用來布雷(即確定哪些方塊放雷,哪些不放),因?yàn)镼tAlgorithms中沒有包含打亂序列的算法,故采用C++的STL里的random_shuffle。
     bool mine_flag[total_block_number_];
      for(int i=0;i<total_mine_number_;i++)
      mine_flag[i]=true;
      for(int i=total_mine_number_;i<total_block_number_;i++)
      mine_flag[i]=false;
    std::random_shuffle(mine_flag,mine_flag+total_block_number_);
  
    //下面4行將方塊放進(jìn)布局
     mainLayout=new QGridLayout(this);
     for(int i=0;i<row_;i++)
     for(int j=0;j<column_;j++)
     mainLayout->addWidget(new Block(mine_flag[i*column_+j]),i,j);

     //下面6行設(shè)置每個(gè)方塊的周圍雷數(shù),并且將信號(hào)safe()與槽slotSafe()相聯(lián),信號(hào)explode()與槽slotExplode()相聯(lián)。Block* current_block=static_cast<Block*>(mainLayout->itemAtPosition(i,j)->widget());這句話是獲取布局中位于(i,j)位置處的widget*,將其轉(zhuǎn)換為Block*,static_cast是C++關(guān)鍵字,這里執(zhí)行一個(gè)下行轉(zhuǎn)換動(dòng)作。
      for(int i=0;i<row_;i++){
      for(int j=0;j<column_;j++){
     Block* current_block=static_cast<Block*>(mainLayout->
        itemAtPosition(i,j)->widget());
     current_block->setNumber(calculateMines(i,j));
     connect(current_block,SIGNAL(safe()),this,SLOT(slotSafe
        ()));
     connect(current_block,SIGNAL(explode()),this,SLOT(slot
        Explode()));
     }
     }
3.2 周邊雷數(shù)的計(jì)算

 


     要計(jì)算(x,y)位置周邊地雷的個(gè)數(shù),首先需計(jì)算出一個(gè)點(diǎn),然后判斷此點(diǎn)是否落在BlockArea中,如果落在BlockArea中,再判斷是否是雷,如果是,則計(jì)數(shù)器加1。
    int BlockArea::calculateMines(int x,int y)const
     {
        int number=0;
        for(int i=0;i<3;i++)
             for(int j=0;j<3;j++)
             if( (x-1+i>=0) && (x-1+i<row_) && (y-1+j>=0)            && (y-1+j<column_) )
             if(static_cast<Block*>(mainLayout->itemAtPosition(x-
            1+i,y-1+j)->widget())->isMine())
             ++number;
            return number;
  }
    該掃雷游戲在Qt4和Red Hat Enterprise Linux 4操作系統(tǒng)上成功實(shí)現(xiàn),能在Windows和Linux平臺(tái)下運(yùn)行。除能實(shí)現(xiàn)基本的左鍵打開、右鍵標(biāo)記的掃雷功能以外,還能實(shí)現(xiàn)計(jì)時(shí)、自定義游戲難度、作弊、語音提示等擴(kuò)展功能。經(jīng)過試驗(yàn)測(cè)試,界面美觀,結(jié)果正確,各項(xiàng)功能達(dá)到游戲要求。該實(shí)現(xiàn)方法對(duì)其他基于Qt的游戲開發(fā)起到了拋磚引玉的作用,其中的鍵盤、鼠標(biāo)等功能的實(shí)現(xiàn)方法可用于其他Qt編程,同時(shí)對(duì)各專業(yè)人員借助Qt快速開發(fā)具備強(qiáng)大計(jì)算機(jī)功能的專業(yè)應(yīng)用軟件具有重要的意義。
參考文獻(xiàn)
[1] 陳子為.基于Matlab GUI掃雷游戲的設(shè)計(jì)與實(shí)現(xiàn)[J]. 現(xiàn)代電子技術(shù),2008(24):85-88.
[2] BLANCHETTE J,SUMMERFIELD M.C++ GUI QT4編程(第二版)[M].北京:電子工業(yè)出版社,2008.
[3] 張建強(qiáng),張秀梅.掃雷游戲策略初探[J]. 數(shù)學(xué)教學(xué),2004(6):32-33.
[4] 成潔, 盧紫毅. Linux窗口程序設(shè)計(jì)——Qt精彩實(shí)例分析[M].北京:清華大學(xué)出版社,2008.
[5] 趙大偉,肖周芳,張艷.從掃雷游戲淺談一些算法問題[J]. 科技信息,2008(29):69.
[6] 錢會(huì)敏,于守秋.自動(dòng)掃雷算法淺談[J].科技創(chuàng)新導(dǎo)報(bào),2009(31):250.
[7] 劉艷青,蘇桂蓮.基于Qt4的圖形用戶界面程序的設(shè)計(jì)與實(shí)現(xiàn)[J].現(xiàn)代計(jì)算機(jī)(專業(yè)版),2009(3):170-172.

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。
亚洲一区二区欧美_亚洲丝袜一区_99re亚洲国产精品_日韩亚洲一区二区
很黄很黄激情成人| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 亚洲国产精品99久久久久久久久| 亚洲欧美日韩一区二区三区在线观看| 在线中文字幕不卡| 艳妇臀荡乳欲伦亚洲一区| 亚洲精品在线三区| 亚洲日本成人女熟在线观看| 亚洲国产婷婷综合在线精品| 亚洲盗摄视频| 在线观看中文字幕不卡| **欧美日韩vr在线| 亚洲激情国产| 亚洲卡通欧美制服中文| 亚洲精一区二区三区| 9l国产精品久久久久麻豆| 99亚洲一区二区| 亚洲一区二区三区欧美| 午夜精品久久| 久久国产精品久久久久久久久久| 久久国产手机看片| 亚洲激情在线| 亚洲最新在线视频| 午夜精品久久久久久| 欧美专区18| 久久婷婷麻豆| 欧美大片在线观看一区| 欧美日韩在线高清| 国产精品一区免费观看| 国产一区二区三区成人欧美日韩在线观看| 国产午夜精品福利| 亚洲国产精品久久人人爱蜜臀| 亚洲人永久免费| 亚洲视频一二区| 欧美在线日韩在线| 91久久精品一区二区三区| 一区二区三区欧美日韩| 欧美在线免费看| 嫩草成人www欧美| 欧美午夜片在线免费观看| 国产精品毛片va一区二区三区| 国产一区二区欧美日韩| 亚洲国产天堂网精品网站| 日韩午夜精品| 欧美一区二区视频97| 亚洲精品裸体| 亚洲欧美综合精品久久成人| 久久精品人人做人人爽电影蜜月| 欧美成人在线免费视频| 欧美三级乱人伦电影| 国产欧美一区二区精品仙草咪| 在线免费观看成人网| 一级日韩一区在线观看| 久久精品30| 亚洲私人黄色宅男| 久久xxxx精品视频| 欧美巨乳在线| 国产亚洲一区在线播放| 日韩午夜三级在线| 久久精品99国产精品| 一区二区三区欧美激情| 久久久免费精品视频| 欧美另类人妖| 韩国一区电影| 中文亚洲免费| 亚洲三级电影全部在线观看高清| 午夜精品久久久久99热蜜桃导演| 免费人成精品欧美精品| 国产精品视频免费观看www| 亚洲激情一区二区| 欧美在线1区| 亚洲欧美另类久久久精品2019| 鲁大师成人一区二区三区| 国产精品国产a| 亚洲国产综合视频在线观看| 亚洲欧美欧美一区二区三区| 日韩视频一区二区三区在线播放免费观看| 欧美一区二区三区免费在线看| 欧美激情中文不卡| 国产最新精品精品你懂的| 中文精品99久久国产香蕉| 亚洲日本激情| 久久精品一区二区三区中文字幕| 欧美日韩国产系列| 在线免费观看一区二区三区| 亚洲欧美国产毛片在线| 亚洲桃色在线一区| 欧美激情成人在线| 伊伊综合在线| 久久9热精品视频| 性色av一区二区三区在线观看| 欧美日韩国产精品一卡| 在线激情影院一区| 久久电影一区| 欧美制服丝袜| 国产精品亚发布| 亚洲亚洲精品三区日韩精品在线视频| 亚洲美女黄色| 免费试看一区| 禁久久精品乱码| 欧美主播一区二区三区| 欧美一区二区免费视频| 国产精品黄视频| 日韩一级裸体免费视频| 99xxxx成人网| 欧美精品一区二区久久婷婷| 亚洲国产精品电影| 亚洲国产裸拍裸体视频在线观看乱了中文 | 欧美日韩福利视频| 91久久在线观看| 亚洲人成网站色ww在线| 欧美xart系列在线观看| 伊人色综合久久天天五月婷| 久久精品一本久久99精品| 久久精品一区二区三区四区 | 亚洲视频在线二区| 欧美日韩高清免费| 亚洲美女精品成人在线视频| 在线亚洲成人| 欧美视频在线一区二区三区| 99精品国产一区二区青青牛奶| 一区二区三区精品视频| 欧美视频在线观看一区| 中文在线不卡| 午夜精品一区二区三区四区 | 一区二区欧美在线| 亚洲欧美999| 国产精品一区二区久久久久| 亚洲中无吗在线| 欧美伊人久久大香线蕉综合69| 国产欧美91| 欧美在线视频在线播放完整版免费观看 | 久久精品欧美日韩| 国内精品**久久毛片app| 亚洲第一久久影院| 欧美大片专区| 亚洲精品美女在线观看| 亚洲午夜精品一区二区| 国产精品成人免费| 香蕉久久一区二区不卡无毒影院| 久久久久久电影| 在线精品视频免费观看| 日韩一级黄色av| 国产精品国产| 欧美在线视屏| 欧美精品在线观看一区二区| 正在播放亚洲一区| 久久国产精品99国产精| 国内一区二区三区| 日韩系列欧美系列| 国产精品美女在线| 久久高清免费观看| 欧美韩国在线| 亚洲香蕉成视频在线观看| 久久久久久久久久久久久9999| 在线免费观看欧美| 亚洲一二三区在线观看| 国产亚洲美州欧州综合国| 亚洲精品视频在线观看免费| 欧美日韩一区成人| 欧美一区国产二区| 欧美欧美全黄| 小黄鸭精品aⅴ导航网站入口| 免费观看久久久4p| 亚洲私人影院在线观看| 久久天天躁夜夜躁狠狠躁2022| 亚洲人午夜精品| 久久国产精品黑丝| 亚洲精品久久| 久久精品99久久香蕉国产色戒 | 99视频精品| 久久久综合免费视频| 亚洲精品视频免费| 久久精品综合网| 亚洲精品偷拍| 久久国产一区二区| 亚洲精品中文字幕在线| 久久久999精品免费| 亚洲精品日韩在线| 久久久.com| 在线中文字幕一区| 欧美高潮视频| 欧美一区二区三区视频| 欧美三级日本三级少妇99| 久久国产精品毛片| 国产精品美女黄网| 亚洲狼人精品一区二区三区| 国产精品一级| 亚洲性视频h| 亚洲国产一成人久久精品| 午夜影院日韩| 日韩亚洲欧美一区二区三区| 久久综合精品一区| 亚洲欧美日韩在线高清直播| 欧美日韩国产成人在线91| 欧美一区二区在线免费观看| 国产精品成人观看视频国产奇米| 亚洲精品永久免费| 国户精品久久久久久久久久久不卡 | 欧美美女日韩|