Qt5.x-小游戲-翻金幣

前言

? ? 事情的起因需要從一只蝙蝠說起,那是2020年過年時,沒有攜帶所有娛樂性工具的我回到老家后,經(jīng)過麻將、電影、電視的洗禮,終于掏出來mac想學(xué)習(xí)一下c++。

? ? c++基礎(chǔ)學(xué)完后,發(fā)現(xiàn)了Qt這門語言,經(jīng)過了解是一門c++編寫的跨平臺桌面程序開發(fā)的框架,就繼續(xù)進(jìn)行學(xué)習(xí)觀看,這個demo也是Qt教學(xué)視頻中的老師最后帶著一起完成的翻金幣小游戲,日常生活中我從事的方向時J2EE方向,并不是過多的使用到學(xué)習(xí)到的東西,記錄到簡書中便于以后觀看查閱。


? ? 視頻學(xué)習(xí)網(wǎng)站:B站

? ? 視頻路徑:B站-Qt學(xué)習(xí)視頻

? ? *素材是在評論中翻找好多以后某位大哥的,很多鏈接都失效了

? ? *如有侵權(quán),請聯(lián)系我進(jìn)行刪除及修改

? ? 個人建議有興趣的同學(xué)最好還是自己來一遍,如果實在敲的過程中有問題,也可以去我Github下載成品的所有代碼。Github地址

????在學(xué)習(xí)的最后老師也提到過新加一些功能,我要立一個Flag:在閑暇的時候也會對這個成品進(jìn)行一定程度的優(yōu)化和修改。


1.代碼結(jié)構(gòu)說明

項目結(jié)構(gòu)

主窗體-mainscene

選擇關(guān)卡-chooseselevelscene

翻金幣-playscene

金幣封裝-mycoin

關(guān)卡數(shù)據(jù)封裝-dataconfig

自定義按鈕類-mypushbutton

2.難點記錄

? ? 01.跳轉(zhuǎn)設(shè)置新窗打開位置屬性

????????跳轉(zhuǎn)時設(shè)置新窗體的geometry屬性和本窗體相同,這樣設(shè)置會解決窗體移動過后,打開的新窗體和舊窗體位置不同的bug;

? ? 02.創(chuàng)建新窗體,初始化屬性

? ? ? ? //設(shè)置固定大小,并且讓窗體無法被更改

? ? ? ? setFixedSize(320, 588);

? ? ? ? //設(shè)置應(yīng)用圖標(biāo)

? ? ? ? setWindowIcon(QPixmap(":/res/Coin0001.png"));

? ? ? ? //設(shè)置窗口標(biāo)題

? ? ? ? setWindowTitle("選擇關(guān)卡");

? ? ? ? //設(shè)置菜單欄

? ? ? ? QMenuBar * qMenuBar = menuBar();

? ? ? ? QAction * qAction = qMenuBar->addMenu("開始")->addAction("退出");

? ? ? ? this->setMenuBar(qMenuBar);

? ? ? ? //點擊退出完成程序退出

? ? ? ? connect(qAction , &QAction::triggered, [=](){

? ? ? ? ? ? this->close();

? ? ? ? });

? ? 重寫窗體的畫家事件,繪制窗體的背景圖

? ? void ChooseLevelScene::paintEvent(QPaintEvent *event)? ?

? ? {

? ? ? ? //繪制背景圖

? ? ? ? QPainter qPainter(this);

? ? ? ? QPixmap qPixmap;

? ? ? ? qPixmap.load(":/res/PlayLevelSceneBg.png");

? ? ? ? //繪制背景圖

? ? ? ? qPainter.drawPixmap(0,0,this->width(),this->height(),qPixmap);

? ? ? ? //繪制左上角游戲名稱

? ? ? ? qPixmap.load(":/res/Title.png");

? ? ? ? qPainter.drawPixmap(20,30,qPixmap.width(),qPixmap.height(),qPixmap);

? ? }

03.定時器QTimer使用

? ? Qt的定時器實現(xiàn)有兩種,一個是重寫定時事件(沒使用過不清楚),另一個就是使用QTimer的靜態(tài)方法:

? ? //500是延遲多少時間執(zhí)行代碼,單位是毫秒

? ? //[=](){ ... }? ? Lamda表達(dá)式(很屌,推薦學(xué)習(xí)而且使用不難)

? ? QTimer::singleShot(500, this, [=](){

? ? ? ? //operator code

? ? });

04.事件穿透設(shè)置上下對齊居中

? ? 選擇關(guān)卡時繪制關(guān)卡是通過自定義按鈕MyPushButton進(jìn)行繪制,顯示關(guān)卡名稱是通過QLabel相同大小覆蓋在自定義按鈕上。

? ? 此時點擊時無法觸發(fā)自定義按鈕上選擇關(guān)卡后的操作,可使用鼠標(biāo)點擊事件穿透設(shè)置到QLabel上,label->setAttribute(Qt::WA_TransparentForMouseEvents);這時鼠標(biāo)點擊后QLabel不會阻攔點擊事件,可以正常觸發(fā)自定義按鈕。

? ? 在QLabel中設(shè)置text后默認(rèn)時居左,設(shè)置上下左右對齊居中,label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

05.設(shè)置開始游戲按鈕的點擊下沉彈回的動畫

? ? //圖標(biāo)下沉

? ? void MyPushButton::zoom1()

? ? {

? ? ? ? QPropertyAnimation * animation1 = new QPropertyAnimation(this, "geometry");

? ? ? ? //設(shè)置事件間隔

? ? ? ? animation1->setDuration(200);

? ? ? ? //設(shè)置起始位置

? ? ? ? animation1->setStartValue(QRect(this->x(), this->y(), this->width(), this->height()));

? ? ? ? animation1->setEndValue(QRect(this->x(), this->y()+10, this->width(), this->height()));

? ? ? ? //設(shè)置動畫,彈跳式,類似彈性球

? ? ? ? animation1->setEasingCurve(QEasingCurve::OutBounce);

? ? ? ? animation1->start();

? ? }

? ? //圖標(biāo)上浮

? ? void MyPushButton::zoom2()

? ? {

? ? ? ? QPropertyAnimation * animation1 = new QPropertyAnimation(this, "geometry");

? ? ? ? //設(shè)置事件間隔

? ? ? ? animation1->setDuration(200);

? ? ? ? //設(shè)置起始位置

? ? ? ? animation1->setStartValue(QRect(this->x(), this->y()+10, this->width(), this->height()));

? ? ? ? animation1->setEndValue(QRect(this->x(), this->y(), this->width(), this->height()));

? ? ? ? //設(shè)置動畫,彈跳式,類似彈性球

? ? ? ? animation1->setEasingCurve(QEasingCurve::OutBounce);

? ? ? ? animation1->start();

? ? }

? ? //給start按鈕綁定點擊事件

? ? connect(btn_start, &QPushButton::clicked, [=](){

? ? ? ? btn_start->zoom1();

? ? ? ? btn_start->zoom2();

? ? ? ? //點擊音效

? ? ? ? startSound->play();

? ? ? ? //延時0.5秒執(zhí)行切換,展示start按鈕的動效

? ? ? ? QTimer::singleShot(500, this, [=](){

? ? ? ? ? ? chooseLevel->setGeometry(this->geometry());

? ? ? ? ? ? this->hide();

? ? ? ? ? ? chooseLevel->show();

? ? ? ? });

? ? });

06.繪制一個4*4的選擇關(guān)卡矩陣,不使用雙層for循環(huán)的前提下,一個for循環(huán)完成繪制

? ? //創(chuàng)建關(guān)卡選擇icon

? ? for(int i = 0; i < 20 ; i++)

? ? {

? ? ? ? MyPushButton * levelIcon = new MyPushButton(":/res/LevelIcon.png");

? ? ? ? levelIcon->setParent(this);

? ? ? ? levelIcon->move(25 + (i%4)*70 , 160 + (i/4)*70);

? ? }

* x軸:25 + (i%4)*70? ? 25為偏移量,70是每個矩陣x軸大小,i%4在第一行0、1、2、3四列,每一行計算的值是0*70、1*70、2*70、3*70;

*y軸:160 + (i/4)*70? ? 160為偏移量,70是每個矩陣y軸大小,i/4在第一列0、1、2、3四行,每一行計算的值是0*70、1*70、2*70、3*70;

*在記錄其中每一個金幣的坐標(biāo)時,構(gòu)建了新的二維數(shù)組保存位置信息,因為這種構(gòu)建不太好保存位置信息

成品截圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容