1. 程式人生 > 其它 >QT翻金幣勝利介面(動畫)的配置

QT翻金幣勝利介面(動畫)的配置

技術標籤:QT學習筆記

任務

當所有金幣翻成正面時,讓金幣點選失效,且從上掉下圖片"Succeed"


先放一下這個遊戲場景 c p p cpp cpp檔案的配置

#include "playscence.h"
#include <QDebug>
#include <QPainter>
#include <QLabel>
#include <QFont>
#include <coin.h>
#include <mypushbutton.h>
#include <QPropertyAnimation>
//playScence::playScence(QWidget *parent) : QMainWindow(parent) //{ //} playScence::playScence(int level) { QLabel *winlabel = new QLabel(); winlabel->setParent(this); QPixmap map; bool YES = map.load(QString(":/res/LevelCompletedDialogBg.png")); if( !YES ) qDebug() <<
"失敗"; else qDebug() << "nice"; winlabel->setGeometry(0,0,map.width(),map.height()); winlabel->setPixmap(map); winlabel->move( (this->width()-map.width())*0.5,-map.height()); this->level = level; //初始化遊戲場景 this->setFixedSize(520,688
); this->setWindowIcon(QPixmap(":/res/Coin0001.png")); this->setWindowTitle(QString("遊戲")); //設定關卡名字 QLabel *label = new QLabel; label->setParent(this); QFont font; font.setPointSize(20); QString str = QString("Level %1").arg(this->level); label->setText(str); label->setFont(font); label->setGeometry(30,this->height()-50,120,50); //顯示金幣背景圖案 for(int i=0;i<4;i++) for(int j=0;j<4;j++) { QLabel *label = new QLabel; label->setGeometry(0,0,70,70); label->setParent(this); label->setPixmap(QPixmap(":/res/BoardNode(1).png")); label->move(122+i*70,200+j*70); QString str; if( this->game[i][j] ) str = ":/res/Coin0001.png"; else str = ":/res/Coin0008.png"; a[i][j] = new Coin(str); a[i][j]->setParent(this); a[i][j]->move(125+i*70,212+j*70); a[i][j]->posx = i,a[i][j]->posy = j,a[i][j]->flag = this->game[i][j];//設定金幣屬性 connect(a[i][j],&Coin::clicked,[=](){ a[i][j]->changeflag(); QTimer::singleShot(200,this,[=](){//延時翻周圍的金幣 if( i-1>=0 ) a[i-1][j]->changeflag(); if( i+1<=3 ) a[i+1][j]->changeflag(); if( j-1>=0 ) a[i][j-1]->changeflag(); if( j+1<=3 ) a[i][j+1]->changeflag(); bool iswin = true; for(int i=0;i<4;i++) for(int j=0;j<4;j++) if( a[i][j]->flag==false ) iswin = false; if( iswin )//都是金幣 { for(int i=0;i<4;i++) for(int j=0;j<4;j++) a[i][j]->iswin = true; QPropertyAnimation *animi = new QPropertyAnimation(winlabel,"geometry"); animi->setDuration(1000); animi->setStartValue(QRect(winlabel->x(),winlabel->y(),winlabel->width(),winlabel->height())); animi->setEndValue(QRect(winlabel->x()-50,winlabel->y()+144,winlabel->width(),winlabel->height())); animi->setEasingCurve(QEasingCurve::OutBounce); animi->start(); } }); }); } } void playScence::paintEvent(QPaintEvent *) { QPainter painter(this); QPixmap map; map.load(":/res/OtherSceneBg.png"); painter.drawPixmap(0,0,this->width(),this->height(),map); map.load(":/res/Title.png"); painter.drawPixmap( (this->width()-map.width())*0.5,30,map); }

第一部分,設定勝利圖片在螢幕外

為什麼放在螢幕外??因為只有勝利後,才"掉下來"

至於怎麼做,移動到 y y y軸的負方向即可

    QLabel *winlabel = new QLabel();
    winlabel->setParent(this);
    QPixmap map;
    bool YES = map.load(QString(":/res/LevelCompletedDialogBg.png"));
    if( !YES )  qDebug() << "失敗";
    else    qDebug() << "nice";
    winlabel->setGeometry(0,0,map.width(),map.height());
    winlabel->setPixmap(map);
    winlabel->move( (this->width()-map.width())*0.5,-map.height());

初始化遊戲背景圖,顯示關卡號

這部分很簡單,看看就好了

    //初始化遊戲場景
    this->setFixedSize(520,688);
    this->setWindowIcon(QPixmap(":/res/Coin0001.png"));
    this->setWindowTitle(QString("遊戲"));

    //設定關卡名字
    QLabel *label = new QLabel;
    label->setParent(this);
    QFont font;//設定字型
    font.setPointSize(20);
    QString str = QString("Level %1").arg(this->level);//放關卡名字上去
    label->setText(str);
    label->setFont(font);
    label->setGeometry(30,this->height()-50,120,50);

設定 20 20 20個金幣按鈕的點選事件

c o n n e c t connect connect連線一下即可,使用 Q T i m e r QTimer QTimer延時

Q T i m e r QTimer QTimer處理完上下左右金幣翻轉後判斷遊戲是否勝利

如果勝利,使用類 Q P r o p e r t y A n i m a t i o n QPropertyAnimation QPropertyAnimation完成勝利圖片掉落的動畫

if( iswin )//都是金幣
{
	 for(int i=0;i<4;i++)
	 for(int j=0;j<4;j++)
	     a[i][j]->iswin = true;
	QPropertyAnimation *animi = new QPropertyAnimation(winlabel,"geometry");
	animi->setDuration(1000);
	animi->setStartValue(QRect(winlabel->x(),winlabel->y(),winlabel->width(),winlabel->height()));
	animi->setEndValue(QRect(winlabel->x()-50,winlabel->y()+144,winlabel->width(),winlabel->height()));
	animi->setEasingCurve(QEasingCurve::OutBounce);
	animi->start();
}

勝利後,讓金幣的點選事件失效

勝利後,給每個金幣按鈕打個勝利標記

這個簡單,在金幣類中捕捉一下點選事件

如果當前勝利了,就攔截下來

void Coin::mousePressEvent(QMouseEvent *e)
{
    if( this->iswin==true )//捕捉
    {
        qDebug() << "進來";
        return;
    }
    else    QPushButton::mousePressEvent(e);//返回
}