概述
1.项目的性质:游戏
2.项目的名字:翻金币
3.实现的软件 ; QT creator 4.2.1 , NisEdit , Nsis
4.游戏介绍:
1.包括游戏界面
2.游戏音效
5.游戏的资源(res)
已经上传
整个的代码包: CoinFilp
已经上传
6.文件:
1.chooselevelscene.h
2.dataconfig.h
3.mainsence.h
4.mycoin.h
5.mypushbutton.h
6.playscene.h
7.main.cpp
8.chooselevelscene.cpp
9.dataconfig.cpp
10.mainsence.cpp
11.mycoin.cpp
12.mypushbutton.cpp
13.playscene.cpp
7.ui -> 设计界面 (添加了一个菜单栏 开始 ,退出的菜单项 )
8.资源文件
res
9.代码:
CoinFlip.pro (这里注意 添加了 一个 multimedia 第7 行 )
#-------------------------------------------------
#
# Project created by QtCreator 2022-09-23T10:33:56
#
#-------------------------------------------------
QT += core gui multimedia
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = CoinFlip
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp
mainsence.cpp
mypushbutton.cpp
chooselevelscene.cpp
playscene.cpp
mycoin.cpp
dataconfig.cpp
HEADERS += mainsence.h
mypushbutton.h
chooselevelscene.h
playscene.h
mycoin.h
dataconfig.h
FORMS += mainsence.ui
RESOURCES +=
res.qrc
1.chooselevelscene.h
#ifndef CHOOSELEVELSCENE_H
#define CHOOSELEVELSCENE_H
#include <QMainWindow>
#include "playscene.h"
class ChooseLevelScene : public QMainWindow
{
Q_OBJECT
public:
explicit ChooseLevelScene(QWidget *parent = 0);
//重写绘画事件
void paintEvent(QPaintEvent *);
//游戏场景的对象指针
PlayScene * paly = NULL;
signals:
//写一个自定义的信号,告诉主场景,点击了返回
void chooseSceneBack();
public slots:
};
#endif // CHOOSELEVELSCENE_H
2.dataconfig.h
#ifndef DATACONFIG_H
#define DATACONFIG_H
#include <QObject>
#include <QMap>//STL 地图
#include <QVector>//STL 动态数组
class dataconfig : public QObject
{
Q_OBJECT
public:
explicit dataconfig(QObject *parent = 0);
QMap<int ,QVector< QVector<int> > >mData;//一个地图
//地图的 key 是 int 类型 value 是 int 的二维的数组QVector< QVector<int> >
signals:
public slots:
};
#endif // DATACONFIG_H
3.mainsence.h
#ifndef MAINSENCE_H
#define MAINSENCE_H
#include <QMainWindow>
#include <QPainter>
#include <QDebug>
#include <chooselevelscene.h>
namespace Ui {
class Mainsence;
}
class Mainsence : public QMainWindow
{
Q_OBJECT
public:
explicit Mainsence(QWidget *parent = 0);
~Mainsence();
//重新paintEvent 事件, 画背景图
void paintEvent(QPaintEvent *);//括号里面是数据类型,不需要写参数,没事
ChooseLevelScene * chooseScene =NULL;
private:
Ui::Mainsence *ui;
};
#endif // MAINSENCE_H
4.mycoin.h
#ifndef MYCOIN_H
#define MYCOIN_H
#include <QWidget>
#include <QPushButton>
#include <QString>
#include <QDebug>
#include <QTimer>
class MyCoin : public QPushButton
{
Q_OBJECT
public:
//explicit MyCoin(QWidget *parent = 0);
//参数表示 传进来的金币路径 还是银币路径
MyCoin(QString btnImg);
//金币的属性
int posX;//x坐标
int posY;//y坐标
bool flag;//正反的标志
void changeFlag();//改变金币的状态
QTimer *timer1;//正面翻反面的定时器
QTimer *timer2;//反面翻正面的定时器
int min=1;//图片的最小号码数
int max=8;//图片的最大号码数
//执行动画 标志
bool isAnimation = false;// 判断他是否在执行翻转的操作 防止用户狂点的行为
//重写 鼠标按下的事件
void mousePressEvent(QMouseEvent * e);
//设置一个是否可以翻转的标志
bool ispaly=true;
signals:
public slots:
};
#endif // MYCOIN_H
5.mypushbutton.h
#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H
#include <QWidget>
#include <QPushButton>
#include <QString>
#include <QDebug>
#include <QPropertyAnimation>
class mypushbutton : public QPushButton
{
Q_OBJECT
public:
//explicit mypushbutton(QWidget *parent = 0);
//构造函数 参数1 正常显示的图片路径 参数2 按下后显示的图片的路径
mypushbutton(QString normalImg,QString pressImg = "");
//成员属性 保存用户传入的默认显示路径 以及按下后显示的图片路径
QString normaLImgPath;
QString pressImgPath;
//弹跳特效
void zoom1();//向下跳
void zoom2();//向上跳
//重写按钮 按下 和 释放事件
void mousePressEvent(QMouseEvent * e);//按下
void mouseReleaseEvent(QMouseEvent * e);//释放
signals:
public slots:
};
#endif // MYPUSHBUTTON_H
6.playscene.h
#ifndef PLAYSCENE_H
#define PLAYSCENE_H
#include <QMainWindow>
#include "mycoin.h"
class PlayScene : public QMainWindow
{
Q_OBJECT
public:
//explicit PlayScene(QWidget *parent = 0);
PlayScene(int levelNum);//构造函数
int levelIndex;//内部成员属性;记录所选的关卡数字
//重写paintEvent事件
void paintEvent(QPaintEvent * );
int gameArray[4][4];//二维数组 维护每个关卡的具体数据
//下面这个指针数组是用来存储 金币的 就是下一个关卡的所有的金币对象
MyCoin * coinBtn[4][4];//维护上一个数组的数据正常
//是否胜利的标志
bool isWin;
signals:
void chooseSceneBack();
public slots:
};
#endif // PLAYSCENE_H
7.main.cpp
#include "mainsence.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Mainsence w;
w.show();
return a.exec();
}
8.chooselevelscene.cpp
#include "chooselevelscene.h"
#include <QMenuBar>
#include <QDebug>
#include <QPainter>
#include "mypushbutton.h"
#include <QTimer>
#include <QString>
#include <QLabel>
#include <QSound>
ChooseLevelScene::ChooseLevelScene(QWidget *parent) : QMainWindow(parent)
{
//配置选择关卡场景
this->setFixedSize(320,588);
//设置图标
this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
//设置标题
this->setWindowTitle("选择关卡场景");
//创建菜单栏
QMenuBar * bar = menuBar();
setMenuBar(bar);
//创建开始菜单
QMenu * startMenu = bar->addMenu("开始");
//创建退出 菜单栏
QAction * quitAction = startMenu->addAction("退出");
//点击退出 实现退出游戏 建立连接
connect(quitAction,&QAction::triggered,[=](){
this->close();
});
//选择关卡的音效
QSound * chooseSound = new QSound(":/res/TapButtonSound.wav",this);
//返回按钮的音效
QSound * backSound = new QSound(":/res/TapButtonSound.wav",this);
//返回按钮
mypushbutton * backBtn = new mypushbutton(":/res/BackButton.png", ":/res/BackButtonSelected.png");//这两个图片有细微的差别,这样构成了一个动态的感觉
backBtn->setParent(this);
backBtn->move(this->width() - backBtn->width(),this->height() - backBtn->height());
//点击返回
connect(backBtn,&mypushbutton::clicked,[=](){
//点击了返回按钮的音效
backSound->play();
qDebug()<<"点击了选择关卡的 返回按键";
//告诉主场景,我返回了,主场景监听 chooseLeveScene 的返回按键
//延时发送信号
QTimer::singleShot(500,this,[=](){
emit this->chooseSceneBack();//激发信号 返回开始界面
});
});
//创建选择关卡的按钮
for(int i=0;i<20;i++)
{
mypushbutton * menuBtn = new mypushbutton(":/res/LevelIcon.png");
menuBtn->setParent(this);//设置父亲,方便关闭和销毁
menuBtn->move(25 + i%4 *70 ,130 + i/4 *70);//设置关卡的图片的位置
//监听每个按钮的点击事件 建立信号的连接
connect(menuBtn,&mypushbutton::clicked,[=](){
//选择关卡之后播放音效
chooseSound->play();
QString str =QString("你选择的是第 %1 关").arg(i+1);
qDebug()<<str;
//
//进入游戏场景
this->hide();//进入游戏关卡 ,隐藏游戏选择界面
paly =new PlayScene(i+1);//创建一个游戏的界面
//设置游戏场景出现的初始位置
paly->setGeometry(this->geometry());
paly->show();//显示游戏界面
//退出游戏的信号连接
connect(paly,&PlayScene::chooseSceneBack,[=](){
this->setGeometry(paly->geometry());//窗口的位置的调整
this->show();
delete paly;
paly=NULL;
});
});
//设置选择关卡上的数字
QLabel *label = new QLabel; //建立一个标签的对象
label->setParent(this);//设置父亲, 方便关闭
label->setFixedSize(menuBtn->width(),menuBtn->height());//设置标签的大小
label->setText(QString::number(i+1));//标签里设置数字
label->move(25 + i%4 *70 ,130+ i/4*70);//设置标签的位置
//设置标签 label 上的文字对齐方式 水平居中 和 垂直居中
label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
//设置让鼠标进行穿透 51号属性
label->setAttribute((Qt::WA_TransparentForMouseEvents));
}
}
void ChooseLevelScene::paintEvent(QPaintEvent *)
{
//加载背景
QPainter painter(this);
QPixmap pix;//建立对象
pix.load(":/res/OtherSceneBg.png");//加载背景
painter.drawPixmap(0,0,this->width(),this->height(),pix);//加载第一张的图片
//加载标题
pix.load(":/res/Title.png");
painter.drawPixmap((this->width() - pix.width())*0.5,30,pix.width(),pix.height(),pix);//加载下一张图片进去
}
9.dataconfig.cpp
//dataconfig.cpp
#include "dataconfig.h"
#include <QDebug>
dataconfig::dataconfig(QObject *parent) : QObject(parent)//构造函数
{
//二维数组
int array1[4][4] = {{1, 1, 1, 1},
{1, 1, 0, 1},
{1, 0, 0, 0},
{1, 1, 0, 1} } ;
QVector< QVector<int>> v; //一个动态数组的 二维数组
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;//一个一维数组的动态数组
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array1[i][j]);//把数据写入到动态数组
}
v.push_back(v1);//把一维数组计入到二维数组
}
mData.insert(1,v);//把二维数组 计入到之前的 map 地图中 key =1 value = v
int array2[4][4] = { {1, 0, 1, 1},
{0, 0, 1, 1},
{1, 1, 0, 0},
{1, 1, 0, 1}} ;
v.clear();//清除二维数组。
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array2[i][j]);
}
v.push_back(v1);
}
mData.insert(2,v);
int array3[4][4] = { {0, 0, 0, 0},
{0, 1, 1, 0},
{0, 1, 1, 0},
{0, 0, 0, 0}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array3[i][j]);
}
v.push_back(v1);
}
mData.insert(3,v);
int array4[4][4] = { {0, 1, 1, 1},
{1, 0, 0, 1},
{1, 0, 1, 1},
{1, 1, 1, 1}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array4[i][j]);
}
v.push_back(v1);
}
mData.insert(4,v);
int array5[4][4] = { {1, 0, 0, 1},
{0, 0, 0, 0},
{0, 0, 0, 0},
{1, 0, 0, 1}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array5[i][j]);
}
v.push_back(v1);
}
mData.insert(5,v);
int array6[4][4] = { {1, 0, 0, 1},
{0, 1, 1, 0},
{0, 1, 1, 0},
{1, 0, 0, 1}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array6[i][j]);
}
v.push_back(v1);
}
mData.insert(6,v);
int array7[4][4] = { {0, 1, 1, 1},
{1, 0, 1, 1},
{1, 1, 0, 1},
{1, 1, 1, 0}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array7[i][j]);
}
v.push_back(v1);
}
mData.insert(7,v);
int array8[4][4] = { {0, 1, 0, 1},
{1, 0, 0, 0},
{0, 0, 0, 1},
{1, 0, 1, 0}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array8[i][j]);
}
v.push_back(v1);
}
mData.insert(8,v);
int array9[4][4] = { {1, 0, 1, 0},
{1, 0, 1, 0},
{0, 0, 1, 0},
{1, 0, 0, 1}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array9[i][j]);
}
v.push_back(v1);
}
mData.insert(9,v);
int array10[4][4] = { {1, 0, 1, 1},
{1, 1, 0, 0},
{0, 0, 1, 1},
{1, 1, 0, 1}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array10[i][j]);
}
v.push_back(v1);
}
mData.insert(10,v);
int array11[4][4] = { {0, 1, 1, 0},
{1, 0, 0, 1},
{1, 0, 0, 1},
{0, 1, 1, 0}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array11[i][j]);
}
v.push_back(v1);
}
mData.insert(11,v);
int array12[4][4] = { {0, 1, 1, 0},
{0, 0, 0, 0},
{1, 1, 1, 1},
{0, 0, 0, 0}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array12[i][j]);
}
v.push_back(v1);
}
mData.insert(12,v);
int array13[4][4] = { {0, 1, 1, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 1, 1, 0}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array13[i][j]);
}
v.push_back(v1);
}
mData.insert(13,v);
int array14[4][4] = { {1, 0, 1, 1},
{0, 1, 0, 1},
{1, 0, 1, 0},
{1, 1, 0, 1}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array14[i][j]);
}
v.push_back(v1);
}
mData.insert(14,v);
int array15[4][4] = { {0, 1, 0, 1},
{1, 0, 0, 0},
{1, 0, 0, 0},
{0, 1, 0, 1}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array15[i][j]);
}
v.push_back(v1);
}
mData.insert(15,v);
int array16[4][4] = { {0, 1, 1, 0},
{1, 1, 1, 1},
{1, 1, 1, 1},
{0, 1, 1, 0}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array16[i][j]);
}
v.push_back(v1);
}
mData.insert(16,v);
int array17[4][4] = { {0, 1, 1, 1},
{0, 1, 0, 0},
{0, 0, 1, 0},
{1, 1, 1, 0}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array17[i][j]);
}
v.push_back(v1);
}
mData.insert(17,v);
int array18[4][4] = { {0, 0, 0, 1},
{0, 0, 1, 0},
{0, 1, 0, 0},
{1, 0, 0, 0}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array18[i][j]);
}
v.push_back(v1);
}
mData.insert(18,v);
int array19[4][4] = { {0, 1, 0, 0},
{0, 1, 1, 0},
{0, 0, 1, 1},
{0, 0, 0, 0}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array19[i][j]);
}
v.push_back(v1);
}
mData.insert(19,v);
int array20[4][4] = { {0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}} ;
v.clear();
for(int i = 0 ; i < 4;i++)
{
QVector<int>v1;
for(int j = 0 ; j < 4;j++)
{
v1.push_back(array20[i][j]);
}
v.push_back(v1);
}
mData.insert(20,v);
}
10.mainsence.cpp
#include "mainsence.h"
#include "ui_mainsence.h"
#include <QPushButton>
#include "mypushbutton.h"
#include <chooselevelscene.h>
#include <QTimer>
#include <QSound>
Mainsence::Mainsence(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Mainsence)
{
ui->setupUi(this);
//配置主场景
//设置固定大小
setFixedSize(320,588);//设置窗口的初始大小
//设置图标
setWindowIcon(QIcon(":/res/Coin0001.png"));
//设置标题
setWindowTitle("翻金币主场景");
//退出按钮实现
connect(ui->action_quit,&QAction::triggered,[=](){
this->close();
});
//准备开始的音效
QSound * startSound = new QSound(":/res/TapButtonSound.wav",this);
//startSound->setLoops(-1); // 这个函数是播放几次 -1 是无限的播放
//开始的按钮
mypushbutton * startBtn = new mypushbutton(":/res/MenuSceneStartButton.png");
startBtn->setParent(this);
startBtn->move((this->width() *0.5) - (startBtn->width()*0.5),this->height()*0.7);
//实列化选择关卡场景
chooseScene =new ChooseLevelScene;
//返回按钮的信号连接
connect(chooseScene,&ChooseLevelScene::chooseSceneBack,this,[=](){
this->setGeometry(chooseScene->geometry());//保证两个窗口出现的位置相同
chooseScene->hide();//选择关卡场景 隐藏
this->show();//重新显示主场景
});
connect(startBtn,&mypushbutton::clicked,[=](){
//播放点击了开始的音效
startSound->play();
qDebug()<<"点击了开始";
//弹起特效
startBtn->zoom1();
startBtn->zoom2();
//延时进入到选择关卡场景中
QTimer::singleShot(500,this,[=](){
//设置chooseScene 场景的位置
chooseScene->setGeometry(this->geometry());//这个函数的作用就是把 新的这个窗口放到 之前要隐藏的窗口的位置,防止返回的时候,两个窗口位置的不同
//自身隐藏
this->hide();
//进入选择关卡场景中
//显示选择关卡
chooseScene->show();
//监听选择关卡场景的返回按钮的信号
});
});
}
Mainsence::~Mainsence()
{
delete ui;
}
//重新paintEvent 事件, 画背景图
void Mainsence::paintEvent(QPaintEvent *)
{
QPainter painter(this);//设置一个画家的对象
QPixmap pix;//定义一个图片的对象
pix.load(":res/PlayLevelSceneBg.png");//加载图片
//第一个参数 第二个参数 位置开始的位置 ,参数三 画家对象窗口的宽 ,参数四 画家对象窗口的高 参数五,要加载的图片
painter.drawPixmap(0,0,this->width(),this->height(),pix);//窗口设置图片 这个函数可以使图片的大小适应窗口的大小
//画背景图标
pix.load(":/res/Title.png");//再次加载一个图片
pix=pix.scaled(pix.width()*0.5,pix.height()*0.5);//得到一个缩放的图片
painter.drawPixmap(10,30,pix);//再次放置图片 开始的位置是10,30
}
11.mycoin.cpp
#include "mycoin.h"
#include <QDebug>
//MyCoin::MyCoin(QWidget *parent) : QWidget(parent)
//{
//}
MyCoin::MyCoin(QString btnImg)
{
QPixmap pix;//建立一个图片的对象
bool ret=pix.load(btnImg);//加载图片
if(!ret)//判定图片是否加载成功
{
QString str = QString("图片 %1 加载失败").arg(btnImg);
qDebug()<<str;//输出加载失败的 图片
return;//结束函数
}
this->setFixedSize(pix.width(),pix.height());//设置 金币按钮的大小
this->setStyleSheet("QPushButton{border:Opx}");//设置为不规则图像的过滤
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 str1 = QString(":/res/Coin000%1").arg(this->min++);
bool ret1=pix.load(str1);
if(!ret1)
{
qDebug()<<"错误 金币正面翻转 "<<str1;
}
this->setFixedSize(pix.width(),pix.height());//设置 金币按钮的大小
this->setStyleSheet("QPushButton{border:Opx}");//设置为不规则图像的过滤
this->setIcon(pix);//加载图片,给这个按钮
this->setIconSize(QSize(pix.width(),pix.height()));//图片大小的设置
//判断 如果翻完了 将min 重置为 1;
if(this->min > this->max)
{
this->min=1;
timer1->stop();//定时器发出信号停止
isAnimation=false;//停止做动画了
}
});
//监听反面的金币的点击 信号
connect(timer2,&QTimer::timeout,[=](){
QPixmap pix;//建立一个图片的对象
QString str1 = QString(":/res/Coin000%1").arg(this->max--);
bool ret1=pix.load(str1);
if(!ret1)
{
qDebug()<<"错误 金币正面翻转 "<<str1;
}
this->setFixedSize(pix.width(),pix.height());//设置 金币按钮的大小
this->setStyleSheet("QPushButton{border:Opx}");//设置为不规则图像的过滤
this->setIcon(pix);//加载图片,给这个按钮
this->setIconSize(QSize(pix.width(),pix.height()));//图片大小的设置
//判断 如果翻完了 将min 重置为 1;
if(this->max < this->min)
{
this->max=8;
timer2->stop();//定时器发出信号停止
isAnimation=false;//停止做动画了
}
});
}
void MyCoin::changeFlag()//改变金币的状态
{
//如果是正面 翻成反面
if(this->flag)
{
//开始运行正面翻反面的定时器
timer1->start(30);//启动定时器 时间间隔为30毫秒
this->flag=false;//把金币的状态改变
isAnimation=true;//开始做动画了
}
else
{
//开始运行反面翻正面的定时器
timer2->start(30);//启动定时器 时间间隔为30毫秒
this->flag=true;//把金币的状态改变
isAnimation=true;//开始做动画了
}
}
//重写 鼠标按下的事件
void MyCoin::mousePressEvent(QMouseEvent * e)
{
if(this->isAnimation || this->ispaly== false)//当他翻转动作正在执行的时候,我们点击按钮 ,使按钮失效
{
return;
}
else//没有进行翻转动作的时候,我们把这个信号交给父类处理
{
QPushButton::mousePressEvent(e);
}
}
12.mypushbutton.cpp
#include "mypushbutton.h"
//mypushbutton::mypushbutton(QWidget *parent) : QPushButton(parent)
//{
//}
mypushbutton::mypushbutton(QString normalImg,QString pressImg)
{
this->normaLImgPath = normalImg;//赋值 //初始的状态图片
this->pressImgPath = pressImg;//鼠标按下去的状态图片
QPixmap pix;
bool ret = pix.load(normalImg);//看图片是否加载成功
if(!ret)
{
qDebug() <<"图片加载失败";
return;
}
//设置图片固定大小
this->setFixedSize(pix.width(),pix.height());
//设置不规则图片样式
this->setStyleSheet("QPushButton{border:Opx;}");//去掉周围的空白,只剩图形
//设置图片
this->setIcon(pix);
//设置图标大小
this->setIconSize(QSize(pix.width(),pix.height()));
}
//弹跳特效
void mypushbutton::zoom1()//向下跳 (这里的按键的 为开始的)
{
//创建一个动态对象
QPropertyAnimation * animation =new QPropertyAnimation(this,"geometry");
//设置动画的事件间隔
animation->setDuration(200);
//起始位置
animation->setStartValue(QRect(this->x(),this->y(),this->width(),this->height()));
//结束位置
animation->setEndValue(QRect(this->x(),this->y()+10,this->width(),this->height()));
//设置弹跳曲线
animation->setEasingCurve(QEasingCurve::OutBounce);
//执行动画
animation->start();
}
void mypushbutton::zoom2()//向上跳
{
//创建一个动态对象
QPropertyAnimation * animation =new QPropertyAnimation(this,"geometry");
//设置动画的事件间隔
animation->setDuration(200);
//起始位置
animation->setStartValue(QRect(this->x(),this->y()+10,this->width(),this->height()));
//结束位置
animation->setEndValue(QRect(this->x(),this->y(),this->width(),this->height()));
//设置弹跳曲线
animation->setEasingCurve(QEasingCurve::OutBounce);
//执行动画
animation->start();
}
void mypushbutton::mousePressEvent(QMouseEvent * e)//鼠标按下去的一瞬间, 这个按钮加载的图片改变, 变为另外一种状态 按下去的状态,与初始的状态的图片,有细微的改变,这样形成一种动态的效果
{
if(this->pressImgPath !="")//传入的按下的图片不为空, 说明需要有按下状态 切换图片
{
QPixmap pix;
bool ret = pix.load(this->pressImgPath);//看图片是否加载成功
if(!ret)
{
qDebug() <<"图片加载失败";
return;
}
//设置图片固定大小
this->setFixedSize(pix.width(),pix.height());
//设置不规则图片样式
this->setStyleSheet("QPushButton{border:Opx;}");//去掉周围的空白,只剩图形
//设置图片
this->setIcon(pix);
//设置图标大小
this->setIconSize(QSize(pix.width(),pix.height()));
}
//让父类执行其他的内容
return QPushButton::mousePressEvent(e);
}
void mypushbutton::mouseReleaseEvent(QMouseEvent * e)//鼠标释放之后的状态为 这个按钮的加载图片的改变 变为之前的还没有改变的状态
{
if(this->pressImgPath !="")//传入的按下的图片不为空, 说明需要有按下状态 切换初始的图片
{
QPixmap pix;
bool ret = pix.load(this->normaLImgPath);//看图片是否加载成功
if(!ret)
{
qDebug() <<"图片加载失败";
return;
}
//设置图片固定大小
this->setFixedSize(pix.width(),pix.height());
//设置不规则图片样式
this->setStyleSheet("QPushButton{border:Opx;}");//去掉周围的空白,只剩图形
//设置图片
this->setIcon(pix);
//设置图标大小
this->setIconSize(QSize(pix.width(),pix.height()));
}
//让父类执行其他的内容
return QPushButton::mouseReleaseEvent(e);
}
13.playscene.cpp
#include "playscene.h"
#include <QDebug>
#include <QMenuBar>
#include <QPainter>
#include "mypushbutton.h"
#include <QTimer>
#include <QLabel>
#include "mycoin.h"
#include "dataconfig.h"
#include <QPropertyAnimation>
#include <QSound>
//PlayScene::PlayScene(QWidget *parent) : QMainWindow(parent)
//{
//}
PlayScene::PlayScene(int levelNum)//构造函数
{
QString str=QString("进入了第 %1 关").arg(levelNum);//进入关卡的体术语句
qDebug()<<str;//输出提示语句
this->levelIndex=levelNum;//内部成员赋值
//初始化游戏的场景
//设置固定大小
this->setFixedSize(320,588);
//设置图标
this->setWindowIcon(QPixmap(":/res/Coin0001.png"));//就是最上面的窗口名称旁边的图标
//设置标题
this->setWindowTitle("翻金币场景");
//创建菜单栏
QMenuBar * bar = menuBar();//创建一个菜单栏的对象,这个对象是空的
setMenuBar(bar);//把菜单栏对象,放置到窗口
//创建开始菜单
QMenu * startMenu = bar->addMenu("开始");
//创建退出 菜单选项
QAction * quitAction = startMenu->addAction("退出");
//点击退出 实现退出游戏
connect(quitAction,&QAction::triggered,[=](){
this->close();
});
//添加音效
//返回按钮的音效
QSound * backSound = new QSound(":/res/TapButtonSound.wav",this);
//翻金币的音效
QSound * flipSound = new QSound(":/res/ConFlipSound.wav",this);
//成功胜利的音效
QSound * winSound = new QSound(":/res/LevelWinSound.wav",this);
//返回按钮
mypushbutton * backBtn = new mypushbutton(":/res/BackButton.png", ":/res/BackButtonSelected.png");//这两个图片有细微的差别,这样构成了一个动态的感觉
backBtn->setParent(this);
backBtn->move(this->width() - backBtn->width(),this->height() - backBtn->height());
//点击返回
connect(backBtn,&mypushbutton::clicked,[=](){
//点击了返回的音效
backSound->play();
qDebug()<<"点击了 游戏场景里面的 返回按键";
//告诉主场景,我返回了,主场景监听 chooseLeveScene 的返回按键
//延时发送信号
QTimer::singleShot(500,this,[=](){
emit this->chooseSceneBack();//激发信号 返回开始界面
});
});
//显示当前关卡数
QLabel * label = new QLabel;
label->setParent(this);//设置父亲
QFont font;//设置字体的对象
font.setFamily("华文新魏");//字体的格式
font.setPointSize(20);//字体大小为 20
//输出的标签显示的内容
QString str1=QString("Level: %1").arg(this->levelIndex);
//将字体的设置加入标签空间之中
label->setFont(font);
label->setText(str1);//设置关卡的标签显示的内容
//label->setFixedSize(20,20);//设置标签的大小
//label->move(100,500);//设置标签的显示的位置在哪里
label->setGeometry(30,this->height() -50 ,150,50);//这个上面 两个命令的合并的功能
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];//赋值
}
}
//胜利的图片显示,
//开始的时候我们把他放到屏幕之外 等到胜利之后我们直接让他掉下来
QLabel * winLabel = new QLabel;
QPixmap tmaPix;
tmaPix.load(":/res/LevelCompletedDialogBg.png");//加载图片
winLabel->setGeometry(0,0,tmaPix.width(),tmaPix.height());//设置标签里面放置的位置
winLabel->setPixmap(tmaPix);//把图片放入到标签
winLabel->setParent(this);//设置标签的父亲
winLabel->move((this->width() - tmaPix.width())*0.5,-tmaPix.height());//设置标签在窗口的位置
//显示金币背景图案 灰色的方形框框
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
//绘制背景图片
QPixmap pix = QPixmap(":/res/BoardNode(1).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);//设置标签在窗口的位置
//创建金币
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, 204 + j*50);//移动金币的位置,与灰色的框框对齐
//给金币的属性赋值
coin->posX=i;//x 坐标
coin->posY=j;//y 坐标
coin->flag=this->gameArray[i][j];//正面是 1 反面是 0
//将金币放到 金币的二维数组里 以便后期的维护
coinBtn[i][j]=coin;//
//点击金币 进行翻转
//他的本质 继承的是 QPushButton
//监听点击信号
connect(coin,&MyCoin::clicked,[=](){
//翻金币的音效
flipSound->play();
coin->changeFlag();//点击之后进行翻转
this->gameArray[i][j]=(this->gameArray[i][j]==0 ? 1:0);
//加一个延时的翻转
QTimer::singleShot(100,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 <=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);
}
//周围的下侧金币翻转的条件
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);
}
//判断是否胜利
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)//胜利了
{
//游戏胜利的音效
winSound->play();
qDebug()<<"第"<<levelNum<<"关 "<<"游戏胜利了";
//把所有的金币按钮禁用
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
coinBtn[i][j]->ispaly=false;//金币按钮不可以使用
}
}
//创建一个动态对象
QPropertyAnimation * animation1 =new QPropertyAnimation(winLabel,"geometry");
//设置动画的事件间隔
animation1->setDuration(1000);
//起始位置
animation1->setStartValue(QRect(winLabel->x(),winLabel->y(),winLabel->width(),winLabel->height()));
//结束位置
animation1->setEndValue(QRect(winLabel->x(),winLabel->y()+144,winLabel->width(),winLabel->height()));
//设置弹跳曲线
animation1->setEasingCurve(QEasingCurve::OutBounce);
//执行动画
animation1->start();
}
});
});
}
}
}
//QWidget中的paintEvent事件处理器可以在子类中被重写来接收绘图事件,然后在指定区域完成图形的绘制。
//重写paintEvent事件
void PlayScene::paintEvent(QPaintEvent * )
{
QPainter painter(this);//设置一个画家的对象
QPixmap pix;//定义一个图片的对象
pix.load(":res/PlayLevelSceneBg.png");//加载图片
//第一个参数 第二个参数 位置开始的位置 ,参数三 画家对象窗口的宽 ,参数四 画家对象窗口的高 参数五,要加载的图片
painter.drawPixmap(0,0,this->width(),this->height(),pix);//窗口设置图片 这个函数可以使图片的大小适应窗口的大小
//画背景图标
pix.load(":/res/Title.png");//再次加载一个图片
pix=pix.scaled(pix.width()*0.5,pix.height()*0.5);//得到一个缩放的图片
painter.drawPixmap(10,30,pix);//再次放置图片 开始的位置是10,30
}
最后
以上就是明理老师为你收集整理的翻金币项目 QT项目 (利用Qt 5.80 实现 )的全部内容,希望文章能够帮你解决翻金币项目 QT项目 (利用Qt 5.80 实现 )所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复