linux qt 扫雷,qt制作扫雷

本文介绍了在Ubuntu环境下使用C++和Qt框架开发的一款扫雷游戏。代码包括游戏界面、扫雷逻辑、不同难度设置等功能,并提供了部分关键代码片段。作者分享了项目的结构和部分截图,同时提到项目中遇到的挑战和解决方法。
摘要由CSDN通过智能技术生成

沉默了一周我终于复活了,这回给大家带来的是扫雷。先说明一下,这个扫雷是我在ubuntu下用c++编写,qt制作的,如果windows系统需要用qt在windows下编译生成的.exe文件才能运行。而且用到了一些控件所以有些代码不能直接复制使用。如果有需要的朋友可以评论留邮箱我把整个项目发过去,虽然做的很一般。话不多说先看几个截图。

初始界面没做好,只能点easy正确,难度在后面改。

9f1a76180db7?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

开始界面

点开easy后出现了我们游戏界面,8x8 8个雷。基本扫雷的操作都有,不解释了,直接上图。

9f1a76180db7?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

简单模式

9f1a76180db7?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

选哪个好啊

9f1a76180db7?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

炸了

9f1a76180db7?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

终于赢了

左上角的菜单里有选项可以重开,选择难度,结束游戏。

下面是代码,分的文件比较多。

mainwindow.h

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

#include"myscene.h"

#include

namespace Ui {

class MainWindow;

}

class MainWindow : public QMainWindow

{

Q_OBJECT

public:

explicit MainWindow(QWidget *parent = 0);

virtual ~MainWindow();

private slots:

void on_actionExit_triggered();

void on_actionRestart_triggered();

void on_actionHard_triggered();

void on_actionEx_triggered();

void on_actionEasy_triggered();

private:

Ui::MainWindow *ui;

myscene sc;

};

#endif // MAINWINDOW_H

myitem.h//单位的头文件

#ifndef MYITEM_H

#define MYITEM_H

#include

#include

#include

class myitem : public QGraphicsPixmapItem

{

public:

int aright;//判断右键点击次数

int aleft;//判断左键是否点击过

myitem(int x,int y);

virtual ~myitem(){}

protected:

int m_x;

int m_y;

void mousePressEvent(QGraphicsSceneMouseEvent *event);

void mousePressEvent2();

void gameover();

};

#endif // MYITEM_H

myscene.h//场景,地图

#ifndef MYSCENE_H

#define MYSCENE_H

#include

#include

#include

using namespace std;

typedef vector irow;

typedef vector imap;

class myscene : public QGraphicsScene

{

Q_OBJECT

public:

explicit myscene(QObject *parent = 0);

virtual ~myscene(){removeAllTheiMx();}

imap iMx;

void removeAllTheiMx();

void resetAllTheiMx();

signals:

public slots:

private:

};

#endif // MYSCENE_H

startgame.h

#ifndef STARTGAME_H

#define STARTGAME_H

#include

#include

#include"mainwindow.h"

#include

namespace Ui {

class startgame;

}

class startgame : public QDialog

{

Q_OBJECT

public:

explicit startgame(QWidget *parent = 0);

virtual ~startgame();

private slots:

void on_pusheasy_clicked();

void on_pushnormal_clicked();

private:

Ui::startgame *ui;

};

#endif // STARTGAME_H

tywmodel.h//布雷

#ifndef TYWMODEL_H

#define TYWMODEL_H

#include

using namespace std;

typedef vector mrow;

typedef vector mmap;

class tywmodel

{

public:

tywmodel();

virtual ~tywmodel(){mMx.clear();}

mmap mMx;

void tywclear();//清理地雷用于重置前

void tywreset();//重置地雷

};

#endif // TYWMODEL_H

main.cpp

#include "mainwindow.h"

#include

#include"tywmodel.h"

#include"startgame.h"

int tywwidth=8;//第一次打开时默认简单模式的数据,宽度

int tywlength=8;//高度,竖着的

int tywtrap=8;//地雷数量

int win=56;//胜利条件,56个非雷区域被点开

int nandu=1;//一开始用于记录难度,后来直接用做判断是否踩过雷

tywmodel m;//一个雷的二维容器

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

startgame q;//显示第一个窗口,其实这个没啥用,可以注掉这行和下一行

q.exec();//阻塞显示q,q不关后面不出来。

MainWindow w;

w.show();

return a.exec();

}

mainwindow.cpp

#include "mainwindow.h"

#include "ui_mainwindow.h"

#include "myscene.h"

#include"myitem.h"

#include "tywmodel.h"

#include

#include

extern int tywwidth;

extern int tywlength;

extern int win;

extern int tywtrap;

extern int nandu;

extern tywmodel m;

MainWindow::MainWindow(QWidget *parent) :

QMainWindow(parent),

ui(new Ui::MainWindow)

{

ui->setupUi(this);

ui->graphicsView->setScene(&sc);

sc.setSceneRect(sc.itemsBoundingRect());// 下面3行代码是自动调整窗口大小自适应的

ui->graphicsView->setFixedSize(sc.sceneRect().width() +5,sc.sceneRect().height()+5);

this->resize(ui->graphicsView->width(),ui->graphicsView->height()+ 39);

}

MainWindow::~MainWindow()

{

delete ui;

}

void MainWindow::on_actionExit_triggered()

{

close();

}

void MainWindow::on_actionRestart_triggered()//点击重新开始

{

win=tywlength*tywlength-tywtrap;

sc.removeAllTheiMx();//先清除之前的东西

m.tywclear();

nandu=1;

sc.resetAllTheiMx();//再赋值

m.tywreset();

}

void MainWindow::on_actionHard_triggered()

{

sc.removeAllTheiMx();

m.tywclear();

tywwidth=16;//数据必须在这里改,如果放在前面,清除时对应不上出错

tywlength=12;

tywtrap=40;

nandu=2;

win=tywwidth*tywlength-tywtrap;//重置胜利条件

sc.resetAllTheiMx();

m.tywreset();

sc.setSceneRect(sc.itemsBoundingRect());// xiamian 3 hang zi dong tiaozheng chuangkou daxiao

ui->graphicsView->setFixedSize(sc.sceneRect().width() +5,sc.sceneRect().height()+5);

this->resize(ui->graphicsView->width(),ui->graphicsView->height()+ 39);

}

void MainWindow::on_actionEx_triggered()//ex难度,后面也是不同难度而已

{

sc.removeAllTheiMx();

m.tywclear();

tywwidth=25;

tywlength=20;

tywtrap=110;

win=tywwidth*tywlength-tywtrap;

nandu=3;

sc.resetAllTheiMx();

m.tywreset();

sc.setSceneRect(sc.itemsBoundingRect());// xiamian 3 hang zi dong tiaozheng chuangkou daxiao

ui->graphicsView->setFixedSize(sc.sceneRect().width() +5,sc.sceneRect().height()+5);

this->resize(ui->graphicsView->width(),ui->graphicsView->height()+ 39);

}

void MainWindow::on_actionEasy_triggered()

{

sc.removeAllTheiMx();

m.tywclear();

tywwidth=8;

tywlength=8;

tywtrap=8;

nandu=1;

win=tywwidth*tywlength-tywtrap;

sc.resetAllTheiMx();

m.tywreset();

sc.setSceneRect(sc.itemsBoundingRect());// xiamian 3 hang zi dong tiaozheng chuangkou daxiao

ui->graphicsView->setFixedSize(sc.sceneRect().width() +5,sc.sceneRect().height()+5);

this->resize(ui->graphicsView->width(),ui->graphicsView->height()+ 39);

}

myitem.cpp 单位控制,单独一个格子的设定。

#include "myitem.h"

#include

#include

#include

#include

#include "tywmodel.h"

#include"myscene.h"

extern tywmodel m;

extern int tywwidth;

extern int tywlength;

extern int win;

extern int tywtrap;

extern int nandu;

myitem::myitem(int x,int y)

{

QPixmap t("mine2.png");

m_x=x;m_y=y;

aright=0;

aleft=0;

setPixmap(t);

}

//鼠标点击事件

void myitem:: mousePressEvent(QGraphicsSceneMouseEvent *event)

{

((myscene*)scene())->iMx;

if(aleft==1)//判断是否被左键点击过

{

return;//是,返回不屌

}

if(event->button()==Qt::LeftButton)//如果是左键点击

{

mousePressEvent2();//调用函数,单独写出去方便递归

}

if(event->button()==Qt::RightButton) // 右键点击

{

if(aright==0)//没点击过插旗,点击过取消小旗

{

QPixmap t("miner.png");

setPixmap(t);

aright=1;

}

else

{

QPixmap t("mine2.png");

setPixmap(t);

aright=0;

}

}

}

void myitem:: mousePressEvent2()

{

int i=0,j=0;

if(aleft==1)

{

return;

}

aleft=1;

switch(m.mMx[m_x][m_y])//判断是什么并显示对应图片

{

case 0:

{

QPixmap t("mine0.png");

setPixmap(t);win--;break;

}

case 1:

{

QPixmap t("1.png");

setPixmap(t);win--;break;

}

case 2:

{

QPixmap t("2.png");win--;

setPixmap(t);break;

}

case 3:

{

QPixmap t("3.png");win--;

setPixmap(t);break;

}

case 4:

{

QPixmap t("4.png");win--;

setPixmap(t);break;

}

case 5:

{

QPixmap t("5.png");win--;

setPixmap(t);break;

}

case 6:

{

QPixmap t("6.png");win--;

setPixmap(t);break;

}

case 7:

{

QPixmap t("7.png");win--;

setPixmap(t);break;

}

case 8:

{

QPixmap t("8.png");win--;

setPixmap(t);break;

}

case -1:

{

QPixmap t("BOOM.png");

setPixmap(t);break;

}

}

if(win==0)//胜利

{

if(nandu != 0)//没有踩过雷

//时间后来忘做了,加一个计时器就好了。这里时间显示是固定的(假的)

{QMessageBox::Cancel==QMessageBox::information(NULL,"You win","time 00:48",QMessageBox::Cancel|QMessageBox::Ok);}

}

if(m.mMx[m_x][m_y]==0)//如果是0对周围自动展开

{

int myrow;

int mycolumn;

for(i=-1;i<2;i++)

{

for(j=-1;j<2;j++)

{

if(i==0&&j==0)

continue;

myrow=m_x+i;

mycolumn=m_y+j;

//防止越界进行判断

if(myrow<0||mycolumn<0||myrow>=tywwidth||mycolumn>=tywlength)

continue;

((myscene*)scene())->iMx[myrow][mycolumn]->mousePressEvent2();

}

}

}

if(m.mMx[m_x][m_y]==-1)//踩雷,触发游戏结束函数

{

win+=100;

if(nandu==0)

return;

gameover();

}

}

void myitem::gameover()//打开所有格子,提示重新开始

{

int i,j;

nandu=0;

int myrow,mycolumn;

for(i=0;i

{

for(j=0;j

{

myrow=i;

mycolumn=j;

if(myrow<0||mycolumn<0||myrow>=tywwidth||mycolumn>=tywlength)

continue;

((myscene*)scene())->iMx[myrow][mycolumn]->mousePressEvent2();

}

}

QMessageBox::Cancel==QMessageBox::information(NULL,"You lose","Please restart!",QMessageBox::Cancel|QMessageBox::Ok);

}

myscene.cpp 场景

#include "myscene.h"

#include"myitem.h"

extern int tywwidth;

extern int tywlength;

myscene::myscene(QObject *parent) :

QGraphicsScene(parent)

{

int i,j;//按照给定的全局变量长宽摆放各个单位格子

for(i=0;i

{

iMx.push_back(irow(tywlength));

for(j=0;j

{

iMx[i][j] = new myitem(i,j);

iMx[i][j]->setPos(iMx[i][j]->boundingRect().width()*i, iMx[i][j]->boundingRect().height()*j);

addItem(iMx[i][j]);

}

}

}

void myscene::removeAllTheiMx()//清除所有格子,才能重来

{

for(int i=0;i

{

for(int j=0;j

{

removeItem(iMx[i][j]);

delete iMx[i][j];

}

}

iMx.clear();

}

void myscene::resetAllTheiMx()//重新造,代码重复可以整理。

{

int i,j;

for(i=0;i

{

iMx.push_back(irow(tywlength));

for(j=0;j

{

iMx[i][j] = new myitem(i,j);

iMx[i][j]->setPos(iMx[i][j]->boundingRect().width()*i, iMx[i][j]->boundingRect().height()*j);

addItem(iMx[i][j]);

}

}

}

startgame.cpp 这个可以无视掉,没啥大用。

#include "startgame.h"

#include "ui_startgame.h"

#include

#include

#include"tywmodel.h"

extern int tywwidth;

extern int tywlength;

extern int tywtrap;

extern int win;

extern int nandu;

extern tywmodel m;

startgame::startgame(QWidget *parent) :

QDialog(parent),

ui(new Ui::startgame)

{

ui->setupUi(this);

QMovie *movie =new QMovie("fm2.png");

ui->label->setMovie(movie);

movie->start();

}

startgame::~startgame()

{

delete ui;

}

void startgame::on_pusheasy_clicked()

{

close();

}

void startgame::on_pushnormal_clicked()

{

close();

}

tywmodel.cpp 布置地雷(具体哪个是雷)

#include "tywmodel.h"

#include "myscene.h"

#include"myitem.h"

#include

#include

extern int tywwidth;

extern int tywlength;

extern int tywtrap;

int suiji(int a)//取1-a的随机整数。这个可以不用。

{

int rp;

int i = 0;

while (i < 10){

srand((unsigned)time(NULL));

rp = 1 + rand() % a;

i++;

}

return rp;

}

tywmodel::tywmodel() //先创造二维容器vector

{

for(int i= 0;i

{

mMx.push_back(mrow(tywlength));

for(int j=0;j

{

mMx[i][j] = 0;

}

}

srand(time(NULL));随机

for(int i=0;i

{

int x = rand()%tywwidth;

int y = rand()%tywlength;

if(mMx[x][y]!=-1)

{

i++;mMx[x][y]=-1;//如果是雷,对周围格子+1,需判断是否越界,是否周围是雷(雷不能+1,-1是雷)

if((x-1>=0)&&(x-1=0)&&(y-1

if((x-1>=0)&&(x-1=0)&&(y

if((x-1>=0)&&(x-1=0)&&(y+1

if((x>=0)&&(x=0)&&(y-1

if((x>=0)&&(x=0)&&(y+1

if((x+1>=0)&&(x+1=0)&&(y-1

if((x+1>=0)&&(x+1=0)&&(y

if((x+1>=0)&&(x+1=0)&&(y+1

}

}

}

void tywmodel::tywclear()//清除与重置,为了再次重开使用。

{

mMx.clear();

}

void tywmodel::tywreset()

{

for(int i= 0;i

{

mMx.push_back(mrow(tywlength));

for(int j=0;j

{

mMx[i][j] = 0;

}

}

srand(time(NULL));

for(int i=0;i

{

int x = rand()%tywwidth;

int y = rand()%tywlength;

if(mMx[x][y]!=-1)

{

i++;mMx[x][y]=-1;

if((x-1>=0)&&(x-1=0)&&(y-1

if((x-1>=0)&&(x-1=0)&&(y

if((x-1>=0)&&(x-1=0)&&(y+1

if((x>=0)&&(x=0)&&(y-1

if((x>=0)&&(x=0)&&(y+1

if((x+1>=0)&&(x+1=0)&&(y-1

if((x+1>=0)&&(x+1=0)&&(y

if((x+1>=0)&&(x+1=0)&&(y+1

}

}

}

还有两个窗口界面,相应的控件需自行拖入,给个截图。

9f1a76180db7?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

1.png

9f1a76180db7?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

2.png

看似简简单单的游戏还需要这么多东西。这期间遇到了不少bug,前面的路还有很长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值