目录
三、最后分享ChooseWindow.h、ChooseWindow.cpp和PlayWindow.h、PlayWindow.cpp完整代码
2021.7.14----优化了翻转周围金币的代码
前言:
分享学习Qt中小项目制作的过程,看完了黑马Qt翻金币小游戏,完成前20关的制作后拓展关卡到100关。所以前面20关,包括游戏核心的内容就不分享了,视频都有,主要分享后面的拓展。
制作完成后首先考虑添加下一页和上一页的功能,实现点击下一页变成21至40页...我没有考虑先关闭选择窗口再建立新的选择窗口,而是在一个选择窗口中通过deleteLater命令清空关卡按钮和标签,再重新创建关卡按钮和标签实现的。
源码地址:链接:https://pan.baidu.com/s/1Qie2UMmpeEl-QgQAwrZwPQ 提取码:h82f
下面开始:
一、拓展——增加到100功能实现:
1、ChooseWindow.cpp中代码
在ChooseWindow界面创建上一页和下一页按钮,通过qt信号槽连接,再声明int类型变量page记录第几页,通过theNewPage函数实现功能。
创建下一页
//设计选关
void ChooseWindow::chooseNumber()
{
//记录页面
page = 1;
//初始化play指针置空
play = NULL;
//创建新页面的按钮和标签
theNewPage();
sign = true;
//--------------------------------------------------------------------------------------
//下一页
//下一页关卡
MyPushButton *nextPage = new MyPushButton(":/res/next.png",":/res/nextSelected.png");
nextPage->setParent(this);
nextPage->setFixedSize(80,30);
nextPage->move(this->width() - nextPage->width()+2,this->height() - 100);
nextPage->show();
//下一页关卡信号槽连接
connect(nextPage,&MyPushButton::clicked,[=](){
if(page == 5)
{
return;
}
page++;
//创建新页面的按钮和标签
theNewPage();
});
//--------------------------------------------------------------------------------------
//上一页关卡
MyPushButton *previousPage = new MyPushButton(":/res/previous.png",":/res/previousSelected.png");
previousPage->setParent(this);
previousPage->setFixedSize(80,30);
previousPage->move(0,this->height() - 100);
previousPage->show();
//上一页关卡信号槽连接
connect(previousPage,&QPushButton::clicked,[=](){
sound->play();
if(page == 1)
{
return;
}
page--;
//创建新页面的按钮和标签
theNewPage();
});
}
int k 记录第几关,sign表示 是否第二次创建关卡按钮和标签,这样在主窗口进入选择窗口时可用下面代码生成按钮和标签。在ChooseWindow.h中声明QLabel *arrayLab[5][4] 和 MyPushButton *arrayBtn[5][4] 记录生成的按钮和标签地址,以便于释放管理。
//创建新页面的按钮和标签
void ChooseWindow::theNewPage()
{
//记录关卡
int k = page * 20 - 20 + 1;
//二维数组建立关卡
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 4; j++,k++)
{
//清空按钮和标签
if(sign == true)
{
if(arrayBtn[i][j] != NULL)
{
arrayBtn[i][j]->deleteLater();
arrayBtn[i][j] = NULL;
}
if(arrayLab[i][j] != NULL)
{
arrayLab[i][j]->deleteLater();
arrayLab[i][j] = NULL;
}
}
//新建按钮
MyPushButton *num = new MyPushButton(":/res/LevelIcon.png");
num->move(60 + j * 80,180 + i * 80);
num->setParent(this);
num->show();
//新建标签显示第几关
QLabel * label = new QLabel;
label->setText(QString::number(k));
label->setParent(this);
label->setFixedSize(num->width(),num->height());
label->move(60 + j * 80,180 + i * 80);
label->show();
//居中
label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
//设置标签穿透
label->setAttribute(Qt::WA_TransparentForMouseEvents);
//记录按钮和标签地址
arrayBtn[i][j] = num;
arrayLab[i][j] = label;
//点击按钮
connect(num,&MyPushButton::clicked,[=](){
qDebug()<<"您选择的是第" << k << "关";
//记录当前窗口坐标
ChooseWindow::m_x = this->x();
ChooseWindow::m_y = this->y();
//创建游戏窗口
this->play = new playwindow(k);
this->play->show();
this->hide();
//接收下一关信号,显示下一关页面
connect(this->play,&playwindow::chooseNextAction,this,&ChooseWindow::nextLevel);
//接收back发送的信号
connect(this->play,&playwindow::chooseBack,[=](){
this->move(this->play->x(),this->play->y());
this->show();
if(this->play != NULL)
{
this->play->deleteLater();
this->play = NULL;
}
});
});
}
}
}
2、PlayWindow.cpp 中代码:
首先需要全新的数据包DataConfig.h和DataConfig.cpp
下载地址:https://pan.baidu.com/s/1I4foSyenefY1nHixxZACaA
提取码:h82f
在“复制数据进入数组中”修改代码为:
//复制数据进入数组
void playwindow::copyData()
{
//数据
data = new DataConfig;
for (int i = 0; i < data->levelsData[this->m_playIndex - 1].m_row; i++)
{
for (int j = 0; j < data->levelsData[this->m_playIndex - 1].m_col; j++)
{
//array[i][j]小bug::显示的金币与数据库不符,换成array[j][i]解决,没搞明白
this->array[j][i] = data->levelsData[this->m_playIndex-1].grid[i][j];
}
}
}
显示金币方格,由于关卡不同显示的金币不同,有4*4,5*4,5*5(在5*5的DataConfig中空白用-1表示),所以需要判断情况翻转周围金币,游戏核心内容也在此算法中。
5*5中空白格我用setEnable(false)进行判断区分,并设置flag = true表示金币面,翻转周围金币时只要判断周围金币enable != false即可。
函数showRect实现功能:
//显示金币方格,完成游戏核心
void playwindow::showRect()
{
for (int i = 0; i < data->levelsData[this->m_playIndex - 1].m_col; i++)
{
for (int j = 0; j < data->levelsData[this->m_playIndex - 1].m_row; j++)
{
//QLabel显示图片
QLabel *label = new QLabel;
QPixmap pix;
pix.load(":/res/BoardNode.png");
pix = pix.scaled(pix.width()*1.5,pix.height()*1.5);
//调整标签界面大小
//5*5
if(data->levelsData[this->m_playIndex - 1].m_row == 5)
{
label->setGeometry(0,0,pix.width(),pix.height());
label->move(25+i*pix.width(),220+j*pix.height());
}
//4*5
else if(data->levelsData[this->m_playIndex - 1].m_col == 5)
{