基于Linux、QT、C++的“别踩白块儿”小游戏
一、功能实现
完善的游戏界面、游戏倒计时、得分记录、历史最高分显示
二、功能描述
1、界面为4*4,一行中只有一个黑块,使用qrand函数,采用时间种子保证 每次产生是随机数不同,在将随机数对4取余来作为黑块的位置。 2、初始时间设定值为30,通过定时器每100ms发出一次信号,刷新时间。 3、通过工厂模式,完成对黑块和白块的生产,并采用queue容器来储存块。 4、当玩家点击黑块时,delete队头的4个块并pop弹出,在加入4个新块, 最后将队列中所有的块Y坐标增加。
三、界面展示

  
四、代码展示
 1、block.h
#ifndef BLOCK_H
#define BLOCK_H
#include <QWidget>
class Block : public QWidget
{
public:
void down(){
move(pos().x(),pos().y() + 120);
}
Block(QWidget *parent = nullptr);
virtual bool isBlack() = 0;
};
class BlueBlock : public Block
{
public:
bool isBlack(){ return true;}
BlueBlock(QWidget *parent = nullptr);
};
class WhiteBlock : public Block
{
public:
bool isBlack(){ return false;}
WhiteBlock(QWidget *parent = nullptr);
};
class Factory
{
public :
virtual Block* CreateBlock(QWidget *parent = nullptr) = 0;
};
class BlueBlockFactory : public Factory
{
public :
Block* CreateBlock(QWidget *parent = nullptr)
{
Block* blueBlock = new BlueBlock(parent);
return blueBlock;
}
};
class WhiteBlockFactory : public Factory
{
public :
Block* CreateBlock(QWidget *parent = nullptr)
{
Block* whiteBlock = new WhiteBlock(parent);
return whiteBlock;
}
};
#endif
2、gemesetting.h
#ifndef GAMESETTING_H
#define GAMESETTING_H
#include <QWidget>
class GameSetting
{
private:
GameSetting();
public:
int highscore = 0;
static GameSetting* getInstance()
{
static GameSetting* m_instance;
if(m_instance == NULL)
{
m_instance = new GameSetting;
}
return m_instance;
}
};
#endif
3、gameview.h
#ifndef GAMEVIEW_H
#define GAMEVIEW_H
#include <QWidget>
#include "block.h"
#include <deque>
#include <QTime>
#include <QTimer>
#include <QDebug>
#include <QMouseEvent>
#include <QMessageBox>
#include "gamesetting.h"
using namespace std;
namespace Ui {
class gameview;
}
class gameview : public QWidget
{
Q_OBJECT
signals:
void gameoversignal();
public:
explicit gameview(QWidget *parent = 0);
~gameview();
void initgameview();
void mousePressEvent(QMouseEvent *event);
void updategameview();
void resetgame();
void gameover();
private slots:
private:
float lasttime = 30;
int score = 0;
void timeoutslot();
QTimer* timer;
Ui::gameview *ui;
BlueBlockFactory blueFactory;
WhiteBlockFactory whiteFacyory;
deque<Block*> blockdeque;
int generateRandomNumber();
};
#endif
4、widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QWidget>
#include <QMessageBox>
#include <QPainter>
#include "gamesetting.h"
#include "gameview.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
void paintEvent(QPaintEvent*event);
~Widget();
private slots:
void on_pushButton_2_clicked();
void on_pushButton_clicked();
void on_pushButton_3_clicked();
void gameoverslot();
private:
gameview* gameVc;
Ui::Widget *ui;
};
#endif
5、block.cpp
#include "block.h"
Block::Block(QWidget *parent) : QWidget(parent)
{
resize(80,120);
}
WhiteBlock::WhiteBlock(QWidget *parent) : Block(parent)
{
this->setStyleSheet("background-color:white;");
}
BlueBlock::BlueBlock(QWidget *parent) : Block(parent)
{
this->setStyleSheet("background-color:black;");
}
6、gamesettingc.cpp
#include "gamesetting.h"
GameSetting::GameSetting()
{
}
7、gameview.cpp
#include "gameview.h"
#include "ui_gameview.h"
gameview::gameview(QWidget *parent) :
QWidget(parent),
ui(new Ui::gameview)
{
ui->setupUi(this);
setFixedSize(320,480);
this->setWindowTitle(QStringLiteral("开始游戏"));
ui->timeLcd->setStyleSheet("background-color:red;");
ui->scoreLcd->setStyleSheet("background-color:yellow;");
timer = new QTimer(this);
connect(timer,&QTimer::timeout,this,&gameview::timeoutslot);
}
void gameview::initgameview()
{
timer->start(100);
for(int i = 0; i < 4; i++)
{
int idex = generateRandomNumber();
for(int j = 0; j < 4; j++)
{
Block* block;
if(idex == j)
{
block = blueFactory.CreateBlock(this);
}
else
{
block = whiteFacyory.CreateBlock(this);
}
block->move(j*80,i*120);
block->stackUnder(ui->topbarWidget);
block->show();
blockdeque.push_back(block);
}
}
}
void gameview::mousePressEvent(QMouseEvent *event)
{
int row = event->y()/120;
int col = event->x()/80;
if(blockdeque.at(row*4 + col)->isBlack())
{
if(row == 3)
{
updategameview();
}
}
else
{
gameover();
}
}
void gameview::updategameview()
{
score ++;
if(GameSetting::getInstance()->highscore < score)
{
GameSetting::getInstance()->highscore = score;
}
ui->scoreLcd->display(score);
for(int i = 0; i < 4; i++)
{
delete blockdeque.back();
blockdeque.pop_back();
}
int idex = generateRandomNumber();
for(int i = 0; i < 4; i++)
{
Block* block;
if(idex == i)
{
block = blueFactory.CreateBlock(this);
}
else
{
block = whiteFacyory.CreateBlock(this);
}
block->move(i*80,-120);
block->stackUnder(ui->topbarWidget);
block->show();
blockdeque.insert(blockdeque.begin()+i,block);
}
for(int i = 0; i < 16; i++)
{
blockdeque.at(i)->down();
}
}
void gameview::timeoutslot()
{
lasttime -= 0.1;
ui->timeLcd->display(lasttime);
if(lasttime <= 0)
{
gameover();
}
}
void gameview::gameover()
{
timer->stop();
QString str = QString("很厉害啊!\n得分: %1 \n 是否再玩一次?").arg(score);
int ret = QMessageBox::question(this,"游戏结束",str);
if(ret == QMessageBox::Yes)
{
resetgame();
initgameview();
}
else
{
resetgame();
emit gameoversignal();
}
}
void gameview::resetgame()
{
lasttime = 10;
score = 0;
ui->timeLcd->display(lasttime);
ui->scoreLcd->display(0);
for(int i = 0; i < 16; i++)
{
delete blockdeque.at(i);
}
blockdeque.clear();
}
int gameview::generateRandomNumber()
{
int randn;
QTime time = QTime::currentTime();
qsrand(time.msec()*qrand()*qrand()*qrand()*qrand());
randn = qrand()%4;
return randn;
}
gameview::~gameview()
{
delete ui;
}
8、main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
9、widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setFixedSize(320,480);
this->setWindowTitle(QStringLiteral("别踩白块"));
GameSetting::getInstance();
gameVc = new gameview;
gameVc->hide();
connect(gameVc,&gameview::gameoversignal,this,&Widget::gameoverslot);
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter paint(this);
paint.drawPixmap(0,0,width(),height(),QPixmap(":/resources/img_bg_level_2.jpg"));
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_3_clicked()
{
gameVc->show();
hide();
gameVc->initgameview();
}
void Widget::gameoverslot()
{
gameVc->hide();
show();
}
void Widget::on_pushButton_2_clicked()
{
QMessageBox::about(this,"玩法","在30秒内尽量多的点击黑块!\n如果点击到白块,游戏立刻结束!");
}
void Widget::on_pushButton_clicked()
{
QString str = QString("历史最高分:\n\n %1").arg(GameSetting::getInstance()->highscore);
QMessageBox::about(this,"最高分",str);
}
9、gameview.ui  10、widget.ui 
|