文章首发在博主知乎
翻转金币场景设置
1.创建金币背景图案
在ps.cpp的构造函数中添加代码:
代码语言:javascript复制 //显示金币背景图案
for(int i=0;i<4;i )
{
for(int j=0;j<4;j )
{
//绘制背景图片
QPixmap pix=QPixmap(":/res/BoardNode.png");
QLabel* label=new QLabel;
label->setGeometry(0,0,pix.width(),pix.height());
label->setPixmap(pix);
label->setParent(this);
label->move(57 i*50,200 j*50);
}
}
结果显示:
2.添加金币类
新建一个class C : MyCoin,简称mc,继承QWidget ,将其修改为继承于QMyPushButton
在mc.cpp中添加实现:
代码语言:javascript复制MyCoin::MyCoin(QString btnImg)
{
QPixmap pix;
bool ret=pix.load(btnImg);
if(!ret)
{
QString str=QString("图片加载失败").arg(btnImg);
qDebug()<<str;
return;
}
this->setFixedSize(pix.width(),pix.height());
this->setStyleSheet("QPushButton[border:0px;]");
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
}
在ps.cpp的构造函数中实例化:
代码语言:javascript复制 //显示金币背景图案
for(int i=0;i<4;i )
{
for(int j=0;j<4;j )
{
//绘制背景图片
QPixmap pix=QPixmap(":/res/BoardNode.png");
QLabel* label=new QLabel;
label->setGeometry(0,0,pix.width(),pix.height());
label->setPixmap(pix);
label->setParent(this);
label->move(57 i*50,200 j*50);
//创建金币
MyCoin *coin=new MyCoin(":/res/Coin0001.png");
coin->setParent(this);
coin->move(59 i*50,209 j*50);
}
}
结果显示:
3.每个关卡的默认实现
添加现有文件,把现有的dataconfig.h和dataconfig.cpp放在同一目录下,只有在父亲节点右键选择->添加现有文件->之后选择dataconfig.h和dataconfig.cpp,最后分成在头文件和源文件中生成了现有文件。
在ps.cpp的构造函数中添加代码:
代码语言:javascript复制
dataConfig config;
//初始化每个关卡的二维数据
for(int i=0;i<4;i )
{
for(int j=0;j<4;j )
{
this->gameArray[i][j]=config.mData[this->levelIndex][i][j];
}
}
//显示金币背景图案
for(int i=0;i<4;i )
{
for(int j=0;j<4;j )
{
//绘制背景图片
QPixmap pix=QPixmap(":/res/BoardNode.png");
QLabel* label=new QLabel;
label->setGeometry(0,0,pix.width(),pix.height());
label->setPixmap(pix);
label->setParent(this);
label->move(57 i*50,200 j*50);
//创建金币
QString str;
if(this->gameArray[i][j] == 0)
{
//显示金币
str=":/res/Coin0001.png";
}
else
{
//显示银币
str=":/res/Coin0008.png";
}
MyCoin *coin=new MyCoin(str);
coin->setParent(this);
coin->move(59 i*50,209 j*50);
}
}
结果显示:
4.金币翻转特效实现
在mc.cpp中定义实现
代码语言:javascript复制MyCoin::MyCoin(QString btnImg)
{
QPixmap pix;
bool ret=pix.load(btnImg);
if(!ret)
{
QString str=QString("图片加载失败").arg(btnImg);
qDebug()<<str;
return;
}
this->setFixedSize(pix.width(),pix.height());
this->setStyleSheet("QPushButton[border:0px;]");
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
//初始化定时器对象
timer1 =new QTimer(this);
timer2 =new QTimer(this);
//监听正面翻反面的信号,并且翻转金币
connect(timer1,&QTimer::timeout,[=](){
QPixmap pix;
QString str=QString(":/res/Coin000%1").arg(this->min );
pix.load(str);
this->setFixedSize(pix.width(),pix.height());
this->setStyleSheet("QPushButton[border:0px;]");
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
//如果翻完了,将min变为1
if(this->min > this->max)
{
this->min=1;
timer1->stop();
}
});
//监听反面翻正面的信号,并且翻转金币
connect(timer2,&QTimer::timeout,[=](){
QPixmap pix;
QString str=QString(":/res/Coin000%1").arg(this->max--);
pix.load(str);
this->setFixedSize(pix.width(),pix.height());
this->setStyleSheet("QPushButton[border:0px;]");
this->setIcon(pix);
this->setIconSize(QSize(pix.width(),pix.height()));
//如果翻完了,将min变为1
if(this->max < this->min)
{
this->max=8;
timer2->stop();
}
});
}
void MyCoin::changeFlag()
{
//如果是正面,翻成反面
if(this->flag)
{
timer1->start(30);
this->flag=false;
}
//反面翻正面
else
{
timer2->start(30);
this->flag=true;
}
}
在ps.cpp的构造函数中进行测试:
代码语言:javascript复制 //显示金币背景图案
for(int i=0;i<4;i )
{
for(int j=0;j<4;j )
{
//绘制背景图片
QPixmap pix=QPixmap(":/res/BoardNode.png");
QLabel* label=new QLabel;
label->setGeometry(0,0,pix.width(),pix.height());
label->setPixmap(pix);
label->setParent(this);
label->move(57 i*50,200 j*50);
//创建金币
QString str;
if(this->gameArray[i][j] == 1)
{
//显示金币
str=":/res/Coin0001.png";
}
else
{
//显示银币
str=":/res/Coin0008.png";
}
MyCoin *coin=new MyCoin(str);
coin->setParent(this);
coin->move(59 i*50,209 j*50);
//给金币属性赋值
coin->posX=i;
coin->posY=j;
coin->flag=this->gameArray[i][j];
//点击金币进行翻转
connect(coin,&MyCoin::clicked,[=](){
coin->changeFlag();
});
}
}
结果显示:
5.翻转周围硬币特效实现
在ps.cpp的构造函数中添加实现:
代码语言:javascript复制 //显示金币背景图案
for(int i=0;i<4;i )
{
for(int j=0;j<4;j )
{
//绘制背景图片
QPixmap pix=QPixmap(":/res/BoardNode.png");
QLabel* label=new QLabel;
label->setGeometry(0,0,pix.width(),pix.height());
label->setPixmap(pix);
label->setParent(this);
label->move(57 i*50,200 j*50);
//创建金币
QString str;
if(this->gameArray[i][j] == 1)
{
//显示金币
str=":/res/Coin0001.png";
}
else
{
//显示银币
str=":/res/Coin0008.png";
}
MyCoin *coin=new MyCoin(str);
coin->setParent(this);
coin->move(59 i*50,209 j*50);
//给金币属性赋值
coin->posX=i;
coin->posY=j;
coin->flag=this->gameArray[i][j];
coinBtn[i][j]=coin;
//点击金币进行翻转
connect(coin,&MyCoin::clicked,[=](){
coin->changeFlag();
this->gameArray[i][j]=this->gameArray[i][j]==0?1:0;
//翻转周围硬币
//延时翻转
QTimer::singleShot(300,this,[=](){
//周围右侧翻转
if(coin->posX 1<=3)
{
coinBtn[coin->posX 1][coin->posY]->changeFlag();
this->gameArray[coin->posX 1][coin->posY]=
this->gameArray[coin->posX 1][coin->posY] == 0 ? 1:0;
}
//周围左侧
if(coin->posX-1>=0)
{
coinBtn[coin->posX-1][coin->posY]->changeFlag();
this->gameArray[coin->posX-1][coin->posY]=
this->gameArray[coin->posX-1][coin->posY] == 0 ? 1:0;
}
//周围下侧
if(coin->posY-1 >= 0)
{
coinBtn[coin->posX][coin->posY-1]->changeFlag();
this->gameArray[coin->posX][coin->posY-1]=
this->gameArray[coin->posX][coin->posY-1]==0?1:0;
}
//周围上册
if(coin->posY 1 <= 3)
{
coinBtn[coin->posX][coin->posY 1]->changeFlag();
this->gameArray[coin->posX][coin->posY 1]=
this->gameArray[coin->posX][coin->posY 1]==0?1:0;
}
});
});
}
}
结果显示:
6.判断游戏是否胜利并禁止按钮
在ps.cpp的构造函数中添加实现:
代码语言:javascript复制 //判断是否胜利
this->isWin=true;
for(int i=0;i<4;i )
{
for(int j=0;j<4;j )
{
//只要有一个是银色就失败
if(coinBtn[i][j]->flag == false)
{
this->isWin=false;
break;
}
}
}
if(this->isWin == true)
{
//游戏胜利
qDebug()<<"游戏胜利";
//将所有胜利按钮改为true,直接return
for(int i=0;i<4;i )
{
for(int j=0;j<4;j )
{
coinBtn[i][j]->isWin=true;
}
}
}
结果显示:
7.项目胜利图片实现
在ps.cpp的构造函数中添加:
代码语言:javascript复制 //胜利图片显示
QLabel *winLabel=new QLabel;
QPixmap tmpPix;
tmpPix.load(":/res/LevelCompletedDialogBg.png");
winLabel->setGeometry(0,0,tmpPix.width(),tmpPix.height());
winLabel->setPixmap(tmpPix);
winLabel->setParent(this);
winLabel->move((this->width()-tmpPix.width())*0.5,-tmpPix.height());
.............................
...........................
if(this->isWin == true)
{
//游戏胜利
qDebug()<<"游戏胜利";
//将所有胜利按钮改为true,直接return
for(int i=0;i<4;i )
{
for(int j=0;j<4;j )
{
coinBtn[i][j]->isWin=true;
}
}
//将胜利的图片砸下来
QPropertyAnimation *animation=new QPropertyAnimation(winLabel,"geometry");
//设置时间间隔
animation->setDuration(1000);
//设置开始位置
animation->setStartValue(QRect(winLabel->x(),winLabel->y(),winLabel->width(),
winLabel->height()));
//设置结束位置
animation->setEndValue(QRect(winLabel->x(),winLabel->y() 114,winLabel->width(),
winLabel->height()));
//设置曲线
animation->setEasingCurve(QEasingCurve::OutBounce);
//执行动画
animation->start();
}
结果显示:
8.设置音效
在.pro中添加QT = core gui multimedia(帮助文档中搜到的)QSound的依赖
之后在mw.cpp中添加开始音效:
代码语言:javascript复制 //增加开始按钮的音效
QSound *startSound=new QSound(":/res/TapButtonSound.wav");
startSound->play();
在cs.cpp中添加选择关卡的音效、返回的音效:
代码语言:javascript复制 //增加选择关卡的音效
QSound *chooseSound=new QSound(":/res/TapButtonSound.wav",this);
//返回按钮
QSound *backSound=new QSound(":/res/BackButtonSound.wav",this);
在ps.cpp中添加翻转金币的音效:
代码语言:javascript复制
//返回按钮
QSound *backSound=new QSound(":/res/BackButtonSound.wav",this);
//翻金币
QSound *flipSound=new QSound(":/res/ConFlipSound.wav",this);
//胜利按钮
QSound *winSound=new QSound(":/res/LevelWinSound.wav",this);
9.项目优化
场景位置固定不变
在mw.cpp中添加
代码语言:javascript复制 //监听选择关卡的返回按钮
connect(chooseScence,&ChooseLevelScence::chooseScenceBack,this,[=](){
this->setGeometry(chooseScence->geometry());
//将选择关卡场景 进行隐藏
chooseScence->hide();
this->show();//重新显示主场景
});
//进入选择关卡界面
//延时进入到
QTimer::singleShot(500,this,[=](){
chooseScence->setGeometry(this->geometry());
//自身隐藏
this->hide();
//显示选择关卡
chooseScence->show();
});
在cs.cpp中添加:
代码语言:javascript复制 //设置游戏的初始位置
play->setGeometry(this->geometry());
play->show();
connect(play,&PlayScence::chooseScenceBack,[=](){
this->setGeometry(play->geometry());
this->show();
delete play;
play=NULL;
});
项目成果: http://mpvideo.qpic.cn/0bf2dyaaiaaar4abtit3qrpfahwdaqpaabaa.f10002.mp4?dis_k=26debd174793a750d1182672b21f28f5&dis_t=1655364400&vid=wxv_1267259138875342849&format_id=10002&support_redirect=0&mmversion=false
10.项目发布
Windows下:
1.将Debug改成Release,生成编译,运行
此时生成一个Release文件,但是对方也要安装QT环境才能玩。
2.将Release中的CoinFlip.exe单独拷贝出来放在一个Game文件夹里,打开终端。
利用安装路径Qt/../../bin下的可执行文件进行打包:
windeployqt CoinFlip.exe
或者应用第三方打包程序软件
hm nis edit
最后生成一个安装包Setup.exe
Ubuntu下:
cnblogs.com/wanghuixi/p
第一步:将Release中的CoinFlip.exe单独拷贝出来放在一个Game文件夹里,打开终端。
编写一个脚本,将ldd CoinFlip.exe显示的链接库全部拷贝Game文件里:
dabao.sh
代码语言:javascript复制#!/bin/sh
exe="/home/lyy/QTQTQT/build-CoinFlip-Desktop_Qt_5_10_0_GCC_64bit-Debug/CoinFlip" #发布的程序名称 这是我的可执行程序的名字
des="/home/lyy/QTQTQT/Game_CoinFlip/" #你的路径 这是我的可执行文件的路径 对应的相应的更改
deplist=$(ldd $exe | awk '{if (match($3,"/")){ printf("%s "),$3 } }')
cp $deplist $des
第二步:编写运行脚本文档
运行脚本命名必须与可执行文件一致,CoinFlip.sh
代码语言:javascript复制#!/bin/sh
appname=`basename $0 | sed s,.sh$,,`
dirname=`dirname $0`
tmp="${dirname#?}"
if [ "${dirname%$tmp}" != "/" ]; then
dirname=$PWD/$dirname
fi
LD_LIBRARY_PATH=$dirname
export LD_LIBRARY_PATH
$dirname/$appname "$@"
给定权限
代码语言:javascript复制chomd x CoinFlip.sh
进行运行
代码语言:javascript复制./CoinFlip.sh
笔记:
参考:黑马程序员